From 2c3b38781c03aafbcb0de072f603bc26ecdefb56 Mon Sep 17 00:00:00 2001 From: Joe Scotto Date: Thu, 1 Jun 2023 11:58:38 -0400 Subject: [PATCH 1/3] Delete jscotto directory --- .../handwired/jscotto/scotto36/info.json | 76 --- .../jscotto/scotto36/keymaps/default/config.h | 23 - .../jscotto/scotto36/keymaps/default/keymap.c | 281 ---------- .../jscotto/scotto36/keymaps/default/rules.mk | 4 - .../handwired/jscotto/scotto36/readme.md | 25 - keyboards/handwired/jscotto/scotto36/rules.mk | 1 - .../handwired/jscotto/scotto40/info.json | 180 ------ .../jscotto/scotto40/keymaps/default/config.h | 23 - .../jscotto/scotto40/keymaps/default/keymap.c | 114 ---- .../jscotto/scotto40/keymaps/default/rules.mk | 1 - .../handwired/jscotto/scotto40/readme.md | 25 - keyboards/handwired/jscotto/scotto40/rules.mk | 1 - keyboards/handwired/jscotto/scotto9/info.json | 47 -- .../jscotto/scotto9/keymaps/default/keymap.c | 27 - keyboards/handwired/jscotto/scotto9/readme.md | 25 - keyboards/handwired/jscotto/scotto9/rules.mk | 1 - .../handwired/jscotto/scottocmd/config.h | 21 - .../handwired/jscotto/scottocmd/info.json | 86 --- .../scottocmd/keymaps/default/config.h | 23 - .../scottocmd/keymaps/default/keymap.c | 515 ------------------ .../scottocmd/keymaps/default/rules.mk | 2 - .../handwired/jscotto/scottocmd/readme.md | 25 - .../handwired/jscotto/scottocmd/rules.mk | 2 - .../handwired/jscotto/scottostarter/info.json | 95 ---- .../scottostarter/keymaps/default/config.h | 23 - .../scottostarter/keymaps/default/keymap.c | 52 -- .../handwired/jscotto/scottostarter/readme.md | 25 - .../handwired/jscotto/scottostarter/rules.mk | 1 - 28 files changed, 1724 deletions(-) delete mode 100644 keyboards/handwired/jscotto/scotto36/info.json delete mode 100644 keyboards/handwired/jscotto/scotto36/keymaps/default/config.h delete mode 100644 keyboards/handwired/jscotto/scotto36/keymaps/default/keymap.c delete mode 100644 keyboards/handwired/jscotto/scotto36/keymaps/default/rules.mk delete mode 100644 keyboards/handwired/jscotto/scotto36/readme.md delete mode 100644 keyboards/handwired/jscotto/scotto36/rules.mk delete mode 100644 keyboards/handwired/jscotto/scotto40/info.json delete mode 100644 keyboards/handwired/jscotto/scotto40/keymaps/default/config.h delete mode 100644 keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c delete mode 100644 keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk delete mode 100644 keyboards/handwired/jscotto/scotto40/readme.md delete mode 100644 keyboards/handwired/jscotto/scotto40/rules.mk delete mode 100644 keyboards/handwired/jscotto/scotto9/info.json delete mode 100644 keyboards/handwired/jscotto/scotto9/keymaps/default/keymap.c delete mode 100644 keyboards/handwired/jscotto/scotto9/readme.md delete mode 100644 keyboards/handwired/jscotto/scotto9/rules.mk delete mode 100644 keyboards/handwired/jscotto/scottocmd/config.h delete mode 100644 keyboards/handwired/jscotto/scottocmd/info.json delete mode 100644 keyboards/handwired/jscotto/scottocmd/keymaps/default/config.h delete mode 100644 keyboards/handwired/jscotto/scottocmd/keymaps/default/keymap.c delete mode 100644 keyboards/handwired/jscotto/scottocmd/keymaps/default/rules.mk delete mode 100644 keyboards/handwired/jscotto/scottocmd/readme.md delete mode 100644 keyboards/handwired/jscotto/scottocmd/rules.mk delete mode 100644 keyboards/handwired/jscotto/scottostarter/info.json delete mode 100644 keyboards/handwired/jscotto/scottostarter/keymaps/default/config.h delete mode 100644 keyboards/handwired/jscotto/scottostarter/keymaps/default/keymap.c delete mode 100644 keyboards/handwired/jscotto/scottostarter/readme.md delete mode 100644 keyboards/handwired/jscotto/scottostarter/rules.mk diff --git a/keyboards/handwired/jscotto/scotto36/info.json b/keyboards/handwired/jscotto/scotto36/info.json deleted file mode 100644 index 3247b4019bdd..000000000000 --- a/keyboards/handwired/jscotto/scotto36/info.json +++ /dev/null @@ -1,76 +0,0 @@ -{ - "manufacturer": "Joe Scotto", - "keyboard_name": "Scotto36", - "maintainer": "joe-scotto", - "bootloader": "caterina", - "diode_direction": "COL2ROW", - "features": { - "bootmagic": true, - "command": false, - "console": false, - "extrakey": true, - "mousekey": true, - "nkro": true - }, - "matrix_pins": { - // 4, 5, 6, 7, 8, 9, A3, A2, A1, A0 - "cols": ["D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5", "F6", "F7"], - // 15, 14, 16, 10 - "rows": ["B1", "B3", "B2", "B6"] - }, - "processor": "atmega32u4", - "url": "", - "usb": { - "device_version": "1.0.0", - "pid": "0x0000", - "vid": "0xFEED" - }, - "layouts": { - "LAYOUT_ortho_3x10_6": { - "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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"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} - ] - } - } -} diff --git a/keyboards/handwired/jscotto/scotto36/keymaps/default/config.h b/keyboards/handwired/jscotto/scotto36/keymaps/default/config.h deleted file mode 100644 index 1a6512052c1d..000000000000 --- a/keyboards/handwired/jscotto/scotto36/keymaps/default/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#pragma once - -// Define options -#define TAPPING_TERM 135 -#define PERMISSIVE_HOLD -#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/jscotto/scotto36/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scotto36/keymaps/default/keymap.c deleted file mode 100644 index ad8451ac09fe..000000000000 --- a/keyboards/handwired/jscotto/scotto36/keymaps/default/keymap.c +++ /dev/null @@ -1,281 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#include QMK_KEYBOARD_H - -#include -char wpm_str[10]; - -// Tap Dance declarations -enum { - TD_ESC_SPOTLIGHT_EMOJI, - TD_ESC_WINDOWS_EMOJI -}; - -void td_esc_spotlight_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code16(G(KC_SPC)); - } else if (state->count == 3) { - tap_code16(C(G(KC_SPC))); - } -} - -void td_esc_windows_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code(KC_LGUI); - } else if (state->count == 3) { - tap_code16(G(KC_DOT)); - } -}; - - // Tap Dance definitions -tap_dance_action_t tap_dance_actions[] = { - [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), - [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) -}; - -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case TD(TD_ESC_SPOTLIGHT_EMOJI) : - case TD(TD_ESC_WINDOWS_EMOJI) : - case LGUI_T(KC_SPC) : - case LT(1, KC_TAB) : - case LT(2, KC_ENT) : - return 200; - default: - return TAPPING_TERM; - } -}; - -// Layer Names -enum layer_names { - _MAC_DEFAULT, - _MAC_CODE, - _MAC_NUM, - _MAC_FUNC, - _WIN_DEFAULT, - _WIN_CODE, - _WIN_NUM, - _WIN_FUNC -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT_ortho_3x10_6( - KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [1] = LAYOUT_ortho_3x10_6( - KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [2] = LAYOUT_ortho_3x10_6( - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [3] = LAYOUT_ortho_3x10_6( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [4] = LAYOUT_ortho_3x10_6( - KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) - ), - [5] = LAYOUT_ortho_3x10_6( - KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE,KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) - ), - [6] = LAYOUT_ortho_3x10_6( - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) - ), - [7] = LAYOUT_ortho_3x10_6( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) - ) -}; - -// OLED -#ifdef OLED_ENABLE -// WPM responsiveness -#define IDLE_FRAMES 5 -#define IDLE_SPEED 20 // Speed at which animation goes into idle -#define TAP_FRAMES 2 -#define TAP_SPEED 40 // WPM to trigger Bongo -#define ANIM_FRAME_DURATION 200 // Frame MS -#define ANIM_SIZE 636 // Number of bytes in array, max 1024 - -uint32_t anim_timer = 0; -uint32_t anim_sleep = 0; -uint8_t current_idle_frame = 0; -uint8_t current_tap_frame = 0; - -static void render_animation(void) { - static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x34, 0xc4, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x31, 0xc1, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; - static const char PROGMEM prep[][ANIM_SIZE] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; - static const char PROGMEM tap[TAP_FRAMES][ANIM_SIZE] = { - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x98, 0xc0, 0x88, 0x88, 0x8c, 0x9c, 0x1c, 0x1e, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x0f, 0x07, 0x03, 0x03, 0x61, 0xf0, 0xf8, 0xfc, 0x60, 0x01, 0x01, 0x01, 0x3c, 0x78, 0xf8, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, - }; - - void animation_phase(void) { - if (get_current_wpm() <= IDLE_SPEED) { - current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES; - oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE); - } - - if (get_current_wpm() > IDLE_SPEED && get_current_wpm() < TAP_SPEED) { - oled_write_raw_P(prep[0], ANIM_SIZE); - } - - if (get_current_wpm() >= TAP_SPEED) { - current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES; - oled_write_raw_P(tap[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIM_SIZE); - } - } - if (get_current_wpm() != 000) { - oled_on(); // Enables OLED on any alpha keypress - - if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { - anim_timer = timer_read32(); - animation_phase(); - } - - anim_sleep = timer_read32(); - } else { - if (timer_elapsed32(anim_sleep) > OLED_TIMEOUT) { - oled_off(); - } else { - if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { - anim_timer = timer_read32(); - animation_phase(); - } - } - } -} - -// Draw to OLED -bool oled_task_user(void) { - // Render Bongo Cat - render_animation(); - - // WPM text - oled_set_cursor(0, 0); - sprintf(wpm_str, "%03d", get_current_wpm()); // %03d defines digits to display - oled_write(wpm_str, false); - - // Layer text - oled_set_cursor(0, 1); - switch (get_highest_layer(layer_state)) { - case _MAC_DEFAULT : - oled_write_P(PSTR("MAC"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("MAIN"), false); - break; - case _MAC_CODE : - oled_write_P(PSTR("MAC"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("CODE"), false); - break; - case _MAC_NUM : - oled_write_P(PSTR("MAC"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("NUM"), false); - break; - case _MAC_FUNC : - oled_write_P(PSTR("MAC"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("FUNC"), false); - break; - case _WIN_DEFAULT : - oled_write_P(PSTR("WIN"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("MAIN"), false); - break; - case _WIN_CODE : - oled_write_P(PSTR("WIN"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("CODE"), false); - break; - case _WIN_NUM : - oled_write_P(PSTR("WIN"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("NUM"), false); - break; - case _WIN_FUNC : - oled_write_P(PSTR("WIN"), false); - oled_set_cursor(0, 2); - oled_write_P(PSTR("FUNC"), false); - break; - } - - // Caps lock text - led_t led_state = host_keyboard_led_state(); - oled_set_cursor(0, 3); - oled_write_P(led_state.caps_lock ? PSTR("CAPS") : PSTR(""), false); - - return false; -} -#endif - diff --git a/keyboards/handwired/jscotto/scotto36/keymaps/default/rules.mk b/keyboards/handwired/jscotto/scotto36/keymaps/default/rules.mk deleted file mode 100644 index 6e339da6c697..000000000000 --- a/keyboards/handwired/jscotto/scotto36/keymaps/default/rules.mk +++ /dev/null @@ -1,4 +0,0 @@ -OLED_ENABLE = yes -WPM_ENABLE = yes -LTO_ENABLE = yes -TAP_DANCE_ENABLE = yes \ No newline at end of file diff --git a/keyboards/handwired/jscotto/scotto36/readme.md b/keyboards/handwired/jscotto/scotto36/readme.md deleted file mode 100644 index f38d0231c587..000000000000 --- a/keyboards/handwired/jscotto/scotto36/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# Scotto36 - -![Scotto36](https://i.imgur.com/MCGv0ZHh.jpeg) - -A 36 key handwired ortholinear ergo keyboard. Featuring an OLED display with Bongo Cat. Case files available [here](https://github.com/joe-scotto/keyboards.git). - -- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) -- Hardware Supported: ATmega32U4 -- Hardware Availability: [Amazon](https://amazon.com) - - -# Compiling - -Make example for this keyboard (after setting up your build environment): - - make handwired/jscotto/scotto36:default - -Flashing example for this keyboard: - - make handwired/jscotto/scotto36:default - -# Bootloader -Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (0, 0) when plugging the board in to enter bootloader 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). diff --git a/keyboards/handwired/jscotto/scotto36/rules.mk b/keyboards/handwired/jscotto/scotto36/rules.mk deleted file mode 100644 index 6e7633bfe015..000000000000 --- a/keyboards/handwired/jscotto/scotto36/rules.mk +++ /dev/null @@ -1 +0,0 @@ -# This file intentionally left blank diff --git a/keyboards/handwired/jscotto/scotto40/info.json b/keyboards/handwired/jscotto/scotto40/info.json deleted file mode 100644 index 767ff1de5499..000000000000 --- a/keyboards/handwired/jscotto/scotto40/info.json +++ /dev/null @@ -1,180 +0,0 @@ -{ - "manufacturer": "Joe Scotto", - "keyboard_name": "Scotto40", - "maintainer": "joe-scotto", - "bootloader": "caterina", - "diode_direction": "COL2ROW", - "features": { - "bootmagic": true, - "command": false, - "console": false, - "extrakey": true, - "mousekey": true, - "nkro": true - }, - "matrix_pins": { - "cols": ["D1", "D0", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5"], - "rows": ["B1", "B3", "B2", "B6"] - }, - "processor": "atmega32u4", - "url": "", - "usb": { - "device_version": "1.0.0", - "pid": "0x0000", - "vid": "0xFEED" - }, - "layouts": { - "LAYOUT_ortho_3x10_7": { - "layout": [ - // Row 1 - {"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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"matrix": [3, 0], "x": 0, "y": 3}, - - {"matrix": [3, 2], "x": 2, "y": 3}, - {"matrix": [3, 3], "x": 3, "y": 3}, - {"matrix": [3, 4], "x": 4, "y": 3, "w": 2}, - {"matrix": [3, 6], "x": 6, "y": 3}, - {"matrix": [3, 7], "x": 7, "y": 3}, - - {"matrix": [3, 9], "x": 9, "y": 3} - ] - }, - "LAYOUT_ortho_3x10_8": { - "layout": [ - // Row 1 - {"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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"matrix": [3, 0], "x": 0, "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, 9], "x": 9, "y": 3} - ] - }, - "LAYOUT_ortho_4x10": { - "layout": [ - // Row 1 - {"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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"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} - ] - } - } -} diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h b/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h deleted file mode 100644 index 1a6512052c1d..000000000000 --- a/keyboards/handwired/jscotto/scotto40/keymaps/default/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#pragma once - -// Define options -#define TAPPING_TERM 135 -#define PERMISSIVE_HOLD -#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c deleted file mode 100644 index ba5f7bc7a8ca..000000000000 --- a/keyboards/handwired/jscotto/scotto40/keymaps/default/keymap.c +++ /dev/null @@ -1,114 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#include QMK_KEYBOARD_H - -// Tap Dance declarations -enum { - TD_ESC_SPOTLIGHT_EMOJI, - TD_ESC_WINDOWS_EMOJI -}; - -void td_esc_spotlight_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code16(G(KC_SPC)); - } else if (state->count == 3) { - tap_code16(C(G(KC_SPC))); - } -} - -void td_esc_windows_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code(KC_LGUI); - } else if (state->count == 3) { - tap_code16(G(KC_DOT)); - } -}; - - // Tap Dance definitions -tap_dance_action_t tap_dance_actions[] = { - [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), - [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) -}; - -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case TD(TD_ESC_SPOTLIGHT_EMOJI) : - case TD(TD_ESC_WINDOWS_EMOJI) : - case LGUI_T(KC_SPC) : - case LT(1, KC_TAB) : - case LT(2, KC_ENT) : - return 200; - default: - return TAPPING_TERM; - } -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT_ortho_3x10_7( - KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [1] = LAYOUT_ortho_3x10_7( - KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [2] = LAYOUT_ortho_3x10_7( - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [3] = LAYOUT_ortho_3x10_7( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) - ), - [4] = LAYOUT_ortho_3x10_7( - KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) - ), - [5] = LAYOUT_ortho_3x10_7( - KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) - ), - [6] = LAYOUT_ortho_3x10_7( - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) - ), - [7] = LAYOUT_ortho_3x10_7( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) - ) -}; diff --git a/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk b/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk deleted file mode 100644 index e5ddcae8d927..000000000000 --- a/keyboards/handwired/jscotto/scotto40/keymaps/default/rules.mk +++ /dev/null @@ -1 +0,0 @@ -TAP_DANCE_ENABLE = yes diff --git a/keyboards/handwired/jscotto/scotto40/readme.md b/keyboards/handwired/jscotto/scotto40/readme.md deleted file mode 100644 index 867313ecfc2b..000000000000 --- a/keyboards/handwired/jscotto/scotto40/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# Scotto40 - -![Scotto40](https://i.imgur.com/wtW5xOth.jpeg) - -A 37, 38, or 40 key handwired ortholinear keyboard. Case files available [here](https://github.com/joe-scotto/keyboards). - -- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) -- Hardware Supported: ATmega32U4 -- Hardware Availability: [Amazon](https://amazon.com) - -# Compiling - -Make example for this keyboard (after setting up your build environment): - - make handwired/jscotto/scotto40:default - -Flashing example for this keyboard: - - make handwired/jscotto/scotto40:default - -# Bootloader - -Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (0, 0) when plugging the board in to enter bootloader 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). diff --git a/keyboards/handwired/jscotto/scotto40/rules.mk b/keyboards/handwired/jscotto/scotto40/rules.mk deleted file mode 100644 index 6e7633bfe015..000000000000 --- a/keyboards/handwired/jscotto/scotto40/rules.mk +++ /dev/null @@ -1 +0,0 @@ -# This file intentionally left blank diff --git a/keyboards/handwired/jscotto/scotto9/info.json b/keyboards/handwired/jscotto/scotto9/info.json deleted file mode 100644 index 8bd393bd434b..000000000000 --- a/keyboards/handwired/jscotto/scotto9/info.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "manufacturer": "Joe Scotto", - "keyboard_name": "Scotto9", - "maintainer": "joe-scotto", - "bootloader": "caterina", - "diode_direction": "COL2ROW", - "features": { - "bootmagic": true, - "command": false, - "console": false, - "extrakey": true, - "mousekey": true, - "nkro": true - }, - "matrix_pins": { - // 4, 5, 6 - "cols": ["D4", "C6", "D7"], - // 15, 14, 16 - "rows": ["B1", "B3", "B2"] - }, - "processor": "atmega32u4", - "url": "", - "usb": { - "device_version": "1.0.0", - "pid": "0x0000", - "vid": "0xFEED" - }, - "layouts": { - "LAYOUT_ortho_3x3": { - "layout": [ - {"matrix": [0, 0], "x": 0, "y": 0}, - {"matrix": [0, 1], "x": 1, "y": 0}, - {"matrix": [0, 2], "x": 2, "y": 0}, - - // Row 2 - {"matrix": [1, 0], "x": 0, "y": 1}, - {"matrix": [1, 1], "x": 1, "y": 1}, - {"matrix": [1, 2], "x": 2, "y": 1}, - - // Row 3 - {"matrix": [2, 0], "x": 0, "y": 2}, - {"matrix": [2, 1], "x": 1, "y": 2}, - {"matrix": [2, 2], "x": 2, "y": 2} - ] - } - } -} diff --git a/keyboards/handwired/jscotto/scotto9/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scotto9/keymaps/default/keymap.c deleted file mode 100644 index eec8d684ada3..000000000000 --- a/keyboards/handwired/jscotto/scotto9/keymaps/default/keymap.c +++ /dev/null @@ -1,27 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#include QMK_KEYBOARD_H - -// Keymap -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT_ortho_3x3( - KC_1, KC_2, KC_3, - KC_4, KC_5, KC_6, - KC_7, KC_8, KC_9 - ) -}; diff --git a/keyboards/handwired/jscotto/scotto9/readme.md b/keyboards/handwired/jscotto/scotto9/readme.md deleted file mode 100644 index 2e5291cba730..000000000000 --- a/keyboards/handwired/jscotto/scotto9/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# Scotto9 - -![Scotto9](https://imgur.com/inbmNSEh.jpeg) - -A 9 key handwired macropad. Case files available [here](https://github.com/joe-scotto/keyboards.git). - -- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) -- Hardware Supported: ATmega32U4 -- Hardware Availability: [Amazon](https://amazon.com) - -# Compiling - -Make example for this keyboard (after setting up your build environment): - - make handwired/jscotto/scotto9:default - -Flashing example for this keyboard: - - make handwired/jscotto/scotto9:default - -# Bootloader - -Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (0, 0) when plugging the board in to enter bootloader 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). diff --git a/keyboards/handwired/jscotto/scotto9/rules.mk b/keyboards/handwired/jscotto/scotto9/rules.mk deleted file mode 100644 index 6e7633bfe015..000000000000 --- a/keyboards/handwired/jscotto/scotto9/rules.mk +++ /dev/null @@ -1 +0,0 @@ -# This file intentionally left blank diff --git a/keyboards/handwired/jscotto/scottocmd/config.h b/keyboards/handwired/jscotto/scottocmd/config.h deleted file mode 100644 index a168f0ef218f..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/config.h +++ /dev/null @@ -1,21 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#pragma once - -// OLED -#define OLED_DISPLAY_128X64 \ No newline at end of file diff --git a/keyboards/handwired/jscotto/scottocmd/info.json b/keyboards/handwired/jscotto/scottocmd/info.json deleted file mode 100644 index 991be93b52cc..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/info.json +++ /dev/null @@ -1,86 +0,0 @@ -{ - "manufacturer": "Joe Scotto", - "keyboard_name": "ScottoCMD", - "maintainer": "joe-scotto", - "bootloader": "caterina", - "diode_direction": "COL2ROW", - "features": { - "bootmagic": true, - "command": false, - "console": false, - "extrakey": true, - "mousekey": true, - "nkro": true - }, - "matrix_pins": { - // TX0, RX1, 4, 5, 6, 7, 8, 9, A3, A2, A1 - "cols": ["D3", "D2", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5", "F6"], - // A0, 15, 14, 16, 10 - "rows": ["F7", "B1", "B3", "B2", "B6"] - }, - "processor": "atmega32u4", - "url": "", - "usb": { - "device_version": "1.0.0", - "pid": "0x0000", - "vid": "0xFEED" - }, - "bootmagic": { - "matrix": [1, 0] - }, - "layouts": { - "LAYOUT_ortho_4_3x10_4": { - "layout": [ - // Row 1 (Macros) - {"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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"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}, - - // Row 5 - {"matrix": [4, 1], "x": 1, "y": 4}, - {"matrix": [4, 5], "x": 5, "y": 4}, - {"matrix": [4, 9], "x": 9, "y": 4}, - {"matrix": [4, 10], "x": 10, "y": 4} - ] - } - } -} diff --git a/keyboards/handwired/jscotto/scottocmd/keymaps/default/config.h b/keyboards/handwired/jscotto/scottocmd/keymaps/default/config.h deleted file mode 100644 index 1a6512052c1d..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/keymaps/default/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#pragma once - -// Define options -#define TAPPING_TERM 135 -#define PERMISSIVE_HOLD -#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/jscotto/scottocmd/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scottocmd/keymaps/default/keymap.c deleted file mode 100644 index b1c77ae94470..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/keymaps/default/keymap.c +++ /dev/null @@ -1,515 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#include QMK_KEYBOARD_H - -#include -char wpm_str[10]; - -// Tap Dance declarations -enum { - TD_ESC_SPOTLIGHT_EMOJI, - TD_ESC_WINDOWS_EMOJI -}; - -void td_esc_spotlight_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code16(G(KC_SPC)); - } else if (state->count == 3) { - tap_code16(C(G(KC_SPC))); - } -} - -void td_esc_windows_emoji (tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - tap_code(KC_ESC); - } else if (state->count == 2) { - tap_code(KC_LGUI); - } else if (state->count == 3) { - tap_code16(G(KC_DOT)); - } -}; - - // Tap Dance definitions -tap_dance_action_t tap_dance_actions[] = { - [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), - [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) -}; - -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case TD(TD_ESC_SPOTLIGHT_EMOJI) : - case TD(TD_ESC_WINDOWS_EMOJI) : - case LGUI_T(KC_SPC) : - case LT(1, KC_TAB) : - case LT(2, KC_ENT) : - return 200; - default: - return TAPPING_TERM; - } -}; - -// Layer Names -enum layer_names { - _MAC_DEFAULT, - _MAC_CODE, - _MAC_NUM, - _MAC_FUNC, - _WIN_DEFAULT, - _WIN_CODE, - _WIN_NUM, - _WIN_FUNC -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT_ortho_4_3x10_4( - KC_LCTL, KC_2, KC_3, TD(TD_ESC_SPOTLIGHT_EMOJI), - KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_ENT, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT) - ), - [1] = LAYOUT_ortho_4_3x10_4( - KC_LCTL, KC_2, KC_3, TD(TD_ESC_SPOTLIGHT_EMOJI), - KC_TAB, KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_ENT, KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS - ), - [2] = LAYOUT_ortho_4_3x10_4( - KC_LCTL, KC_2, KC_3, TD(TD_ESC_SPOTLIGHT_EMOJI), - KC_TAB, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_ENT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS - ), - [3] = LAYOUT_ortho_4_3x10_4( - KC_LCTL, KC_2, KC_3, TD(TD_ESC_SPOTLIGHT_EMOJI), - KC_TAB, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), - KC_ENT, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS - ), - [4] = LAYOUT_ortho_4_3x10_4( - KC_1, KC_2, KC_3, TD(TD_ESC_WINDOWS_EMOJI), - KC_TAB, KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, - KC_ENT, KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), - KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT) - ), - [5] = LAYOUT_ortho_4_3x10_4( - KC_1, KC_2, KC_3, TD(TD_ESC_WINDOWS_EMOJI), - KC_TAB, KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, - KC_ENT, KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), - KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS - ), - [6] = LAYOUT_ortho_4_3x10_4( - KC_1, KC_2, KC_3, TD(TD_ESC_WINDOWS_EMOJI), - KC_TAB, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, - KC_ENT, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), - KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS - ), - [7] = LAYOUT_ortho_4_3x10_4( - KC_1, KC_2, KC_3, TD(TD_ESC_WINDOWS_EMOJI), - KC_TAB, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), - KC_ENT, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, - KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS - ) -}; - -// OLED -#ifdef OLED_ENABLE -// WPM responsiveness -#define IDLE_FRAMES 5 // How many idle frames in animation -#define IDLE_SPEED 20 // Speed at which animation idles -#define TAP_FRAMES 2 // How many tapping frames -#define TAP_SPEED 40 // WPM to trigger Bongo -#define ANIMATION_FRAME_DURATION 200 // MS duration of each frame -#define ANIMATION_SIZE 256 // Number of bytes per animation frame - -uint32_t anim_timer = 0; -uint32_t anim_sleep = 0; -uint8_t current_idle_frame = 0; -uint8_t current_tap_frame = 0; - -oled_rotation_t oled_init_user(oled_rotation_t rotation) { - return OLED_ROTATION_90; // flips the display 180 degrees if offhand -} - -static void render_animation(void) { - static const char PROGMEM idle[IDLE_FRAMES][ANIMATION_SIZE] = { - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, - 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x31, 0xc1, 0x01, 0x01, 0x01, 0x02, 0x02, - 0x02, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, - 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, - 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x34, 0xc4, 0x04, 0x04, 0x04, 0x08, 0x08, - 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, - 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, - 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x02, 0x02, 0x04, 0x04, 0x08, - 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x08, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, - 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, - 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, - 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, - 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, - 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, - 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, - 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - }; - static const char PROGMEM prep[][ANIMATION_SIZE] = { - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, - 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, - 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, - 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, - 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - }; - static const char PROGMEM tap[TAP_FRAMES][ANIMATION_SIZE] = { - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, - 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, - 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, - 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, - 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x98, 0xc0, 0x88, 0x88, 0x8c, 0x9c, - 0x1c, 0x1e, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, - 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, - 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, - 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, - 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, - 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, - 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, - 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, - 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x0f, 0x07, 0x03, 0x03, 0x61, - 0xf0, 0xf8, 0xfc, 0x60, 0x01, 0x01, 0x01, 0x3c, 0x78, 0xf8, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00 - } - }; - - void animation_phase(void) { - // Set cursor to draw from the bottom up - oled_set_cursor(128, 0); - - if (get_current_wpm() <= IDLE_SPEED) { - current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES; - oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIMATION_SIZE); - } - - // Start prep image - if (get_current_wpm() > IDLE_SPEED && get_current_wpm() < TAP_SPEED) { - oled_write_raw_P(prep[0], ANIMATION_SIZE); - } - - // Start tap animation - if (get_current_wpm() >= TAP_SPEED) { - current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES; - oled_write_raw_P(tap[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIMATION_SIZE); - } - } - if (get_current_wpm() != 000) { - oled_on(); // Enables OLED on any alpha keypress - - if (timer_elapsed32(anim_timer) > ANIMATION_FRAME_DURATION) { - anim_timer = timer_read32(); - animation_phase(); - } - - anim_sleep = timer_read32(); - } else { - if (timer_elapsed32(anim_sleep) > OLED_TIMEOUT) { - oled_off(); - } else { - if (timer_elapsed32(anim_timer) > ANIMATION_FRAME_DURATION) { - anim_timer = timer_read32(); - animation_phase(); - } - } - } -} - -// Draw to OLED -bool oled_task_user(void) { - // Caps lock text - led_t led_state = host_keyboard_led_state(); - oled_set_cursor(0,1); - oled_write_P(led_state.caps_lock ? PSTR(" Caps Lock "): PSTR(" ScottoCMD "), false); - - //WPM text - oled_set_cursor(0, 9); - oled_write(get_u8_str(get_current_wpm(), '0'), false); - oled_write_P(PSTR(" WPM"), false); - - static const char PROGMEM logos[][256] = { - // Apple - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x70, 0x78, 0x7c, 0x3e, 0x1f, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, - 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0x0e, 0x04, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xc0, 0x80, 0x80, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x0f, 0x1f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x7f, - 0x7f, 0x7f, 0x7f, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x0f, 0x07, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - }, - - // Windows - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xf0, 0xf8, 0xf8, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, - 0xf8, 0xf8, 0x00, 0x80, 0xe0, 0xc0, 0xc0, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xc0, 0x40, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xb8, 0x9f, 0x9f, 0x9f, 0x9f, 0x8f, 0x9f, 0x9f, 0x9f, 0x1f, 0x3f, 0x3f, - 0x07, 0xc0, 0xf8, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x07, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0xe0, 0xfc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0x03, 0xe0, - 0xfc, 0xfc, 0xf9, 0xf9, 0xf9, 0xf3, 0xf3, 0xf3, 0xfb, 0xfb, 0xf9, 0x19, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x02, 0x03, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x03, 0x03, 0x07, 0x01, 0x00, 0x1e, 0x1f, - 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x3f, 0x1f, 0x1f, 0x0f, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - }, - - // Code - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x80, 0xc0, 0xe0, 0xf0, 0x78, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, - 0xf8, 0xfc, 0x3f, 0x0f, 0x03, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x3c, 0x78, 0xf0, 0xe0, 0xc0, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x03, 0x07, 0x0f, 0x3e, 0x3c, 0x38, 0x00, 0x00, 0x00, 0xc0, 0xf0, 0xfc, 0x7e, 0x1f, 0x07, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x3c, 0x3e, 0x0f, 0x07, 0x03, 0x01, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - - // Number - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x1f, - 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x1e, 0x1e, 0x1e, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1e, - 0x1e, 0x1e, 0xbe, 0xff, 0xff, 0xff, 0xff, 0x3f, 0x1e, 0x1e, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x78, 0x78, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x78, 0x78, - 0x78, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x78, 0x78, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, - 0xc0, 0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - - }, - - // Function - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xf0, - 0xf8, 0xfc, 0xfe, 0xfe, 0xff, 0x9f, 0x0f, 0x07, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0x8f, 0x3f, - 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xf8, 0xf8, 0xfc, 0xfe, 0x7f, 0x3f, 0x0f, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x7f, 0x3e, - 0x1e, 0x0c, 0x01, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x78, 0xfc, 0xff, 0xff, 0xff, 0x7f, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - }, - - // Caps Lock - { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0xc0, 0xc0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, 0xe0, - 0xc0, 0xc0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xe0, 0xf8, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfc, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x03, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x1f, 0x1f, 0x3f, 0x3f, 0x3f, 0x7f, 0x7f, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfc, 0xf8, 0xf8, 0xf0, 0xe0, 0xe0, 0xc0, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, - 0x01, 0x03, 0x03, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x03, 0x03, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 - } - }; - - // Layer images - oled_set_cursor(32, 0); - switch (get_highest_layer(layer_state)) { - case _MAC_DEFAULT : - oled_write_raw_P(logos[0], sizeof(logos[0])); - break; - case _WIN_DEFAULT : - oled_write_raw_P(logos[1], sizeof(logos[1])); - break; - case _MAC_CODE : - case _WIN_CODE : - oled_write_raw_P(logos[2], sizeof(logos[2])); - break; - case _MAC_NUM : - case _WIN_NUM : - oled_write_raw_P(logos[3], sizeof(logos[3])); - break; - case _MAC_FUNC : - case _WIN_FUNC : - oled_write_raw_P(logos[4], sizeof(logos[4])); - break; - } - - // Render Bongo Cat - render_animation(); - - return false; -} -#endif diff --git a/keyboards/handwired/jscotto/scottocmd/keymaps/default/rules.mk b/keyboards/handwired/jscotto/scottocmd/keymaps/default/rules.mk deleted file mode 100644 index bcee933e75eb..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/keymaps/default/rules.mk +++ /dev/null @@ -1,2 +0,0 @@ -WPM_ENABLE = yes -TAP_DANCE_ENABLE = yes diff --git a/keyboards/handwired/jscotto/scottocmd/readme.md b/keyboards/handwired/jscotto/scottocmd/readme.md deleted file mode 100644 index b08d02d678e8..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# ScottoCMD - -![ScottoCMD](https://i.imgur.com/rxiMZNnh.jpg) - -A 40 key handwired ortholinear keyboard with non-ortho bottom row. Featuring a 128x64 OLED display along with a 6.25u spacebar. Case files available [here](https://github.com/joe-scotto/keyboards.git). - -- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) -- Hardware Supported: ATmega32U4 -- Hardware Availability: [Amazon](https://amazon.com) - -# Compiling - -Make example for this keyboard (after setting up your build environment): - - make handwired/jscotto/scottocmd:default - -Flashing example for this keyboard: - - make handwired/jscotto/scottocmd:default - -# Bootloader - -Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (1, 0) when plugging the board in to enter bootloader 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). diff --git a/keyboards/handwired/jscotto/scottocmd/rules.mk b/keyboards/handwired/jscotto/scottocmd/rules.mk deleted file mode 100644 index 9f00574d5d01..000000000000 --- a/keyboards/handwired/jscotto/scottocmd/rules.mk +++ /dev/null @@ -1,2 +0,0 @@ -OLED_ENABLE = yes -LTO_ENABLE = yes diff --git a/keyboards/handwired/jscotto/scottostarter/info.json b/keyboards/handwired/jscotto/scottostarter/info.json deleted file mode 100644 index 65fe2d931067..000000000000 --- a/keyboards/handwired/jscotto/scottostarter/info.json +++ /dev/null @@ -1,95 +0,0 @@ -{ - "manufacturer": "Joe Scotto", - "keyboard_name": "ScottoStarter", - "maintainer": "joe-scotto", - "bootloader": "caterina", - "diode_direction": "COL2ROW", - "features": { - "bootmagic": true, - "command": false, - "console": false, - "extrakey": true, - "mousekey": true, - "nkro": true - }, - "matrix_pins": { - // RX1, 4, 5, 6, 7, 8, 9, A3, A2, A1, TX0 - "cols": ["D2", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5", "F6", "D3"], - // A0, 15, 14, 16, 10 - "rows": ["F7", "B1", "B3", "B2", "B6"] - }, - "processor": "atmega32u4", - "url": "", - "usb": { - "device_version": "1.0.0", - "pid": "0x0000", - "vid": "0xFEED" - }, - "layouts": { - "LAYOUT_ortho_4x11_8": { - "layout": [ - // Row 1 - {"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}, - - // Row 2 - {"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}, - - // Row 3 - {"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}, - - // Row 4 - {"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}, - - // Row 5 - {"matrix": [4, 0], "x": 0, "y": 4}, - {"matrix": [4, 1], "x": 1, "y": 4}, - {"matrix": [4, 2], "x": 2, "y": 4}, - {"matrix": [4, 4], "x": 4, "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} - ] - } - } -} diff --git a/keyboards/handwired/jscotto/scottostarter/keymaps/default/config.h b/keyboards/handwired/jscotto/scottostarter/keymaps/default/config.h deleted file mode 100644 index 1a6512052c1d..000000000000 --- a/keyboards/handwired/jscotto/scottostarter/keymaps/default/config.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#pragma once - -// Define options -#define TAPPING_TERM 135 -#define PERMISSIVE_HOLD -#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/jscotto/scottostarter/keymaps/default/keymap.c b/keyboards/handwired/jscotto/scottostarter/keymaps/default/keymap.c deleted file mode 100644 index fb47637f189d..000000000000 --- a/keyboards/handwired/jscotto/scottostarter/keymaps/default/keymap.c +++ /dev/null @@ -1,52 +0,0 @@ -/* -Copyright 2022 Joe Scotto - -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 . -*/ - -#include QMK_KEYBOARD_H - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT_ortho_4x11_8( - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, - KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_TAB, - KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, - LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), KC_ENT, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), MO(2), KC_ESC, KC_CAPS - ), - [1] = LAYOUT_ortho_4x11_8( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_DEL, - KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_NO, KC_TAB, - KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, KC_QUOT, - LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILD, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), KC_ENT, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS - ), - [2] = LAYOUT_ortho_4x11_8( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSPC, - KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, KC_TAB, - KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_QUOT, - KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), KC_ENT, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS - ), - [3] = LAYOUT_ortho_4x11_8( - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSPC, - KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), KC_TAB, - KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_QUOT, - KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, KC_ENT, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS - ) -}; - - - diff --git a/keyboards/handwired/jscotto/scottostarter/readme.md b/keyboards/handwired/jscotto/scottostarter/readme.md deleted file mode 100644 index 5886bc9d3b0d..000000000000 --- a/keyboards/handwired/jscotto/scottostarter/readme.md +++ /dev/null @@ -1,25 +0,0 @@ -# ScottoStarter - -![ScottoStarter](https://i.imgur.com/bspbVPah.jpg) - -A 52 key ortholinear keyboard that is designed to help transition you into smaller layouts. Case files available [here](https://github.com/joe-scotto/keyboards.git). - -- Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) -- Hardware Supported: ATmega32U4 -- Hardware Availability: [Amazon](https://amazon.com) - -# Compiling - -Make example for this keyboard (after setting up your build environment): - - make handwired/jscotto/scottostarter:default - -Flashing example for this keyboard: - - make handwired/jscotto/scottostarter:default - -# Bootloader - -Uses [bootmagic](https://github.com/qmk/qmk_firmware/blob/master/docs/feature_bootmagic.md) allowing you to hold the top left key (0, 0) when plugging the board in to enter bootloader 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). diff --git a/keyboards/handwired/jscotto/scottostarter/rules.mk b/keyboards/handwired/jscotto/scottostarter/rules.mk deleted file mode 100644 index 7ff128fa692e..000000000000 --- a/keyboards/handwired/jscotto/scottostarter/rules.mk +++ /dev/null @@ -1 +0,0 @@ -# This file intentionally left blank \ No newline at end of file From 3740c52b612b5fac8b284d80e367009dd484bb6e Mon Sep 17 00:00:00 2001 From: Joe Scotto Date: Wed, 7 Jun 2023 11:01:10 -0400 Subject: [PATCH 2/3] Add aliases for boards --- data/mappings/keyboard_aliases.hjson | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/data/mappings/keyboard_aliases.hjson b/data/mappings/keyboard_aliases.hjson index a656288a8fb6..d0fe4a2df012 100644 --- a/data/mappings/keyboard_aliases.hjson +++ b/data/mappings/keyboard_aliases.hjson @@ -218,6 +218,21 @@ "handwired/ibm122m": { "target": "ibm/model_m_122/ibm122m" }, + "handwired/jscotto/scotto9": { + "target": "handwired/scottokeebs/scotto9" + }, + "handwired/jscotto/scotto36": { + "target": "handwired/scottokeebs/scotto36" + }, + "handwired/jscotto/scotto40": { + "target": "handwired/scottokeebs/scotto40" + }, + "handwired/jscotto/scottocmd": { + "target": "handwired/scottokeebs/scottocmd" + }, + "handwired/jscotto/scottostarter": { + "target": "handwired/scottokeebs/scottostarter" + }, "handwired/p1800fl": { "target": "team0110/p1800fl" }, From 9a7deb36b2b458dc86c3683d4df0c6f9a2b566d7 Mon Sep 17 00:00:00 2001 From: Joe Scotto Date: Wed, 7 Jun 2023 11:51:57 -0400 Subject: [PATCH 3/3] revert --- docs/.nojekyll | 0 docs/CNAME | 1 - docs/ChangeLog/20190830.md | 52 - docs/ChangeLog/20200229.md | 75 - docs/ChangeLog/20200530.md | 239 --- docs/ChangeLog/20200829.md | 148 -- docs/ChangeLog/20201128.md | 150 -- docs/ChangeLog/20210227.md | 169 -- docs/ChangeLog/20210529.md | 227 --- docs/ChangeLog/20210828.md | 557 ------ docs/ChangeLog/20211127.md | 457 ----- docs/ChangeLog/20220226.md | 489 ------ docs/ChangeLog/20220528.md | 216 --- docs/ChangeLog/20220827.md | 343 ---- docs/ChangeLog/20221126.md | 510 ------ docs/ChangeLog/20230226.md | 367 ---- docs/ChangeLog/20230528.md | 551 ------ docs/README.md | 37 - docs/_langs.md | 4 - docs/_summary.md | 204 --- docs/adc_driver.md | 173 -- docs/api_development_environment.md | 3 - docs/api_development_overview.md | 44 - docs/api_docs.md | 106 -- docs/api_overview.md | 15 - docs/arm_debugging.md | 87 - docs/audio_driver.md | 219 --- docs/breaking_changes.md | 180 -- docs/breaking_changes_history.md | 19 - docs/breaking_changes_instructions.md | 34 - docs/chibios_upgrade_instructions.md | 72 - docs/cli.md | 38 - docs/cli_commands.md | 658 ------- docs/cli_configuration.md | 121 -- docs/cli_development.md | 219 --- docs/cli_tab_complete.md | 31 - docs/coding_conventions_c.md | 58 - docs/coding_conventions_python.md | 326 ---- docs/compatible_microcontrollers.md | 84 - docs/config_options.md | 485 ------ docs/configurator_architecture.md | 61 - docs/configurator_default_keymaps.md | 191 --- docs/configurator_diagram.drawio | 1 - docs/configurator_diagram.svg | 3 - docs/configurator_step_by_step.md | 58 - docs/configurator_troubleshooting.md | 26 - docs/contributing.md | 168 -- docs/custom_matrix.md | 108 -- docs/custom_quantum_functions.md | 362 ---- docs/data_driven_config.md | 92 - docs/documentation_best_practices.md | 64 - docs/documentation_templates.md | 52 - docs/driver_installation_zadig.md | 99 -- docs/easy_maker.md | 31 - docs/eeprom_driver.md | 160 -- docs/faq_build.md | 69 - docs/faq_debug.md | 136 -- docs/faq_general.md | 53 - docs/faq_keymap.md | 151 -- docs/faq_misc.md | 113 -- docs/feature_advanced_keycodes.md | 187 -- docs/feature_audio.md | 367 ---- docs/feature_auto_shift.md | 347 ---- docs/feature_autocorrect.md | 307 ---- docs/feature_backlight.md | 220 --- docs/feature_bluetooth.md | 46 - docs/feature_bootmagic.md | 81 - docs/feature_caps_word.md | 189 -- docs/feature_combo.md | 397 ----- docs/feature_command.md | 51 - docs/feature_converters.md | 209 --- docs/feature_debounce_type.md | 134 -- docs/feature_digitizer.md | 117 -- docs/feature_dip_switch.md | 109 -- docs/feature_dynamic_macros.md | 67 - docs/feature_eeprom.md | 134 -- docs/feature_encoders.md | 176 -- docs/feature_grave_esc.md | 32 - docs/feature_haptic_feedback.md | 213 --- docs/feature_hd44780.md | 298 ---- docs/feature_joystick.md | 228 --- docs/feature_key_lock.md | 23 - docs/feature_key_overrides.md | 227 --- docs/feature_layers.md | 188 -- docs/feature_layouts.md | 109 -- docs/feature_leader_key.md | 297 ---- docs/feature_led_indicators.md | 121 -- docs/feature_led_matrix.md | 454 ----- docs/feature_macros.md | 410 ----- docs/feature_midi.md | 264 --- docs/feature_mouse_keys.md | 207 --- docs/feature_oled_driver.md | 460 ----- docs/feature_os_detection.md | 77 - docs/feature_pointing_device.md | 824 --------- docs/feature_programmable_button.md | 144 -- docs/feature_ps2_mouse.md | 326 ---- docs/feature_rawhid.md | 69 - docs/feature_repeat_key.md | 457 ----- docs/feature_rgb_matrix.md | 1096 ------------ docs/feature_rgblight.md | 585 ------- docs/feature_secure.md | 54 - docs/feature_send_string.md | 224 --- docs/feature_sequencer.md | 87 - docs/feature_space_cadet.md | 60 - docs/feature_split_keyboard.md | 486 ------ docs/feature_st7565.md | 274 --- docs/feature_stenography.md | 215 --- docs/feature_swap_hands.md | 57 - docs/feature_tap_dance.md | 563 ------ docs/feature_tri_layer.md | 48 - docs/feature_unicode.md | 8 +- docs/feature_userspace.md | 255 --- docs/feature_velocikey.md | 29 - docs/feature_wpm.md | 76 - docs/flash_driver.md | 24 - docs/flashing.md | 444 ----- docs/flashing_bootloadhid.md | 70 - docs/fuse.txt | 49 - docs/getting_started_docker.md | 55 - docs/getting_started_github.md | 64 - docs/getting_started_introduction.md | 60 - docs/getting_started_make_guide.md | 2 +- docs/gitbook/images/color-wheel.svg | 441 ----- docs/gitbook/images/favicon.ico | Bin 1150 -> 0 bytes docs/gitbook/images/favicon.png | Bin 793 -> 0 bytes docs/gpio_control.md | 44 - docs/hand_wire.md | 249 --- docs/hardware_drivers.md | 35 - docs/hardware_keyboard_guidelines.md | 263 --- docs/how_a_matrix_works.md | 99 -- docs/how_keyboards_work.md | 76 - docs/i2c_driver.md | 278 --- docs/index.html | 147 -- docs/internals/defines.md | 78 - docs/internals/input_callback_reg.md | 169 -- docs/internals/midi_device.md | 143 -- docs/internals/midi_device_setup_process.md | 31 - docs/internals/midi_util.md | 54 - docs/internals/send_functions.md | 241 --- docs/internals/sysex_tools.md | 61 - docs/isp_flashing_guide.md | 387 ----- docs/ja/README.md | 47 - docs/ja/_summary.md | 181 -- docs/ja/adc_driver.md | 155 -- docs/ja/api_development_environment.md | 8 - docs/ja/api_development_overview.md | 49 - docs/ja/api_docs.md | 73 - docs/ja/api_overview.md | 20 - docs/ja/arm_debugging.md | 92 - docs/ja/breaking_changes.md | 120 -- docs/ja/breaking_changes_instructions.md | 51 - docs/ja/cli.md | 43 - docs/ja/cli_commands.md | 296 ---- docs/ja/cli_configuration.md | 126 -- docs/ja/cli_development.md | 223 --- docs/ja/coding_conventions_c.md | 63 - docs/ja/coding_conventions_python.md | 331 ---- docs/ja/compatible_microcontrollers.md | 54 - docs/ja/config_options.md | 410 ----- docs/ja/configurator_step_by_step.md | 67 - docs/ja/configurator_troubleshooting.md | 32 - docs/ja/contributing.md | 173 -- docs/ja/custom_matrix.md | 114 -- docs/ja/custom_quantum_functions.md | 403 ----- docs/ja/data_driven_config.md | 123 -- docs/ja/documentation_best_practices.md | 69 - docs/ja/documentation_templates.md | 45 - docs/ja/driver_installation_zadig.md | 53 - docs/ja/faq_build.md | 73 - docs/ja/faq_debug.md | 131 -- docs/ja/faq_general.md | 58 - docs/ja/faq_keymap.md | 160 -- docs/ja/faq_misc.md | 103 -- docs/ja/feature_advanced_keycodes.md | 185 -- docs/ja/feature_audio.md | 322 ---- docs/ja/feature_auto_shift.md | 135 -- docs/ja/feature_backlight.md | 225 --- docs/ja/feature_bluetooth.md | 49 - docs/ja/feature_bootmagic.md | 182 -- docs/ja/feature_combo.md | 108 -- docs/ja/feature_command.md | 56 - docs/ja/feature_debounce_type.md | 128 -- docs/ja/feature_dip_switch.md | 115 -- docs/ja/feature_dynamic_macros.md | 72 - docs/ja/feature_encoders.md | 85 - docs/ja/feature_grave_esc.md | 37 - docs/ja/feature_haptic_feedback.md | 173 -- docs/ja/feature_hd44780.md | 62 - docs/ja/feature_key_lock.md | 27 - docs/ja/feature_layers.md | 97 -- docs/ja/feature_layouts.md | 114 -- docs/ja/feature_leader_key.md | 164 -- docs/ja/feature_led_indicators.md | 119 -- docs/ja/feature_led_matrix.md | 96 -- docs/ja/feature_macros.md | 303 ---- docs/ja/feature_mouse_keys.md | 147 -- docs/ja/feature_pointing_device.md | 58 - docs/ja/feature_ps2_mouse.md | 288 ---- docs/ja/feature_rawhid.md | 74 - docs/ja/feature_split_keyboard.md | 251 --- docs/ja/feature_stenography.md | 135 -- docs/ja/feature_swap_hands.md | 36 - docs/ja/feature_tap_dance.md | 530 ------ docs/ja/feature_thermal_printer.md | 15 - docs/ja/feature_unicode.md | 266 --- docs/ja/feature_userspace.md | 260 --- docs/ja/feature_velocikey.md | 34 - docs/ja/feature_wpm.md | 24 - docs/ja/flashing.md | 247 --- docs/ja/flashing_bootloadhid.md | 75 - docs/ja/getting_started_docker.md | 60 - docs/ja/getting_started_github.md | 69 - docs/ja/getting_started_introduction.md | 65 - docs/ja/getting_started_make_guide.md | 161 -- docs/ja/gpio_control.md | 47 - docs/ja/hardware_avr.md | 190 -- docs/ja/hardware_drivers.md | 41 - docs/ja/hardware_keyboard_guidelines.md | 239 --- docs/ja/how_a_matrix_works.md | 104 -- docs/ja/how_keyboards_work.md | 74 - docs/ja/i2c_driver.md | 135 -- docs/ja/isp_flashing_guide.md | 294 ---- docs/ja/ja_doc_status.sh | 34 - docs/ja/keycodes.md | 574 ------- docs/ja/keycodes_basic.md | 261 --- docs/ja/keycodes_us_ansi_shifted.md | 41 - docs/ja/keymap.md | 189 -- docs/ja/mod_tap.md | 71 - docs/ja/newbs.md | 40 - docs/ja/newbs_building_firmware.md | 81 - .../newbs_building_firmware_configurator.md | 20 - docs/ja/newbs_flashing.md | 133 -- docs/ja/newbs_getting_started.md | 210 --- docs/ja/newbs_git_best_practices.md | 24 - .../ja/newbs_git_resolving_merge_conflicts.md | 94 - docs/ja/newbs_git_resynchronize_a_branch.md | 88 - docs/ja/newbs_git_using_your_master_branch.md | 101 -- docs/ja/newbs_learn_more_resources.md | 63 - docs/ja/newbs_testing_debugging.md | 15 - docs/ja/one_shot_keys.md | 110 -- docs/ja/other_eclipse.md | 89 - docs/ja/other_vscode.md | 119 -- docs/ja/pr_checklist.md | 145 -- docs/ja/proton_c_conversion.md | 98 -- docs/ja/quantum_keycodes.md | 20 - docs/ja/ref_functions.md | 124 -- docs/ja/reference_configurator_support.md | 200 --- docs/ja/reference_glossary.md | 173 -- docs/ja/reference_info_json.md | 68 - docs/ja/reference_keymap_extras.md | 89 - docs/ja/serial_driver.md | 75 - docs/ja/support.md | 22 - docs/ja/syllabus.md | 76 - docs/ja/tap_hold.md | 167 -- docs/ja/translating.md | 60 - docs/ja/understanding_qmk.md | 190 -- docs/keycodes.md | 4 +- docs/keycodes_basic.md | 260 --- docs/keycodes_magic.md | 41 - docs/keycodes_us_ansi_shifted.md | 37 - docs/keymap.md | 191 --- docs/mod_tap.md | 135 -- docs/newbs.md | 24 - docs/newbs_building_firmware.md | 78 - docs/newbs_building_firmware_configurator.md | 13 - docs/newbs_building_firmware_workflow.md | 192 --- docs/newbs_flashing.md | 120 -- docs/newbs_getting_started.md | 189 -- docs/newbs_git_best_practices.md | 16 - docs/newbs_git_resolving_merge_conflicts.md | 79 - docs/newbs_git_resynchronize_a_branch.md | 71 - docs/newbs_git_using_your_master_branch.md | 74 - docs/newbs_learn_more_resources.md | 28 - docs/newbs_testing_debugging.md | 9 - docs/one_shot_keys.md | 105 -- docs/other_eclipse.md | 90 - docs/other_vscode.md | 119 -- docs/platformdev_blackpill_f4x1.md | 49 - docs/platformdev_chibios_earlyinit.md | 63 - docs/platformdev_proton_c.md | 77 - docs/platformdev_rp2040.md | 141 -- docs/platformdev_selecting_arm_mcu.md | 58 - docs/porting_your_keyboard_to_qmk.md | 164 -- docs/power.txt | 62 - docs/pr_checklist.md | 226 --- docs/qmk.css | 862 ---------- docs/qmk_custom_dark.css | 41 - docs/qmk_custom_light.css | 58 - docs/quantum_keycodes.md | 17 - docs/quantum_painter.md | 896 ---------- docs/quantum_painter_lvgl.md | 55 - docs/quantum_painter_qff.md | 103 -- docs/quantum_painter_qgf.md | 178 -- docs/quantum_painter_rle.md | 29 - docs/redirects.json | 52 - docs/ref_functions.md | 123 -- docs/reference_configurator_support.md | 195 --- docs/reference_glossary.md | 167 -- docs/reference_info_json.md | 369 ---- docs/reference_keymap_extras.md | 92 - docs/serial_driver.md | 383 ----- docs/spi_driver.md | 150 -- docs/squeezing_avr.md | 201 --- docs/support.md | 17 - docs/support_deprecation_policy.md | 44 - docs/sw.js | 83 - docs/syllabus.md | 72 - docs/tap_hold.md | 475 ----- docs/translating.md | 55 - docs/uart_driver.md | 116 -- docs/understanding_qmk.md | 198 --- docs/unit_testing.md | 76 - docs/usb_nkro.txt | 160 -- docs/ws2812_driver.md | 189 -- docs/zh-cn/README.md | 42 - docs/zh-cn/_summary.md | 192 --- docs/zh-cn/api_docs.md | 73 - docs/zh-cn/api_overview.md | 20 - docs/zh-cn/cli.md | 43 - docs/zh-cn/cli_commands.md | 503 ------ docs/zh-cn/cli_configuration.md | 126 -- docs/zh-cn/cli_tab_complete.md | 32 - docs/zh-cn/configurator_architecture.md | 66 - docs/zh-cn/configurator_default_keymaps.md | 198 --- docs/zh-cn/configurator_step_by_step.md | 63 - docs/zh-cn/configurator_troubleshooting.md | 31 - docs/zh-cn/contributing.md | 175 -- docs/zh-cn/custom_quantum_functions.md | 476 ------ docs/zh-cn/driver_installation_zadig.md | 102 -- docs/zh-cn/easy_maker.md | 37 - docs/zh-cn/faq_build.md | 73 - docs/zh-cn/faq_debug.md | 136 -- docs/zh-cn/faq_general.md | 58 - docs/zh-cn/faq_keymap.md | 157 -- docs/zh-cn/faq_misc.md | 108 -- docs/zh-cn/feature_grave_esc.md | 39 - docs/zh-cn/feature_space_cadet.md | 70 - docs/zh-cn/flashing.md | 329 ---- docs/zh-cn/flashing_bootloadhid.md | 75 - docs/zh-cn/getting_started_docker.md | 59 - docs/zh-cn/getting_started_github.md | 69 - docs/zh-cn/getting_started_introduction.md | 59 - docs/zh-cn/hand_wire.md | 255 --- docs/zh-cn/keymap.md | 211 --- docs/zh-cn/mod_tap.md | 141 -- docs/zh-cn/newbs.md | 29 - docs/zh-cn/newbs_building_firmware.md | 68 - .../newbs_building_firmware_configurator.md | 18 - docs/zh-cn/newbs_flashing.md | 124 -- docs/zh-cn/newbs_getting_started.md | 208 --- docs/zh-cn/newbs_git_best_practices.md | 23 - .../newbs_git_resolving_merge_conflicts.md | 86 - .../zh-cn/newbs_git_resynchronize_a_branch.md | 76 - .../newbs_git_using_your_master_branch.md | 79 - docs/zh-cn/newbs_learn_more_resources.md | 35 - docs/zh-cn/newbs_testing_debugging.md | 14 - docs/zh-cn/other_eclipse.md | 90 - docs/zh-cn/other_vscode.md | 120 -- docs/zh-cn/reference_configurator_support.md | 200 --- docs/zh-cn/reference_glossary.md | 198 --- docs/zh-cn/support.md | 22 - docs/zh-cn/syllabus.md | 77 - docs/zh-cn/translating.md | 60 - docs/zh-cn/zh_cn_doc_status.sh | 35 - keyboards/a_dux/keymaps/daliusd/keymap.c | 44 +- keyboards/abacus/keymaps/unicodemap/keymap.c | 2 +- keyboards/aleblazer/zodiark/config.h | 1 - keyboards/aleblazer/zodiark/info.json | 3 +- keyboards/andean_condor/info.json | 89 + .../andean_condor/keymaps/default/keymap.c | 14 + keyboards/andean_condor/readme.md | 33 + keyboards/andean_condor/rules.mk | 1 + keyboards/arabica37/rev1/config.h | 1 - keyboards/arabica37/rev1/info.json | 3 + .../atreus/keymaps/ridingqwerty/keymap.c | 2 +- keyboards/avalanche/v2/config.h | 1 - keyboards/avalanche/v2/info.json | 3 + keyboards/avalanche/v3/config.h | 1 - keyboards/avalanche/v3/info.json | 3 + keyboards/avalanche/v4/config.h | 1 - keyboards/avalanche/v4/info.json | 3 +- keyboards/basekeys/slice/rev1_rgb/config.h | 1 - keyboards/basekeys/slice/rev1_rgb/info.json | 3 +- keyboards/bastardkb/dilemma/3x5_3/config.h | 4 +- keyboards/bastardkb/dilemma/3x5_3/info.json | 3 + keyboards/bastardkb/scylla/config.h | 4 +- keyboards/bastardkb/scylla/info.json | 3 + keyboards/bastardkb/skeletyl/config.h | 4 +- keyboards/bastardkb/skeletyl/info.json | 3 + keyboards/bastardkb/tbk/config.h | 1 - keyboards/bastardkb/tbk/info.json | 3 + keyboards/bastardkb/tbkmini/config.h | 4 +- keyboards/bastardkb/tbkmini/info.json | 3 + keyboards/bioi/g60/matrix_diagram.md | 6 +- keyboards/bioi/g60ble/config.h | 13 +- .../bioi/g60ble/keymaps/chemicalwill/keymap.c | 206 +++ .../bioi/g60ble/keymaps/chemicalwill/rules.mk | 7 + keyboards/bioi/g60ble/matrix_diagram.md | 24 + keyboards/bioi/g60ble/rules.mk | 10 +- keyboards/bluebell/swoop/config.h | 2 - keyboards/bluebell/swoop/info.json | 3 +- keyboards/cablecardesigns/phoenix/info.json | 497 ++++++ .../phoenix/keymaps/default/keymap.c | 27 + .../phoenix/keymaps/via/keymap.c | 27 + .../phoenix/keymaps/via/rules.mk | 1 + .../cablecardesigns/phoenix/phoenix.c | 10 +- keyboards/cablecardesigns/phoenix/readme.md | 32 + keyboards/cablecardesigns/phoenix/rules.mk | 7 + keyboards/churrosoft/deck8/info.json | 43 + .../churrosoft/deck8/keymaps/default/keymap.c | 25 + .../churrosoft/deck8/keymaps/via/keymap.c | 24 + .../churrosoft/deck8/keymaps/via/rules.mk | 1 + keyboards/churrosoft/deck8/noleds/info.json | 5 + keyboards/churrosoft/deck8/noleds/readme.md | 27 + keyboards/churrosoft/deck8/noleds/rules.mk | 1 + keyboards/churrosoft/deck8/rgb/config.h | 74 + keyboards/churrosoft/deck8/rgb/info.json | 27 + keyboards/churrosoft/deck8/rgb/readme.md | 27 + keyboards/churrosoft/deck8/rgb/rules.mk | 1 + keyboards/contra/keymaps/bramver/README.md | 6 +- keyboards/contra/keymaps/bramver/keymap.c | 6 +- .../ibm_terminal/keymaps/priyadi/keymap.c | 6 +- keyboards/crkbd/r2g/config.h | 2 - keyboards/crkbd/r2g/info.json | 3 + keyboards/crkbd/rev1/config.h | 2 - keyboards/crkbd/rev1/info.json | 3 + keyboards/doppelganger/config.h | 1 - keyboards/doppelganger/info.json | 3 + .../durgod/k320/keymaps/kuenhlee/keymap.c | 10 +- .../dz65rgb/keymaps/catrielmuller/keymap.c | 8 +- keyboards/ebastler/e80_1800/info.json | 6 +- keyboards/eggsworks/egg58/config.h | 6 + keyboards/eggsworks/egg58/info.json | 172 ++ .../eggsworks/egg58/keymaps/default/keymap.c | 27 + .../eggsworks/egg58/keymaps/via/keymap.c | 27 + .../eggsworks/egg58/keymaps/via/rules.mk | 2 + keyboards/eggsworks/egg58/readme.md | 23 + keyboards/eggsworks/egg58/rules.mk | 1 + keyboards/elephant42/config.h | 3 +- keyboards/elephant42/info.json | 3 +- keyboards/ergoslab/rev1/config.h | 4 - keyboards/flxlb/zplit/config.h | 1 - keyboards/flxlb/zplit/info.json | 3 + .../gh60/satan/keymaps/addcninblue/rules.mk | 2 +- keyboards/giabalanai/config.h | 5 - keyboards/giabalanai/giabalanai.c | 255 --- keyboards/giabalanai/giabalanai.h | 68 - keyboards/giabalanai/info.json | 305 ---- .../giabalanai/keymaps/2firmware/keymap.c | 739 -------- .../giabalanai/keymaps/2firmware/readme.md | 12 - .../giabalanai/keymaps/2firmware/rules.mk | 4 - keyboards/giabalanai/keymaps/3araht/keymap.c | 780 --------- keyboards/giabalanai/keymaps/3araht/readme.md | 1 - keyboards/giabalanai/keymaps/3araht/rules.mk | 4 - keyboards/giabalanai/keymaps/default/keymap.c | 259 --- .../giabalanai/keymaps/default/readme.md | 1 - keyboards/giabalanai/keymaps/default/rules.mk | 1 - .../keymaps/default_giabarinaix2/config.h | 42 - .../keymaps/default_giabarinaix2/info.json | 146 -- .../keymaps/default_giabarinaix2/keymap.c | 262 --- .../keymaps/default_giabarinaix2/readme.md | 1 - .../keymaps/default_giabarinaix2/rules.mk | 3 - .../keymaps/giabarinaix2led/config.h | 42 - .../keymaps/giabarinaix2led/info.json | 146 -- .../keymaps/giabarinaix2led/keymap.c | 464 ----- .../keymaps/giabarinaix2led/readme.md | 1 - .../keymaps/giabarinaix2led/rules.mk | 3 - keyboards/giabalanai/keymaps/party/keymap.c | 818 --------- keyboards/giabalanai/keymaps/party/readme.md | 3 - .../keymaps/party/rgb_matrix_user.inc | 57 - keyboards/giabalanai/keymaps/party/rules.mk | 6 - keyboards/giabalanai/keymaps/via/keymap.c | 260 --- keyboards/giabalanai/keymaps/via/readme.md | 1 - keyboards/giabalanai/keymaps/via/rules.mk | 3 - .../keymaps/via_giabarinaix2/config.h | 27 - .../keymaps/via_giabarinaix2/info.json | 146 -- .../keymaps/via_giabarinaix2/keymap.c | 262 --- .../keymaps/via_giabarinaix2/readme.md | 1 - .../keymaps/via_giabarinaix2/rules.mk | 4 - keyboards/giabalanai/readme.md | 24 - keyboards/giabalanai/rules.mk | 9 - keyboards/halfcliff/config.h | 1 - keyboards/halfcliff/info.json | 3 + .../dactyl_manuform/dmote/62key/config.h | 1 - .../dactyl_manuform/dmote/62key/info.json | 3 + keyboards/handwired/freoduo/config.h | 1 - keyboards/handwired/freoduo/info.json | 3 + .../minorca/keymaps/ridingqwerty/keymap.c | 6 +- .../promethium/keymaps/default/keymap.c | 26 +- .../promethium/keymaps/priyadi/keymap.c | 26 +- .../handwired/scottokeebs/scotto36/info.json | 76 + .../scotto36/keymaps/default/config.h | 9 +- .../scotto36/keymaps/default/keymap.c | 45 + .../scotto36/keymaps/scotto}/config.h | 10 +- .../scotto36/keymaps/scotto/keymap.c | 281 +++ .../scotto36/keymaps/scotto/rules.mk | 4 + .../handwired/scottokeebs/scotto36/readme.md | 27 + .../handwired/scottokeebs/scotto36/rules.mk | 1 + .../handwired/scottokeebs/scotto40/info.json | 183 ++ .../scotto40/keymaps/default}/config.h | 16 +- .../scotto40/keymaps/default/keymap.c | 45 + .../scotto40/keymaps/scotto/config.h | 16 +- .../scotto40/keymaps/scotto/keymap.c | 114 ++ .../scotto40/keymaps/scotto/rules.mk | 1 + .../handwired/scottokeebs/scotto40/readme.md | 27 + .../handwired/scottokeebs/scotto40/rules.mk | 1 + .../scottokeebs/scottostarter/info.json | 94 + .../scottostarter/keymaps/default/config.h | 23 + .../scottostarter/keymaps/default/keymap.c | 52 + .../scottokeebs/scottostarter/readme.md | 27 + .../scottokeebs/scottostarter/rules.mk | 1 + keyboards/handwired/splittest/config.h | 1 - keyboards/handwired/splittest/info.json | 3 + .../handwired/t111/keymaps/oleg/keymap.c | 8 +- .../5x6_right/elite_c/config.h | 2 - .../5x6_right/elite_c/info.json | 3 +- .../tractyl_manuform/5x6_right/f303/config.h | 2 - .../tractyl_manuform/5x6_right/f303/info.json | 3 + .../tractyl_manuform/5x6_right/f411/config.h | 2 - .../tractyl_manuform/5x6_right/f411/info.json | 3 + .../5x6_right/teensy2pp/config.h | 2 - .../5x6_right/teensy2pp/info.json | 3 +- keyboards/handwired/tsubasa/config.h | 1 - keyboards/handwired/tsubasa/info.json | 3 + .../handwired/wulkan/keymaps/default/keymap.c | 4 +- keyboards/helix/rev3_4rows/config.h | 1 - keyboards/helix/rev3_4rows/info.json | 3 +- keyboards/helix/rev3_5rows/config.h | 1 - keyboards/helix/rev3_5rows/info.json | 3 +- .../hidtech/bastyl/keymaps/nstickney/keymap.c | 10 +- keyboards/jiran/rev2/config.h | 1 - keyboards/jiran/rev2/info.json | 3 + keyboards/jorne/rev1/config.h | 1 - keyboards/jorne/rev1/info.json | 3 + .../kakunpc/rabbit_capture_plan/config.h | 1 - .../kakunpc/rabbit_capture_plan/info.json | 3 +- keyboards/kakunpc/suihankey/alpha/config.h | 2 - keyboards/kakunpc/suihankey/rev1/config.h | 2 - .../kakunpc/suihankey/split/alpha/config.h | 2 - .../kakunpc/suihankey/split/rev1/config.h | 2 - keyboards/kapl/rev1/config.h | 1 - keyboards/kapl/rev1/info.json | 3 +- keyboards/keebio/bfo9000/config.h | 1 - keyboards/keebio/bfo9000/info.json | 3 + keyboards/keebio/foldkb/rev1/config.h | 1 - keyboards/keebio/foldkb/rev1/info.json | 3 + keyboards/keebio/fourier/config.h | 1 - keyboards/keebio/fourier/info.json | 3 + .../keebio/iris/keymaps/nstickney/keymap.c | 10 +- keyboards/keebio/iris/rev2/config.h | 1 - keyboards/keebio/iris/rev2/info.json | 3 + keyboards/keebio/iris/rev3/config.h | 1 - keyboards/keebio/iris/rev3/info.json | 3 + keyboards/keebio/iris/rev4/config.h | 1 - keyboards/keebio/iris/rev4/info.json | 3 + keyboards/keebio/iris/rev5/config.h | 1 - keyboards/keebio/iris/rev5/info.json | 3 + keyboards/keebio/iris/rev6/config.h | 1 - keyboards/keebio/iris/rev6/info.json | 3 +- keyboards/keebio/iris/rev7/config.h | 1 - keyboards/keebio/iris/rev7/info.json | 3 +- keyboards/keebio/kbo5000/rev1/config.h | 1 - keyboards/keebio/kbo5000/rev1/info.json | 3 + keyboards/keebio/levinson/rev1/config.h | 1 - keyboards/keebio/levinson/rev1/info.json | 3 + keyboards/keebio/levinson/rev2/config.h | 1 - keyboards/keebio/levinson/rev2/info.json | 3 + keyboards/keebio/levinson/rev3/config.h | 1 - keyboards/keebio/levinson/rev3/info.json | 3 + .../keebio/nyquist/keymaps/bramver/keymap.c | 6 +- keyboards/keebio/nyquist/rev1/config.h | 1 - keyboards/keebio/nyquist/rev1/info.json | 3 + keyboards/keebio/nyquist/rev2/config.h | 1 - keyboards/keebio/nyquist/rev2/info.json | 3 + keyboards/keebio/nyquist/rev3/config.h | 1 - keyboards/keebio/nyquist/rev3/info.json | 3 + .../quefrency/keymaps/bramver/README.md | 6 +- .../keebio/quefrency/keymaps/bramver/keymap.c | 6 +- keyboards/keebio/quefrency/rev1/config.h | 1 - keyboards/keebio/quefrency/rev1/info.json | 3 + keyboards/keebio/quefrency/rev2/config.h | 1 - keyboards/keebio/quefrency/rev2/info.json | 3 + keyboards/keebio/quefrency/rev3/config.h | 1 - keyboards/keebio/quefrency/rev3/info.json | 3 + keyboards/keebio/quefrency/rev4/config.h | 1 - keyboards/keebio/quefrency/rev4/info.json | 3 + keyboards/keebio/quefrency/rev5/config.h | 1 - keyboards/keebio/quefrency/rev5/info.json | 3 + keyboards/keebio/viterbi/rev1/config.h | 1 - keyboards/keebio/viterbi/rev1/info.json | 3 + keyboards/keebio/viterbi/rev2/config.h | 1 - keyboards/keebio/viterbi/rev2/info.json | 3 + keyboards/keycapsss/kimiko/rev1/config.h | 1 - keyboards/keycapsss/kimiko/rev1/info.json | 3 + .../q1/iso/keymaps/victorsavu3/keymap.c | 4 +- keyboards/kibou/harbour/info.json | 102 ++ .../kibou/harbour/keymaps/default/keymap.c | 13 + keyboards/kibou/harbour/keymaps/via/keymap.c | 13 + keyboards/kibou/harbour/keymaps/via/rules.mk | 1 + keyboards/kibou/harbour/readme.md | 23 + keyboards/kibou/harbour/rules.mk | 1 + keyboards/ktec/ergodone/keymaps/vega/keymap.c | 118 +- keyboards/lily58/glow_enc/config.h | 1 - keyboards/lily58/glow_enc/info.json | 3 +- keyboards/lily58/light/config.h | 1 - keyboards/lily58/light/info.json | 3 +- keyboards/manta60/config.h | 1 - keyboards/manta60/info.json | 3 + .../maple_computing/lets_split_eh/eh/config.h | 1 - .../lets_split_eh/eh/info.json | 3 + keyboards/marksard/rhymestone/rev1/config.h | 1 - keyboards/marksard/rhymestone/rev1/info.json | 3 +- .../alt/keymaps/charlesrocket/keymap.c | 8 +- keyboards/mechlovin/zed65/info.json | 9 +- .../mechlovin/zed65/rev1/config.h | 19 +- .../mechlovin/zed65/rev1/halconf.h | 8 +- keyboards/mechlovin/zed65/rev1/info.json | 354 ++++ .../zed65/rev1/keymaps/default/keymap.c | 28 + .../mechlovin/zed65/rev1/keymaps/via/keymap.c | 29 + .../mechlovin/zed65/rev1/keymaps/via/rules.mk | 2 + .../mechlovin/zed65/rev1/mcuconf.h | 8 +- keyboards/mechlovin/zed65/rev1/readme.md | 28 + keyboards/mechlovin/zed65/rev1/rules.mk | 1 + keyboards/mechlovin/zed65/rules.mk | 12 - keyboards/mechwild/mokulua/mirrored/config.h | 1 - keyboards/mechwild/mokulua/mirrored/info.json | 3 + keyboards/mechwild/mokulua/standard/config.h | 1 - keyboards/mechwild/mokulua/standard/info.json | 3 + keyboards/merge/um70/config.h | 3 +- keyboards/merge/um70/info.json | 3 +- keyboards/merge/um80/config.h | 3 +- keyboards/merge/um80/info.json | 3 +- keyboards/meson/config.h | 1 - keyboards/meson/info.json | 3 + keyboards/mlego/m60_split/rev1/config.h | 2 - keyboards/mlego/m60_split/rev1/info.json | 3 +- keyboards/mlego/m60_split/rev2/config.h | 2 - keyboards/mlego/m60_split/rev2/info.json | 3 + keyboards/mlego/m65/keymaps/uk/keymap.c | 12 +- keyboards/momoka_ergo/config.h | 1 - keyboards/momoka_ergo/info.json | 3 + keyboards/nacly/splitreus62/config.h | 1 - keyboards/nacly/splitreus62/info.json | 3 + keyboards/nullbitsco/snap/config.h | 1 - keyboards/nullbitsco/snap/info.json | 3 + keyboards/obosob/arch_36/config.h | 1 - keyboards/obosob/arch_36/info.json | 3 + keyboards/ogre/ergo_split/config.h | 1 - keyboards/ogre/ergo_split/info.json | 3 + keyboards/omkbd/ergodash/mini/config.h | 1 - keyboards/omkbd/ergodash/mini/info.json | 3 + keyboards/omkbd/ergodash/rev1/config.h | 1 - keyboards/omkbd/ergodash/rev1/info.json | 3 + keyboards/omkbd/runner3680/3x6/config.h | 1 - keyboards/omkbd/runner3680/3x6/info.json | 3 +- keyboards/omkbd/runner3680/3x7/config.h | 1 - keyboards/omkbd/runner3680/3x7/info.json | 3 +- keyboards/omkbd/runner3680/3x8/config.h | 1 - keyboards/omkbd/runner3680/3x8/info.json | 3 +- keyboards/omkbd/runner3680/4x6/config.h | 1 - keyboards/omkbd/runner3680/4x6/info.json | 3 +- keyboards/omkbd/runner3680/4x7/config.h | 1 - keyboards/omkbd/runner3680/4x7/info.json | 3 +- keyboards/omkbd/runner3680/4x8/config.h | 1 - keyboards/omkbd/runner3680/4x8/info.json | 3 +- keyboards/omkbd/runner3680/5x6/config.h | 1 - keyboards/omkbd/runner3680/5x6/info.json | 3 +- keyboards/omkbd/runner3680/5x6_5x8/config.h | 1 - keyboards/omkbd/runner3680/5x6_5x8/info.json | 3 +- keyboards/omkbd/runner3680/5x7/config.h | 1 - keyboards/omkbd/runner3680/5x7/info.json | 3 +- keyboards/omkbd/runner3680/5x8/config.h | 1 - keyboards/omkbd/runner3680/5x8/info.json | 3 +- keyboards/peej/tripel/left/info.json | 2 +- keyboards/peej/tripel/middle/info.json | 2 +- keyboards/peej/tripel/right/info.json | 2 +- keyboards/planck/keymaps/mwpeterson/keymap.c | 2 +- .../keymaps/zach/zach_common_functions.c | 60 +- .../keymaps/zach/zach_common_functions.c | 60 +- keyboards/rate/pistachio/rev1/config.h | 1 - keyboards/rate/pistachio/rev1/info.json | 3 + keyboards/rate/pistachio/rev2/config.h | 1 - keyboards/rate/pistachio/rev2/info.json | 3 +- .../reviung41/keymaps/ciutadellla/keymap.c | 2 +- keyboards/rgbkb/mun/config.h | 1 - keyboards/rgbkb/mun/rev1/info.json | 3 + keyboards/rgbkb/sol3/config.h | 1 - keyboards/rgbkb/sol3/rev1/info.json | 3 + keyboards/rgbkb/zygomorph/rev1/config.h | 1 - keyboards/rgbkb/zygomorph/rev1/info.json | 3 + keyboards/rura66/rev1/config.h | 1 - keyboards/rura66/rev1/info.json | 3 +- keyboards/salicylic_acid3/7skb/rev1/config.h | 1 - keyboards/salicylic_acid3/7skb/rev1/info.json | 3 + keyboards/salicylic_acid3/7splus/config.h | 1 - keyboards/salicylic_acid3/7splus/info.json | 3 + keyboards/salicylic_acid3/ergoarrows/config.h | 1 - .../salicylic_acid3/ergoarrows/info.json | 3 + .../salicylic_acid3/jisplit89/rev1/config.h | 1 - .../salicylic_acid3/jisplit89/rev1/info.json | 3 + keyboards/salicylic_acid3/nknl7en/config.h | 1 - keyboards/salicylic_acid3/nknl7en/info.json | 3 + keyboards/salicylic_acid3/nknl7jp/config.h | 1 - keyboards/salicylic_acid3/nknl7jp/info.json | 3 + .../signum/3_0/keymaps/default/generate_km.py | 2 +- .../signum/3_0/keymaps/default/layout.py | 2 +- keyboards/silverbullet44/config.h | 1 - keyboards/silverbullet44/info.json | 3 +- keyboards/soda/mango/info.json | 49 + keyboards/soda/mango/keymaps/default/keymap.c | 32 + keyboards/soda/mango/keymaps/via/keymap.c | 33 + keyboards/soda/mango/keymaps/via/rules.mk | 1 + keyboards/soda/mango/readme.md | 23 + keyboards/soda/mango/rules.mk | 1 + keyboards/sofle/keyhive/config.h | 1 - keyboards/sofle/keyhive/info.json | 3 +- keyboards/splitkb/aurora/lily58/rev1/config.h | 2 +- keyboards/splitkb/aurora/sweep/rev1/config.h | 2 +- keyboards/splitkb/kyria/keymaps/lw/keymap.c | 6 +- keyboards/splitkb/kyria/rev1/config.h | 2 - keyboards/splitkb/kyria/rev1/info.json | 3 + keyboards/splitkb/kyria/rev2/config.h | 2 - keyboards/splitkb/kyria/rev2/info.json | 3 + keyboards/splitkb/kyria/rev3/config.h | 2 +- keyboards/takashicompany/compacx/config.h | 1 - keyboards/takashicompany/compacx/info.json | 3 + keyboards/takashicompany/heavy_left/config.h | 1 - keyboards/takashicompany/heavy_left/info.json | 3 + keyboards/takashiski/hecomi/alpha/config.h | 1 - keyboards/takashiski/hecomi/alpha/info.json | 3 + .../minivan/keymaps/josjoha/keymap.c | 2 +- .../minivan/keymaps/josjoha/unicode_macros.c | 2 +- keyboards/tkw/grandiceps/config.h | 1 - keyboards/tkw/grandiceps/info.json | 3 +- keyboards/uzu42/rev1/config.h | 1 - keyboards/uzu42/rev1/info.json | 3 +- keyboards/viktus/sp_mini/config.h | 1 - keyboards/viktus/sp_mini/info.json | 3 + keyboards/vitamins_included/rev2/config.h | 1 - keyboards/vitamins_included/rev2/info.json | 3 + keyboards/xelus/rs108/info.json | 72 +- keyboards/xiudi/xd75/keymaps/bramver/keymap.c | 2 +- .../xiudi/xd75/keymaps/bramver/readme.md | 2 +- keyboards/xiudi/xd75/keymaps/minna/keymap.c | 2 +- keyboards/yoichiro/lunakey_mini/config.h | 1 - keyboards/yoichiro/lunakey_mini/info.json | 3 + .../yushakobo/navpad/10_helix_r/config.h | 1 - .../yushakobo/navpad/10_helix_r/info.json | 3 +- keyboards/zvecr/split_blackpill/config.h | 1 - keyboards/zvecr/split_blackpill/info.json | 3 + keyboards/zvecr/zv48/config.h | 1 - keyboards/zvecr/zv48/info.json | 3 +- layouts/community/60_iso/bifbofii/keymap.c | 6 +- .../65_ansi_blocker/spidey3/keymap.c | 4 +- layouts/community/75_ansi/spidey3/keymap.c | 4 +- .../community/ortho_4x12/bifbofii/keymap.c | 6 +- layouts/default/readme.md | 42 +- layouts/default/split_3x5_2/layout.json | 2 +- platforms/chibios/wait.c | 2 +- quantum/action.c | 1215 ------------- quantum/action.h | 154 -- quantum/action_code.h | 264 --- quantum/action_layer.c | 363 ---- quantum/action_layer.h | 169 -- quantum/action_tapping.c | 547 ------ quantum/action_tapping.h | 65 - quantum/action_util.c | 502 ------ quantum/action_util.h | 107 -- quantum/audio/audio.c | 566 ------ quantum/audio/audio.h | 282 --- quantum/audio/luts.c | 27 - quantum/audio/luts.h | 27 - quantum/audio/muse.c | 56 - quantum/audio/muse.h | 6 - quantum/audio/musical_notes.h | 234 --- quantum/audio/song_list.h | 281 --- quantum/audio/voices.c | 362 ---- quantum/audio/voices.h | 66 - quantum/backlight/backlight.c | 277 --- quantum/backlight/backlight.h | 91 - quantum/backlight/backlight_avr.c | 473 ----- quantum/backlight/backlight_chibios.c | 173 -- quantum/backlight/backlight_driver_common.c | 53 - quantum/backlight/backlight_driver_common.h | 7 - quantum/backlight/backlight_software.c | 54 - quantum/backlight/backlight_timer.c | 179 -- quantum/basic_profiling.h | 69 - quantum/bitwise.c | 126 -- quantum/bitwise.h | 40 - quantum/bootmagic/bootmagic.h | 22 - quantum/bootmagic/bootmagic_lite.c | 64 - quantum/bootmagic/bootmagic_lite.h | 25 - quantum/bootmagic/magic.c | 54 - quantum/bootmagic/magic.h | 18 - quantum/caps_word.c | 86 - quantum/caps_word.h | 48 - quantum/color.c | 121 -- quantum/color.h | 150 -- quantum/command.c | 748 -------- quantum/command.h | 162 -- quantum/crc.c | 75 - quantum/crc.h | 45 - quantum/debounce.h | 17 - quantum/debounce/asym_eager_defer_pk.c | 177 -- quantum/debounce/none.c | 32 - quantum/debounce/sym_defer_g.c | 56 - quantum/debounce/sym_defer_pk.c | 145 -- quantum/debounce/sym_defer_pr.c | 78 - quantum/debounce/sym_eager_pk.c | 150 -- quantum/debounce/sym_eager_pr.c | 142 -- .../tests/asym_eager_defer_pk_tests.cpp | 394 ----- .../debounce/tests/debounce_test_common.cpp | 211 --- quantum/debounce/tests/debounce_test_common.h | 81 - quantum/debounce/tests/rules.mk | 49 - quantum/debounce/tests/sym_defer_g_tests.cpp | 238 --- quantum/debounce/tests/sym_defer_pk_tests.cpp | 240 --- quantum/debounce/tests/sym_defer_pr_tests.cpp | 238 --- quantum/debounce/tests/sym_eager_pk_tests.cpp | 253 --- quantum/debounce/tests/sym_eager_pr_tests.cpp | 299 ---- quantum/debounce/tests/testlist.mk | 7 - quantum/deferred_exec.c | 171 -- quantum/deferred_exec.h | 121 -- quantum/digitizer.c | 76 - quantum/digitizer.h | 84 - quantum/dip_switch.c | 128 -- quantum/dip_switch.h | 30 - quantum/dynamic_keymap.c | 346 ---- quantum/dynamic_keymap.h | 70 - quantum/dynamic_macro.h | 264 --- quantum/eeconfig.c | 340 ---- quantum/eeconfig.h | 193 --- quantum/encoder.c | 292 ---- quantum/encoder.h | 64 - quantum/encoder/tests/config_mock.h | 22 - .../tests/config_mock_split_left_eq_right.h | 26 - .../tests/config_mock_split_left_gt_right.h | 26 - .../tests/config_mock_split_left_lt_right.h | 26 - .../encoder/tests/config_mock_split_no_left.h | 26 - .../tests/config_mock_split_no_right.h | 26 - .../encoder/tests/config_mock_split_role.h | 26 - quantum/encoder/tests/encoder_tests.cpp | 144 -- .../encoder_tests_split_left_eq_right.cpp | 135 -- .../encoder_tests_split_left_gt_right.cpp | 139 -- .../encoder_tests_split_left_lt_right.cpp | 139 -- .../tests/encoder_tests_split_no_left.cpp | 125 -- .../tests/encoder_tests_split_no_right.cpp | 118 -- .../tests/encoder_tests_split_role.cpp | 122 -- quantum/encoder/tests/mock.c | 40 - quantum/encoder/tests/mock.h | 34 - quantum/encoder/tests/mock_split.c | 42 - quantum/encoder/tests/mock_split.h | 38 - quantum/encoder/tests/rules.mk | 68 - quantum/encoder/tests/testlist.mk | 8 - quantum/haptic.c | 351 ---- quantum/haptic.h | 106 -- quantum/joystick.c | 135 -- quantum/joystick.h | 132 -- quantum/keyboard.c | 700 -------- quantum/keyboard.h | 131 -- quantum/keycode.h | 43 - quantum/keycode_config.c | 167 -- quantum/keycode_config.h | 52 - quantum/keycodes.h | 1422 --------------- quantum/keymap_common.c | 203 --- quantum/keymap_common.h | 10 - quantum/keymap_extras/keymap_belgian.h | 114 -- quantum/keymap_extras/keymap_bepo.h | 175 -- .../keymap_extras/keymap_brazilian_abnt2.h | 115 -- .../keymap_canadian_multilingual.h | 174 -- quantum/keymap_extras/keymap_colemak.h | 99 -- quantum/keymap_extras/keymap_croatian.h | 121 -- quantum/keymap_extras/keymap_czech.h | 129 -- quantum/keymap_extras/keymap_danish.h | 110 -- quantum/keymap_extras/keymap_dvorak.h | 99 -- quantum/keymap_extras/keymap_dvorak_fr.h | 101 -- .../keymap_extras/keymap_dvorak_programmer.h | 99 -- quantum/keymap_extras/keymap_estonian.h | 112 -- quantum/keymap_extras/keymap_finnish.h | 110 -- quantum/keymap_extras/keymap_french.h | 112 -- quantum/keymap_extras/keymap_french_afnor.h | 167 -- quantum/keymap_extras/keymap_french_mac_iso.h | 186 -- quantum/keymap_extras/keymap_german.h | 110 -- quantum/keymap_extras/keymap_german_mac_iso.h | 181 -- quantum/keymap_extras/keymap_greek.h | 118 -- quantum/keymap_extras/keymap_hebrew.h | 107 -- quantum/keymap_extras/keymap_hungarian.h | 129 -- quantum/keymap_extras/keymap_icelandic.h | 109 -- quantum/keymap_extras/keymap_irish.h | 109 -- quantum/keymap_extras/keymap_italian.h | 108 -- .../keymap_extras/keymap_italian_mac_ansi.h | 188 -- .../keymap_extras/keymap_italian_mac_iso.h | 189 -- quantum/keymap_extras/keymap_japanese.h | 106 -- quantum/keymap_extras/keymap_korean.h | 101 -- quantum/keymap_extras/keymap_latvian.h | 127 -- .../keymap_extras/keymap_lithuanian_azerty.h | 114 -- .../keymap_extras/keymap_lithuanian_qwerty.h | 109 -- quantum/keymap_extras/keymap_neo2.h | 81 - quantum/keymap_extras/keymap_nordic.h | 68 - quantum/keymap_extras/keymap_norman.h | 99 -- quantum/keymap_extras/keymap_norwegian.h | 109 -- quantum/keymap_extras/keymap_plover.h | 54 - quantum/keymap_extras/keymap_plover_dvorak.h | 54 - quantum/keymap_extras/keymap_polish.h | 109 -- quantum/keymap_extras/keymap_portuguese.h | 109 -- .../keymap_extras/keymap_portuguese_mac_iso.h | 172 -- quantum/keymap_extras/keymap_romanian.h | 128 -- quantum/keymap_extras/keymap_russian.h | 93 - quantum/keymap_extras/keymap_serbian.h | 97 -- quantum/keymap_extras/keymap_serbian_latin.h | 122 -- quantum/keymap_extras/keymap_slovak.h | 131 -- quantum/keymap_extras/keymap_slovenian.h | 121 -- quantum/keymap_extras/keymap_spanish.h | 110 -- quantum/keymap_extras/keymap_spanish_dvorak.h | 110 -- quantum/keymap_extras/keymap_steno.h | 119 -- quantum/keymap_extras/keymap_swedish.h | 110 -- .../keymap_extras/keymap_swedish_mac_ansi.h | 177 -- .../keymap_extras/keymap_swedish_mac_iso.h | 177 -- .../keymap_swedish_pro_mac_ansi.h | 177 -- .../keymap_swedish_pro_mac_iso.h | 177 -- quantum/keymap_extras/keymap_swiss_de.h | 115 -- quantum/keymap_extras/keymap_swiss_fr.h | 115 -- quantum/keymap_extras/keymap_turkish_f.h | 137 -- quantum/keymap_extras/keymap_turkish_q.h | 114 -- quantum/keymap_extras/keymap_uk.h | 108 -- quantum/keymap_extras/keymap_ukrainian.h | 94 - quantum/keymap_extras/keymap_us.h | 72 - quantum/keymap_extras/keymap_us_extended.h | 164 -- .../keymap_extras/keymap_us_international.h | 144 -- .../keymap_us_international_linux.h | 161 -- quantum/keymap_extras/keymap_workman.h | 99 -- quantum/keymap_extras/keymap_workman_zxcvm.h | 99 -- quantum/keymap_extras/sendstring_belgian.h | 120 -- quantum/keymap_extras/sendstring_bepo.h | 120 -- .../sendstring_brazilian_abnt2.h | 100 -- .../sendstring_canadian_multilingual.h | 120 -- quantum/keymap_extras/sendstring_colemak.h | 59 - quantum/keymap_extras/sendstring_croatian.h | 120 -- quantum/keymap_extras/sendstring_czech.h | 120 -- quantum/keymap_extras/sendstring_danish.h | 120 -- quantum/keymap_extras/sendstring_dvorak.h | 59 - quantum/keymap_extras/sendstring_dvorak_fr.h | 99 -- .../sendstring_dvorak_programmer.h | 80 - quantum/keymap_extras/sendstring_estonian.h | 120 -- quantum/keymap_extras/sendstring_finnish.h | 120 -- quantum/keymap_extras/sendstring_french.h | 120 -- .../keymap_extras/sendstring_french_afnor.h | 120 -- .../keymap_extras/sendstring_french_mac_iso.h | 120 -- quantum/keymap_extras/sendstring_german.h | 120 -- .../keymap_extras/sendstring_german_mac_iso.h | 120 -- quantum/keymap_extras/sendstring_hungarian.h | 120 -- quantum/keymap_extras/sendstring_icelandic.h | 120 -- quantum/keymap_extras/sendstring_italian.h | 100 -- .../sendstring_italian_mac_ansi.h | 100 -- .../sendstring_italian_mac_iso.h | 100 -- quantum/keymap_extras/sendstring_japanese.h | 80 - quantum/keymap_extras/sendstring_latvian.h | 80 - .../sendstring_lithuanian_azerty.h | 100 -- .../sendstring_lithuanian_qwerty.h | 80 - quantum/keymap_extras/sendstring_norman.h | 59 - quantum/keymap_extras/sendstring_norwegian.h | 120 -- quantum/keymap_extras/sendstring_portuguese.h | 120 -- .../sendstring_portuguese_mac_iso.h | 120 -- quantum/keymap_extras/sendstring_romanian.h | 100 -- .../keymap_extras/sendstring_serbian_latin.h | 120 -- quantum/keymap_extras/sendstring_slovak.h | 120 -- quantum/keymap_extras/sendstring_slovenian.h | 120 -- quantum/keymap_extras/sendstring_spanish.h | 120 -- .../keymap_extras/sendstring_spanish_dvorak.h | 120 -- quantum/keymap_extras/sendstring_swedish.h | 120 -- quantum/keymap_extras/sendstring_swiss_de.h | 120 -- quantum/keymap_extras/sendstring_swiss_fr.h | 120 -- quantum/keymap_extras/sendstring_turkish_f.h | 120 -- quantum/keymap_extras/sendstring_turkish_q.h | 120 -- quantum/keymap_extras/sendstring_uk.h | 80 - .../sendstring_us_international.h | 100 -- quantum/keymap_extras/sendstring_workman.h | 59 - .../keymap_extras/sendstring_workman_zxcvm.h | 59 - quantum/keymap_introspection.c | 93 - quantum/keymap_introspection.h | 57 - quantum/leader.c | 101 -- quantum/leader.h | 119 -- quantum/led.c | 192 --- quantum/led.h | 71 - .../led_matrix/animations/alpha_mods_anim.h | 24 - quantum/led_matrix/animations/band_anim.h | 15 - .../animations/band_pinwheel_anim.h | 14 - .../led_matrix/animations/band_spiral_anim.h | 14 - .../led_matrix/animations/breathing_anim.h | 19 - .../animations/cycle_left_right_anim.h | 14 - .../led_matrix/animations/cycle_out_in_anim.h | 14 - .../animations/cycle_up_down_anim.h | 14 - .../led_matrix/animations/dual_beacon_anim.h | 14 - .../animations/led_matrix_effects.inc | 18 - .../animations/runners/effect_runner_dx_dy.h | 16 - .../runners/effect_runner_dx_dy_dist.h | 17 - .../animations/runners/effect_runner_i.h | 14 - .../runners/effect_runner_reactive.h | 28 - .../runners/effect_runner_reactive_splash.h | 26 - .../runners/effect_runner_sin_cos_i.h | 16 - .../animations/runners/led_matrix_runners.inc | 6 - quantum/led_matrix/animations/solid_anim.h | 15 - .../animations/solid_reactive_cross.h | 39 - .../animations/solid_reactive_nexus.h | 36 - .../animations/solid_reactive_simple_anim.h | 16 - .../animations/solid_reactive_wide.h | 34 - .../led_matrix/animations/solid_splash_anim.h | 34 - .../animations/wave_left_right_anim.h | 14 - .../led_matrix/animations/wave_up_down_anim.h | 14 - quantum/led_matrix/led_matrix.c | 640 ------- quantum/led_matrix/led_matrix.h | 201 --- quantum/led_matrix/led_matrix_drivers.c | 247 --- quantum/led_matrix/led_matrix_types.h | 98 -- quantum/led_tables.c | 43 - quantum/logging/debug.c | 25 - quantum/logging/debug.h | 169 -- quantum/logging/print.c | 33 - quantum/logging/print.h | 151 -- quantum/logging/print.mk | 12 - quantum/logging/sendchar.c | 22 - quantum/main.c | 76 - quantum/matrix.c | 348 ---- quantum/matrix.h | 86 - quantum/matrix_common.c | 183 -- quantum/midi/Config/LUFAConfig.h | 91 - quantum/midi/bytequeue/COPYING | 674 -------- quantum/midi/bytequeue/bytequeue.c | 64 - quantum/midi/bytequeue/bytequeue.h | 55 - quantum/midi/bytequeue/interrupt_setting.c | 47 - quantum/midi/bytequeue/interrupt_setting.h | 35 - quantum/midi/midi.c | 244 --- quantum/midi/midi.h | 487 ------ quantum/midi/midi_device.c | 277 --- quantum/midi/midi_device.h | 148 -- quantum/midi/midi_function_types.h | 47 - quantum/midi/qmk_midi.c | 135 -- quantum/midi/qmk_midi.h | 10 - quantum/midi/sysex_tools.c | 97 -- quantum/midi/sysex_tools.h | 92 - quantum/modifiers.h | 54 - quantum/mousekey.c | 653 ------- quantum/mousekey.h | 198 --- quantum/os_detection.c | 136 -- quantum/os_detection.h | 42 - quantum/os_detection/tests/os_detection.cpp | 164 -- quantum/os_detection/tests/rules.mk | 5 - quantum/os_detection/tests/testlist.mk | 1 - quantum/painter/lvgl/qp_lvgl.c | 150 -- quantum/painter/lvgl/qp_lvgl.h | 25 - quantum/painter/lvgl/rules.mk | 24 - quantum/painter/qff.c | 137 -- quantum/painter/qff.h | 88 - quantum/painter/qgf.c | 294 ---- quantum/painter/qgf.h | 136 -- quantum/painter/qp.c | 228 --- quantum/painter/qp.h | 512 ------ quantum/painter/qp_comms.c | 72 - quantum/painter/qp_comms.h | 25 - quantum/painter/qp_draw.h | 95 - quantum/painter/qp_draw_circle.c | 172 -- quantum/painter/qp_draw_codec.c | 178 -- quantum/painter/qp_draw_core.c | 294 ---- quantum/painter/qp_draw_ellipse.c | 116 -- quantum/painter/qp_draw_image.c | 420 ----- quantum/painter/qp_draw_text.c | 463 ----- quantum/painter/qp_internal.c | 103 -- quantum/painter/qp_internal.h | 33 - quantum/painter/qp_internal_driver.h | 89 - quantum/painter/qp_internal_formats.h | 51 - quantum/painter/qp_stream.c | 166 -- quantum/painter/qp_stream.h | 85 - quantum/painter/rules.mk | 161 -- quantum/pointing_device/pointing_device.c | 497 ------ quantum/pointing_device/pointing_device.h | 131 -- .../pointing_device_auto_mouse.c | 432 ----- .../pointing_device_auto_mouse.h | 93 - .../pointing_device/pointing_device_drivers.c | 401 ----- .../pointing_device_gestures.c | 133 -- .../pointing_device_gestures.h | 58 - quantum/pointing_device_internal.h | 14 - .../autocorrect_data_default.h | 85 - quantum/process_keycode/process_audio.c | 66 - quantum/process_keycode/process_audio.h | 11 - quantum/process_keycode/process_auto_shift.c | 490 ------ quantum/process_keycode/process_auto_shift.h | 51 - quantum/process_keycode/process_autocorrect.c | 19 +- quantum/process_keycode/process_autocorrect.h | 1 + quantum/process_keycode/process_backlight.c | 76 - quantum/process_keycode/process_backlight.h | 21 - quantum/process_keycode/process_caps_word.c | 260 --- quantum/process_keycode/process_caps_word.h | 37 - quantum/process_keycode/process_clicky.c | 117 -- quantum/process_keycode/process_clicky.h | 14 - quantum/process_keycode/process_combo.c | 646 ------- quantum/process_keycode/process_combo.h | 81 - .../process_keycode/process_dynamic_macro.c | 117 +- .../process_keycode/process_dynamic_macro.h | 1 + .../process_dynamic_tapping_term.c | 52 - .../process_dynamic_tapping_term.h | 26 - quantum/process_keycode/process_grave_esc.c | 71 - quantum/process_keycode/process_grave_esc.h | 20 - quantum/process_keycode/process_haptic.c | 147 -- quantum/process_keycode/process_haptic.h | 21 - quantum/process_keycode/process_joystick.c | 31 - quantum/process_keycode/process_joystick.h | 22 - quantum/process_keycode/process_key_lock.c | 139 -- .../process_keycode/process_key_override.c | 520 ------ .../process_keycode/process_key_override.h | 153 -- quantum/process_keycode/process_leader.c | 48 - quantum/process_keycode/process_leader.h | 21 - quantum/process_keycode/process_magic.c | 194 --- quantum/process_keycode/process_midi.c | 276 --- quantum/process_keycode/process_midi.h | 54 - quantum/process_keycode/process_music.c | 326 ---- quantum/process_keycode/process_music.h | 60 - .../process_programmable_button.c | 31 - .../process_programmable_button.h | 23 - quantum/process_keycode/process_repeat_key.c | 109 -- quantum/process_keycode/process_repeat_key.h | 62 - quantum/process_keycode/process_rgb.c | 218 --- quantum/process_keycode/process_rgb.h | 20 - quantum/process_keycode/process_secure.c | 45 - quantum/process_keycode/process_secure.h | 15 - quantum/process_keycode/process_sequencer.c | 62 - quantum/process_keycode/process_sequencer.h | 21 - quantum/process_keycode/process_space_cadet.c | 161 -- quantum/process_keycode/process_space_cadet.h | 21 - quantum/process_keycode/process_steno.c | 249 --- quantum/process_keycode/process_steno.h | 39 - quantum/process_keycode/process_tap_dance.c | 179 -- quantum/process_keycode/process_tap_dance.h | 100 -- quantum/process_keycode/process_tri_layer.c | 30 - quantum/process_keycode/process_tri_layer.h | 16 - quantum/process_keycode/process_ucis.c | 124 -- quantum/process_keycode/process_ucis.h | 65 - quantum/process_keycode/process_unicode.c | 28 - quantum/process_keycode/process_unicode.h | 24 - .../process_keycode/process_unicode_common.c | 70 - .../process_keycode/process_unicode_common.h | 24 - quantum/process_keycode/process_unicodemap.c | 55 - quantum/process_keycode/process_unicodemap.h | 28 - quantum/programmable_button.c | 62 - quantum/programmable_button.h | 91 - quantum/quantum.c | 604 ------- quantum/quantum.h | 291 ---- quantum/quantum_keycodes.h | 4 +- quantum/quantum_keycodes_legacy.h | 3 + quantum/raw_hid.h | 5 - quantum/repeat_key.c | 282 --- quantum/repeat_key.h | 80 - .../rgb_matrix/animations/alpha_mods_anim.h | 26 - .../rgb_matrix/animations/breathing_anim.h | 20 - .../animations/colorband_pinwheel_sat_anim.h | 15 - .../animations/colorband_pinwheel_val_anim.h | 15 - .../animations/colorband_sat_anim.h | 16 - .../animations/colorband_spiral_sat_anim.h | 15 - .../animations/colorband_spiral_val_anim.h | 15 - .../animations/colorband_val_anim.h | 16 - .../rgb_matrix/animations/cycle_all_anim.h | 15 - .../animations/cycle_left_right_anim.h | 15 - .../rgb_matrix/animations/cycle_out_in_anim.h | 15 - .../animations/cycle_out_in_dual_anim.h | 17 - .../animations/cycle_pinwheel_anim.h | 15 - .../rgb_matrix/animations/cycle_spiral_anim.h | 15 - .../animations/cycle_up_down_anim.h | 15 - .../rgb_matrix/animations/digital_rain_anim.h | 83 - .../rgb_matrix/animations/dual_beacon_anim.h | 15 - .../animations/gradient_left_right_anim.h | 22 - .../animations/gradient_up_down_anim.h | 22 - .../animations/hue_breathing_anim.h | 22 - .../rgb_matrix/animations/hue_pendulum_anim.h | 19 - quantum/rgb_matrix/animations/hue_wave_anim.h | 19 - .../animations/jellybean_raindrops_anim.h | 29 - .../rgb_matrix/animations/pixel_flow_anim.h | 51 - .../animations/pixel_fractal_anim.h | 58 - .../rgb_matrix/animations/pixel_rain_anim.h | 37 - .../animations/rainbow_beacon_anim.h | 15 - .../animations/rainbow_moving_chevron_anim.h | 15 - .../animations/rainbow_pinwheels_anim.h | 15 - .../rgb_matrix/animations/raindrops_anim.h | 38 - .../animations/rgb_matrix_effects.inc | 40 - .../animations/runners/effect_runner_dx_dy.h | 17 - .../runners/effect_runner_dx_dy_dist.h | 18 - .../animations/runners/effect_runner_i.h | 15 - .../runners/effect_runner_reactive.h | 29 - .../runners/effect_runner_reactive_splash.h | 29 - .../runners/effect_runner_sin_cos_i.h | 17 - .../animations/runners/rgb_matrix_runners.inc | 6 - .../rgb_matrix/animations/solid_color_anim.h | 15 - .../animations/solid_reactive_anim.h | 20 - .../animations/solid_reactive_cross.h | 43 - .../animations/solid_reactive_nexus.h | 42 - .../animations/solid_reactive_simple_anim.h | 20 - .../animations/solid_reactive_wide.h | 38 - .../rgb_matrix/animations/solid_splash_anim.h | 35 - quantum/rgb_matrix/animations/splash_anim.h | 36 - .../animations/typing_heatmap_anim.h | 100 -- quantum/rgb_matrix/rgb_matrix.c | 744 -------- quantum/rgb_matrix/rgb_matrix.h | 270 --- quantum/rgb_matrix/rgb_matrix_drivers.c | 471 ----- quantum/rgb_matrix/rgb_matrix_types.h | 100 -- quantum/rgblight/rgblight.c | 1521 ----------------- quantum/rgblight/rgblight.h | 448 ----- quantum/rgblight/rgblight_breathe_table.h | 141 -- quantum/rgblight/rgblight_modes.h | 75 - quantum/rgblight/rgblight_post_config.h | 5 - quantum/ring_buffer.h | 48 - quantum/secure.c | 103 -- quantum/secure.h | 86 - quantum/send_string/send_string.c | 328 ---- quantum/send_string/send_string.h | 154 -- quantum/send_string/send_string_keycodes.h | 445 ----- quantum/sequencer/sequencer.c | 303 ---- quantum/sequencer/sequencer.h | 132 -- quantum/sequencer/tests/midi_mock.c | 32 - quantum/sequencer/tests/midi_mock.h | 26 - quantum/sequencer/tests/rules.mk | 11 - quantum/sequencer/tests/sequencer_tests.cpp | 592 ------- quantum/sequencer/tests/testlist.mk | 1 - quantum/split_common/eeprom-lefthand.eep | 2 - quantum/split_common/eeprom-righthand.eep | 2 - quantum/split_common/post_config.h | 10 - quantum/split_common/split_util.c | 263 --- quantum/split_common/split_util.h | 20 - quantum/split_common/transaction_id_define.h | 124 -- quantum/split_common/transactions.c | 1012 ----------- quantum/split_common/transactions.h | 53 - quantum/split_common/transport.c | 130 -- quantum/split_common/transport.h | 235 --- quantum/sync_timer.c | 60 - quantum/sync_timer.h | 54 - quantum/tri_layer.c | 39 - quantum/tri_layer.h | 59 - quantum/unicode/unicode.c | 386 ----- quantum/unicode/unicode.h | 168 -- quantum/unicode/utf8.c | 46 - quantum/util.h | 48 - quantum/variable_trace.c | 123 -- quantum/variable_trace.h | 47 - quantum/velocikey.c | 40 - quantum/velocikey.h | 10 - quantum/via.c | 760 -------- quantum/via.h | 190 -- quantum/virtser.h | 9 - quantum/wear_leveling/tests/backing_mocks.cpp | 154 -- quantum/wear_leveling/tests/backing_mocks.hpp | 210 --- quantum/wear_leveling/tests/rules.mk | 66 - quantum/wear_leveling/tests/testlist.mk | 6 - .../tests/wear_leveling_2byte.cpp | 228 --- .../wear_leveling_2byte_optimized_writes.cpp | 295 ---- .../tests/wear_leveling_4byte.cpp | 193 --- .../tests/wear_leveling_8byte.cpp | 178 -- .../tests/wear_leveling_general.cpp | 204 --- quantum/wear_leveling/wear_leveling.c | 768 --------- quantum/wear_leveling/wear_leveling.h | 54 - .../wear_leveling/wear_leveling_internal.h | 151 -- quantum/wpm.c | 178 -- quantum/wpm.h | 45 - readme.md | 40 - .../test_caps_word_unicodemap.cpp | 4 +- users/konstantin/unicode.h | 2 +- users/kuchosauronad0/unicode.h | 1 - users/kuchosauronad0/wrappers.h | 12 +- users/ridingqwerty/unicode.h | 116 +- users/rmeli/keyrecords/unicode.h | 20 +- users/rupa/wrappers.h | 24 +- users/spidey3/spidey3_unicode.h | 4 +- users/turbomech/turbomech.c | 3 +- users/yet-another-developer/unicode.h | 1 - users/yet-another-developer/wrappers.h | 12 +- util/uf2conv.py | 21 +- util/uf2families.json | 12 +- 1271 files changed, 4131 insertions(+), 125747 deletions(-) delete mode 100644 docs/.nojekyll delete mode 100644 docs/CNAME delete mode 100644 docs/ChangeLog/20190830.md delete mode 100644 docs/ChangeLog/20200229.md delete mode 100644 docs/ChangeLog/20200530.md delete mode 100644 docs/ChangeLog/20200829.md delete mode 100644 docs/ChangeLog/20201128.md delete mode 100644 docs/ChangeLog/20210227.md delete mode 100644 docs/ChangeLog/20210529.md delete mode 100644 docs/ChangeLog/20210828.md delete mode 100644 docs/ChangeLog/20211127.md delete mode 100644 docs/ChangeLog/20220226.md delete mode 100644 docs/ChangeLog/20220528.md delete mode 100644 docs/ChangeLog/20220827.md delete mode 100644 docs/ChangeLog/20221126.md delete mode 100644 docs/ChangeLog/20230226.md delete mode 100644 docs/ChangeLog/20230528.md delete mode 100644 docs/README.md delete mode 100644 docs/_langs.md delete mode 100644 docs/_summary.md delete mode 100644 docs/adc_driver.md delete mode 100644 docs/api_development_environment.md delete mode 100644 docs/api_development_overview.md delete mode 100644 docs/api_docs.md delete mode 100644 docs/api_overview.md delete mode 100644 docs/arm_debugging.md delete mode 100644 docs/audio_driver.md delete mode 100644 docs/breaking_changes.md delete mode 100644 docs/breaking_changes_history.md delete mode 100644 docs/breaking_changes_instructions.md delete mode 100644 docs/chibios_upgrade_instructions.md delete mode 100644 docs/cli.md delete mode 100644 docs/cli_commands.md delete mode 100644 docs/cli_configuration.md delete mode 100644 docs/cli_development.md delete mode 100644 docs/cli_tab_complete.md delete mode 100644 docs/coding_conventions_c.md delete mode 100644 docs/coding_conventions_python.md delete mode 100644 docs/compatible_microcontrollers.md delete mode 100644 docs/config_options.md delete mode 100644 docs/configurator_architecture.md delete mode 100644 docs/configurator_default_keymaps.md delete mode 100644 docs/configurator_diagram.drawio delete mode 100644 docs/configurator_diagram.svg delete mode 100644 docs/configurator_step_by_step.md delete mode 100644 docs/configurator_troubleshooting.md delete mode 100644 docs/contributing.md delete mode 100644 docs/custom_matrix.md delete mode 100644 docs/custom_quantum_functions.md delete mode 100644 docs/data_driven_config.md delete mode 100644 docs/documentation_best_practices.md delete mode 100644 docs/documentation_templates.md delete mode 100644 docs/driver_installation_zadig.md delete mode 100644 docs/easy_maker.md delete mode 100644 docs/eeprom_driver.md delete mode 100644 docs/faq_build.md delete mode 100644 docs/faq_debug.md delete mode 100644 docs/faq_general.md delete mode 100644 docs/faq_keymap.md delete mode 100644 docs/faq_misc.md delete mode 100644 docs/feature_advanced_keycodes.md delete mode 100644 docs/feature_audio.md delete mode 100644 docs/feature_auto_shift.md delete mode 100644 docs/feature_autocorrect.md delete mode 100644 docs/feature_backlight.md delete mode 100644 docs/feature_bluetooth.md delete mode 100644 docs/feature_bootmagic.md delete mode 100644 docs/feature_caps_word.md delete mode 100644 docs/feature_combo.md delete mode 100644 docs/feature_command.md delete mode 100644 docs/feature_converters.md delete mode 100644 docs/feature_debounce_type.md delete mode 100644 docs/feature_digitizer.md delete mode 100644 docs/feature_dip_switch.md delete mode 100644 docs/feature_dynamic_macros.md delete mode 100644 docs/feature_eeprom.md delete mode 100644 docs/feature_encoders.md delete mode 100644 docs/feature_grave_esc.md delete mode 100644 docs/feature_haptic_feedback.md delete mode 100644 docs/feature_hd44780.md delete mode 100644 docs/feature_joystick.md delete mode 100644 docs/feature_key_lock.md delete mode 100644 docs/feature_key_overrides.md delete mode 100644 docs/feature_layers.md delete mode 100644 docs/feature_layouts.md delete mode 100644 docs/feature_leader_key.md delete mode 100644 docs/feature_led_indicators.md delete mode 100644 docs/feature_led_matrix.md delete mode 100644 docs/feature_macros.md delete mode 100644 docs/feature_midi.md delete mode 100644 docs/feature_mouse_keys.md delete mode 100644 docs/feature_oled_driver.md delete mode 100644 docs/feature_os_detection.md delete mode 100644 docs/feature_pointing_device.md delete mode 100644 docs/feature_programmable_button.md delete mode 100644 docs/feature_ps2_mouse.md delete mode 100644 docs/feature_rawhid.md delete mode 100644 docs/feature_repeat_key.md delete mode 100644 docs/feature_rgb_matrix.md delete mode 100644 docs/feature_rgblight.md delete mode 100644 docs/feature_secure.md delete mode 100644 docs/feature_send_string.md delete mode 100644 docs/feature_sequencer.md delete mode 100644 docs/feature_space_cadet.md delete mode 100644 docs/feature_split_keyboard.md delete mode 100644 docs/feature_st7565.md delete mode 100644 docs/feature_stenography.md delete mode 100644 docs/feature_swap_hands.md delete mode 100644 docs/feature_tap_dance.md delete mode 100644 docs/feature_tri_layer.md delete mode 100644 docs/feature_userspace.md delete mode 100644 docs/feature_velocikey.md delete mode 100644 docs/feature_wpm.md delete mode 100644 docs/flash_driver.md delete mode 100644 docs/flashing.md delete mode 100644 docs/flashing_bootloadhid.md delete mode 100644 docs/fuse.txt delete mode 100644 docs/getting_started_docker.md delete mode 100644 docs/getting_started_github.md delete mode 100644 docs/getting_started_introduction.md delete mode 100644 docs/gitbook/images/color-wheel.svg delete mode 100644 docs/gitbook/images/favicon.ico delete mode 100644 docs/gitbook/images/favicon.png delete mode 100644 docs/gpio_control.md delete mode 100644 docs/hand_wire.md delete mode 100644 docs/hardware_drivers.md delete mode 100644 docs/hardware_keyboard_guidelines.md delete mode 100644 docs/how_a_matrix_works.md delete mode 100644 docs/how_keyboards_work.md delete mode 100644 docs/i2c_driver.md delete mode 100644 docs/index.html delete mode 100644 docs/internals/defines.md delete mode 100644 docs/internals/input_callback_reg.md delete mode 100644 docs/internals/midi_device.md delete mode 100644 docs/internals/midi_device_setup_process.md delete mode 100644 docs/internals/midi_util.md delete mode 100644 docs/internals/send_functions.md delete mode 100644 docs/internals/sysex_tools.md delete mode 100644 docs/isp_flashing_guide.md delete mode 100644 docs/ja/README.md delete mode 100644 docs/ja/_summary.md delete mode 100644 docs/ja/adc_driver.md delete mode 100644 docs/ja/api_development_environment.md delete mode 100644 docs/ja/api_development_overview.md delete mode 100644 docs/ja/api_docs.md delete mode 100644 docs/ja/api_overview.md delete mode 100644 docs/ja/arm_debugging.md delete mode 100644 docs/ja/breaking_changes.md delete mode 100644 docs/ja/breaking_changes_instructions.md delete mode 100644 docs/ja/cli.md delete mode 100644 docs/ja/cli_commands.md delete mode 100644 docs/ja/cli_configuration.md delete mode 100644 docs/ja/cli_development.md delete mode 100644 docs/ja/coding_conventions_c.md delete mode 100644 docs/ja/coding_conventions_python.md delete mode 100644 docs/ja/compatible_microcontrollers.md delete mode 100644 docs/ja/config_options.md delete mode 100644 docs/ja/configurator_step_by_step.md delete mode 100644 docs/ja/configurator_troubleshooting.md delete mode 100644 docs/ja/contributing.md delete mode 100644 docs/ja/custom_matrix.md delete mode 100644 docs/ja/custom_quantum_functions.md delete mode 100644 docs/ja/data_driven_config.md delete mode 100644 docs/ja/documentation_best_practices.md delete mode 100644 docs/ja/documentation_templates.md delete mode 100644 docs/ja/driver_installation_zadig.md delete mode 100644 docs/ja/faq_build.md delete mode 100644 docs/ja/faq_debug.md delete mode 100644 docs/ja/faq_general.md delete mode 100644 docs/ja/faq_keymap.md delete mode 100644 docs/ja/faq_misc.md delete mode 100644 docs/ja/feature_advanced_keycodes.md delete mode 100644 docs/ja/feature_audio.md delete mode 100644 docs/ja/feature_auto_shift.md delete mode 100644 docs/ja/feature_backlight.md delete mode 100644 docs/ja/feature_bluetooth.md delete mode 100644 docs/ja/feature_bootmagic.md delete mode 100644 docs/ja/feature_combo.md delete mode 100644 docs/ja/feature_command.md delete mode 100644 docs/ja/feature_debounce_type.md delete mode 100644 docs/ja/feature_dip_switch.md delete mode 100644 docs/ja/feature_dynamic_macros.md delete mode 100644 docs/ja/feature_encoders.md delete mode 100644 docs/ja/feature_grave_esc.md delete mode 100644 docs/ja/feature_haptic_feedback.md delete mode 100644 docs/ja/feature_hd44780.md delete mode 100644 docs/ja/feature_key_lock.md delete mode 100644 docs/ja/feature_layers.md delete mode 100644 docs/ja/feature_layouts.md delete mode 100644 docs/ja/feature_leader_key.md delete mode 100644 docs/ja/feature_led_indicators.md delete mode 100644 docs/ja/feature_led_matrix.md delete mode 100644 docs/ja/feature_macros.md delete mode 100644 docs/ja/feature_mouse_keys.md delete mode 100644 docs/ja/feature_pointing_device.md delete mode 100644 docs/ja/feature_ps2_mouse.md delete mode 100644 docs/ja/feature_rawhid.md delete mode 100644 docs/ja/feature_split_keyboard.md delete mode 100644 docs/ja/feature_stenography.md delete mode 100644 docs/ja/feature_swap_hands.md delete mode 100644 docs/ja/feature_tap_dance.md delete mode 100644 docs/ja/feature_thermal_printer.md delete mode 100644 docs/ja/feature_unicode.md delete mode 100644 docs/ja/feature_userspace.md delete mode 100644 docs/ja/feature_velocikey.md delete mode 100644 docs/ja/feature_wpm.md delete mode 100644 docs/ja/flashing.md delete mode 100644 docs/ja/flashing_bootloadhid.md delete mode 100644 docs/ja/getting_started_docker.md delete mode 100644 docs/ja/getting_started_github.md delete mode 100644 docs/ja/getting_started_introduction.md delete mode 100644 docs/ja/getting_started_make_guide.md delete mode 100644 docs/ja/gpio_control.md delete mode 100644 docs/ja/hardware_avr.md delete mode 100644 docs/ja/hardware_drivers.md delete mode 100644 docs/ja/hardware_keyboard_guidelines.md delete mode 100644 docs/ja/how_a_matrix_works.md delete mode 100644 docs/ja/how_keyboards_work.md delete mode 100644 docs/ja/i2c_driver.md delete mode 100644 docs/ja/isp_flashing_guide.md delete mode 100644 docs/ja/ja_doc_status.sh delete mode 100644 docs/ja/keycodes.md delete mode 100644 docs/ja/keycodes_basic.md delete mode 100644 docs/ja/keycodes_us_ansi_shifted.md delete mode 100644 docs/ja/keymap.md delete mode 100644 docs/ja/mod_tap.md delete mode 100644 docs/ja/newbs.md delete mode 100644 docs/ja/newbs_building_firmware.md delete mode 100644 docs/ja/newbs_building_firmware_configurator.md delete mode 100644 docs/ja/newbs_flashing.md delete mode 100644 docs/ja/newbs_getting_started.md delete mode 100644 docs/ja/newbs_git_best_practices.md delete mode 100644 docs/ja/newbs_git_resolving_merge_conflicts.md delete mode 100644 docs/ja/newbs_git_resynchronize_a_branch.md delete mode 100644 docs/ja/newbs_git_using_your_master_branch.md delete mode 100644 docs/ja/newbs_learn_more_resources.md delete mode 100644 docs/ja/newbs_testing_debugging.md delete mode 100644 docs/ja/one_shot_keys.md delete mode 100644 docs/ja/other_eclipse.md delete mode 100644 docs/ja/other_vscode.md delete mode 100644 docs/ja/pr_checklist.md delete mode 100644 docs/ja/proton_c_conversion.md delete mode 100644 docs/ja/quantum_keycodes.md delete mode 100644 docs/ja/ref_functions.md delete mode 100644 docs/ja/reference_configurator_support.md delete mode 100644 docs/ja/reference_glossary.md delete mode 100644 docs/ja/reference_info_json.md delete mode 100644 docs/ja/reference_keymap_extras.md delete mode 100644 docs/ja/serial_driver.md delete mode 100644 docs/ja/support.md delete mode 100644 docs/ja/syllabus.md delete mode 100644 docs/ja/tap_hold.md delete mode 100644 docs/ja/translating.md delete mode 100644 docs/ja/understanding_qmk.md delete mode 100644 docs/keycodes_basic.md delete mode 100644 docs/keycodes_magic.md delete mode 100644 docs/keycodes_us_ansi_shifted.md delete mode 100644 docs/keymap.md delete mode 100644 docs/mod_tap.md delete mode 100644 docs/newbs.md delete mode 100644 docs/newbs_building_firmware.md delete mode 100644 docs/newbs_building_firmware_configurator.md delete mode 100644 docs/newbs_building_firmware_workflow.md delete mode 100644 docs/newbs_flashing.md delete mode 100644 docs/newbs_getting_started.md delete mode 100644 docs/newbs_git_best_practices.md delete mode 100644 docs/newbs_git_resolving_merge_conflicts.md delete mode 100644 docs/newbs_git_resynchronize_a_branch.md delete mode 100644 docs/newbs_git_using_your_master_branch.md delete mode 100644 docs/newbs_learn_more_resources.md delete mode 100644 docs/newbs_testing_debugging.md delete mode 100644 docs/one_shot_keys.md delete mode 100644 docs/other_eclipse.md delete mode 100644 docs/other_vscode.md delete mode 100644 docs/platformdev_blackpill_f4x1.md delete mode 100644 docs/platformdev_chibios_earlyinit.md delete mode 100644 docs/platformdev_proton_c.md delete mode 100644 docs/platformdev_rp2040.md delete mode 100644 docs/platformdev_selecting_arm_mcu.md delete mode 100644 docs/porting_your_keyboard_to_qmk.md delete mode 100644 docs/power.txt delete mode 100644 docs/pr_checklist.md delete mode 100644 docs/qmk.css delete mode 100644 docs/qmk_custom_dark.css delete mode 100644 docs/qmk_custom_light.css delete mode 100644 docs/quantum_keycodes.md delete mode 100644 docs/quantum_painter.md delete mode 100644 docs/quantum_painter_lvgl.md delete mode 100644 docs/quantum_painter_qff.md delete mode 100644 docs/quantum_painter_qgf.md delete mode 100644 docs/quantum_painter_rle.md delete mode 100644 docs/redirects.json delete mode 100644 docs/ref_functions.md delete mode 100644 docs/reference_configurator_support.md delete mode 100644 docs/reference_glossary.md delete mode 100644 docs/reference_info_json.md delete mode 100644 docs/reference_keymap_extras.md delete mode 100644 docs/serial_driver.md delete mode 100644 docs/spi_driver.md delete mode 100644 docs/squeezing_avr.md delete mode 100644 docs/support.md delete mode 100644 docs/support_deprecation_policy.md delete mode 100644 docs/sw.js delete mode 100644 docs/syllabus.md delete mode 100644 docs/tap_hold.md delete mode 100644 docs/translating.md delete mode 100644 docs/uart_driver.md delete mode 100644 docs/understanding_qmk.md delete mode 100644 docs/unit_testing.md delete mode 100644 docs/usb_nkro.txt delete mode 100644 docs/ws2812_driver.md delete mode 100644 docs/zh-cn/README.md delete mode 100644 docs/zh-cn/_summary.md delete mode 100644 docs/zh-cn/api_docs.md delete mode 100644 docs/zh-cn/api_overview.md delete mode 100644 docs/zh-cn/cli.md delete mode 100644 docs/zh-cn/cli_commands.md delete mode 100644 docs/zh-cn/cli_configuration.md delete mode 100644 docs/zh-cn/cli_tab_complete.md delete mode 100644 docs/zh-cn/configurator_architecture.md delete mode 100644 docs/zh-cn/configurator_default_keymaps.md delete mode 100644 docs/zh-cn/configurator_step_by_step.md delete mode 100644 docs/zh-cn/configurator_troubleshooting.md delete mode 100644 docs/zh-cn/contributing.md delete mode 100644 docs/zh-cn/custom_quantum_functions.md delete mode 100644 docs/zh-cn/driver_installation_zadig.md delete mode 100644 docs/zh-cn/easy_maker.md delete mode 100644 docs/zh-cn/faq_build.md delete mode 100644 docs/zh-cn/faq_debug.md delete mode 100644 docs/zh-cn/faq_general.md delete mode 100644 docs/zh-cn/faq_keymap.md delete mode 100644 docs/zh-cn/faq_misc.md delete mode 100644 docs/zh-cn/feature_grave_esc.md delete mode 100644 docs/zh-cn/feature_space_cadet.md delete mode 100644 docs/zh-cn/flashing.md delete mode 100644 docs/zh-cn/flashing_bootloadhid.md delete mode 100644 docs/zh-cn/getting_started_docker.md delete mode 100644 docs/zh-cn/getting_started_github.md delete mode 100644 docs/zh-cn/getting_started_introduction.md delete mode 100644 docs/zh-cn/hand_wire.md delete mode 100644 docs/zh-cn/keymap.md delete mode 100644 docs/zh-cn/mod_tap.md delete mode 100644 docs/zh-cn/newbs.md delete mode 100644 docs/zh-cn/newbs_building_firmware.md delete mode 100644 docs/zh-cn/newbs_building_firmware_configurator.md delete mode 100644 docs/zh-cn/newbs_flashing.md delete mode 100644 docs/zh-cn/newbs_getting_started.md delete mode 100644 docs/zh-cn/newbs_git_best_practices.md delete mode 100644 docs/zh-cn/newbs_git_resolving_merge_conflicts.md delete mode 100644 docs/zh-cn/newbs_git_resynchronize_a_branch.md delete mode 100644 docs/zh-cn/newbs_git_using_your_master_branch.md delete mode 100644 docs/zh-cn/newbs_learn_more_resources.md delete mode 100644 docs/zh-cn/newbs_testing_debugging.md delete mode 100644 docs/zh-cn/other_eclipse.md delete mode 100644 docs/zh-cn/other_vscode.md delete mode 100644 docs/zh-cn/reference_configurator_support.md delete mode 100644 docs/zh-cn/reference_glossary.md delete mode 100644 docs/zh-cn/support.md delete mode 100644 docs/zh-cn/syllabus.md delete mode 100644 docs/zh-cn/translating.md delete mode 100644 docs/zh-cn/zh_cn_doc_status.sh create mode 100644 keyboards/andean_condor/info.json create mode 100644 keyboards/andean_condor/keymaps/default/keymap.c create mode 100644 keyboards/andean_condor/readme.md create mode 100644 keyboards/andean_condor/rules.mk create mode 100644 keyboards/bioi/g60ble/keymaps/chemicalwill/keymap.c create mode 100644 keyboards/bioi/g60ble/keymaps/chemicalwill/rules.mk create mode 100644 keyboards/bioi/g60ble/matrix_diagram.md create mode 100755 keyboards/cablecardesigns/phoenix/info.json create mode 100644 keyboards/cablecardesigns/phoenix/keymaps/default/keymap.c create mode 100644 keyboards/cablecardesigns/phoenix/keymaps/via/keymap.c create mode 100755 keyboards/cablecardesigns/phoenix/keymaps/via/rules.mk rename quantum/process_keycode/process_key_lock.h => keyboards/cablecardesigns/phoenix/phoenix.c (79%) mode change 100644 => 100755 create mode 100755 keyboards/cablecardesigns/phoenix/readme.md create mode 100755 keyboards/cablecardesigns/phoenix/rules.mk create mode 100644 keyboards/churrosoft/deck8/info.json create mode 100644 keyboards/churrosoft/deck8/keymaps/default/keymap.c create mode 100644 keyboards/churrosoft/deck8/keymaps/via/keymap.c create mode 100644 keyboards/churrosoft/deck8/keymaps/via/rules.mk create mode 100644 keyboards/churrosoft/deck8/noleds/info.json create mode 100644 keyboards/churrosoft/deck8/noleds/readme.md create mode 100644 keyboards/churrosoft/deck8/noleds/rules.mk create mode 100644 keyboards/churrosoft/deck8/rgb/config.h create mode 100644 keyboards/churrosoft/deck8/rgb/info.json create mode 100644 keyboards/churrosoft/deck8/rgb/readme.md create mode 100644 keyboards/churrosoft/deck8/rgb/rules.mk create mode 100644 keyboards/eggsworks/egg58/config.h create mode 100644 keyboards/eggsworks/egg58/info.json create mode 100644 keyboards/eggsworks/egg58/keymaps/default/keymap.c create mode 100644 keyboards/eggsworks/egg58/keymaps/via/keymap.c create mode 100644 keyboards/eggsworks/egg58/keymaps/via/rules.mk create mode 100644 keyboards/eggsworks/egg58/readme.md create mode 100644 keyboards/eggsworks/egg58/rules.mk delete mode 100644 keyboards/giabalanai/giabalanai.c delete mode 100644 keyboards/giabalanai/giabalanai.h delete mode 100644 keyboards/giabalanai/info.json delete mode 100644 keyboards/giabalanai/keymaps/2firmware/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/2firmware/readme.md delete mode 100644 keyboards/giabalanai/keymaps/2firmware/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/3araht/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/3araht/readme.md delete mode 100644 keyboards/giabalanai/keymaps/3araht/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/default/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/default/readme.md delete mode 100644 keyboards/giabalanai/keymaps/default/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/default_giabarinaix2/config.h delete mode 100644 keyboards/giabalanai/keymaps/default_giabarinaix2/info.json delete mode 100644 keyboards/giabalanai/keymaps/default_giabarinaix2/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/default_giabarinaix2/readme.md delete mode 100644 keyboards/giabalanai/keymaps/default_giabarinaix2/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/giabarinaix2led/config.h delete mode 100644 keyboards/giabalanai/keymaps/giabarinaix2led/info.json delete mode 100644 keyboards/giabalanai/keymaps/giabarinaix2led/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/giabarinaix2led/readme.md delete mode 100644 keyboards/giabalanai/keymaps/giabarinaix2led/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/party/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/party/readme.md delete mode 100644 keyboards/giabalanai/keymaps/party/rgb_matrix_user.inc delete mode 100644 keyboards/giabalanai/keymaps/party/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/via/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/via/readme.md delete mode 100644 keyboards/giabalanai/keymaps/via/rules.mk delete mode 100644 keyboards/giabalanai/keymaps/via_giabarinaix2/config.h delete mode 100644 keyboards/giabalanai/keymaps/via_giabarinaix2/info.json delete mode 100644 keyboards/giabalanai/keymaps/via_giabarinaix2/keymap.c delete mode 100644 keyboards/giabalanai/keymaps/via_giabarinaix2/readme.md delete mode 100644 keyboards/giabalanai/keymaps/via_giabarinaix2/rules.mk delete mode 100644 keyboards/giabalanai/readme.md delete mode 100644 keyboards/giabalanai/rules.mk create mode 100644 keyboards/handwired/scottokeebs/scotto36/info.json rename quantum/keymap.h => keyboards/handwired/scottokeebs/scotto36/keymaps/default/config.h (75%) create mode 100644 keyboards/handwired/scottokeebs/scotto36/keymaps/default/keymap.c rename keyboards/{giabalanai/keymaps/via => handwired/scottokeebs/scotto36/keymaps/scotto}/config.h (75%) create mode 100644 keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/keymap.c create mode 100644 keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/rules.mk create mode 100644 keyboards/handwired/scottokeebs/scotto36/readme.md create mode 100644 keyboards/handwired/scottokeebs/scotto36/rules.mk create mode 100644 keyboards/handwired/scottokeebs/scotto40/info.json rename keyboards/{giabalanai/keymaps/2firmware => handwired/scottokeebs/scotto40/keymaps/default}/config.h (73%) create mode 100644 keyboards/handwired/scottokeebs/scotto40/keymaps/default/keymap.c rename quantum/led_tables.h => keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/config.h (73%) create mode 100644 keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/keymap.c create mode 100644 keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/rules.mk create mode 100644 keyboards/handwired/scottokeebs/scotto40/readme.md create mode 100644 keyboards/handwired/scottokeebs/scotto40/rules.mk create mode 100644 keyboards/handwired/scottokeebs/scottostarter/info.json create mode 100644 keyboards/handwired/scottokeebs/scottostarter/keymaps/default/config.h create mode 100644 keyboards/handwired/scottokeebs/scottostarter/keymaps/default/keymap.c create mode 100644 keyboards/handwired/scottokeebs/scottostarter/readme.md create mode 100644 keyboards/handwired/scottokeebs/scottostarter/rules.mk create mode 100644 keyboards/kibou/harbour/info.json create mode 100644 keyboards/kibou/harbour/keymaps/default/keymap.c create mode 100644 keyboards/kibou/harbour/keymaps/via/keymap.c create mode 100644 keyboards/kibou/harbour/keymaps/via/rules.mk create mode 100644 keyboards/kibou/harbour/readme.md create mode 100644 keyboards/kibou/harbour/rules.mk rename quantum/logging/sendchar.h => keyboards/mechlovin/zed65/rev1/config.h (69%) rename quantum/process_keycode/process_magic.h => keyboards/mechlovin/zed65/rev1/halconf.h (87%) create mode 100644 keyboards/mechlovin/zed65/rev1/info.json create mode 100644 keyboards/mechlovin/zed65/rev1/keymaps/default/keymap.c create mode 100644 keyboards/mechlovin/zed65/rev1/keymaps/via/keymap.c create mode 100644 keyboards/mechlovin/zed65/rev1/keymaps/via/rules.mk rename quantum/unicode/utf8.h => keyboards/mechlovin/zed65/rev1/mcuconf.h (86%) create mode 100644 keyboards/mechlovin/zed65/rev1/readme.md create mode 100644 keyboards/mechlovin/zed65/rev1/rules.mk create mode 100644 keyboards/soda/mango/info.json create mode 100755 keyboards/soda/mango/keymaps/default/keymap.c create mode 100755 keyboards/soda/mango/keymaps/via/keymap.c create mode 100644 keyboards/soda/mango/keymaps/via/rules.mk create mode 100644 keyboards/soda/mango/readme.md create mode 100644 keyboards/soda/mango/rules.mk delete mode 100644 quantum/action.c delete mode 100644 quantum/action.h delete mode 100644 quantum/action_code.h delete mode 100644 quantum/action_layer.c delete mode 100644 quantum/action_layer.h delete mode 100644 quantum/action_tapping.c delete mode 100644 quantum/action_tapping.h delete mode 100644 quantum/action_util.c delete mode 100644 quantum/action_util.h delete mode 100644 quantum/audio/audio.c delete mode 100644 quantum/audio/audio.h delete mode 100644 quantum/audio/luts.c delete mode 100644 quantum/audio/luts.h delete mode 100644 quantum/audio/muse.c delete mode 100644 quantum/audio/muse.h delete mode 100644 quantum/audio/musical_notes.h delete mode 100644 quantum/audio/song_list.h delete mode 100644 quantum/audio/voices.c delete mode 100644 quantum/audio/voices.h delete mode 100644 quantum/backlight/backlight.c delete mode 100644 quantum/backlight/backlight.h delete mode 100644 quantum/backlight/backlight_avr.c delete mode 100644 quantum/backlight/backlight_chibios.c delete mode 100644 quantum/backlight/backlight_driver_common.c delete mode 100644 quantum/backlight/backlight_driver_common.h delete mode 100644 quantum/backlight/backlight_software.c delete mode 100644 quantum/backlight/backlight_timer.c delete mode 100644 quantum/basic_profiling.h delete mode 100644 quantum/bitwise.c delete mode 100644 quantum/bitwise.h delete mode 100644 quantum/bootmagic/bootmagic.h delete mode 100644 quantum/bootmagic/bootmagic_lite.c delete mode 100644 quantum/bootmagic/bootmagic_lite.h delete mode 100644 quantum/bootmagic/magic.c delete mode 100644 quantum/bootmagic/magic.h delete mode 100644 quantum/caps_word.c delete mode 100644 quantum/caps_word.h delete mode 100644 quantum/color.c delete mode 100644 quantum/color.h delete mode 100644 quantum/command.c delete mode 100644 quantum/command.h delete mode 100644 quantum/crc.c delete mode 100644 quantum/crc.h delete mode 100644 quantum/debounce.h delete mode 100644 quantum/debounce/asym_eager_defer_pk.c delete mode 100644 quantum/debounce/none.c delete mode 100644 quantum/debounce/sym_defer_g.c delete mode 100644 quantum/debounce/sym_defer_pk.c delete mode 100644 quantum/debounce/sym_defer_pr.c delete mode 100644 quantum/debounce/sym_eager_pk.c delete mode 100644 quantum/debounce/sym_eager_pr.c delete mode 100644 quantum/debounce/tests/asym_eager_defer_pk_tests.cpp delete mode 100644 quantum/debounce/tests/debounce_test_common.cpp delete mode 100644 quantum/debounce/tests/debounce_test_common.h delete mode 100644 quantum/debounce/tests/rules.mk delete mode 100644 quantum/debounce/tests/sym_defer_g_tests.cpp delete mode 100644 quantum/debounce/tests/sym_defer_pk_tests.cpp delete mode 100644 quantum/debounce/tests/sym_defer_pr_tests.cpp delete mode 100644 quantum/debounce/tests/sym_eager_pk_tests.cpp delete mode 100644 quantum/debounce/tests/sym_eager_pr_tests.cpp delete mode 100644 quantum/debounce/tests/testlist.mk delete mode 100644 quantum/deferred_exec.c delete mode 100644 quantum/deferred_exec.h delete mode 100644 quantum/digitizer.c delete mode 100644 quantum/digitizer.h delete mode 100644 quantum/dip_switch.c delete mode 100644 quantum/dip_switch.h delete mode 100644 quantum/dynamic_keymap.c delete mode 100644 quantum/dynamic_keymap.h delete mode 100644 quantum/dynamic_macro.h delete mode 100644 quantum/eeconfig.c delete mode 100644 quantum/eeconfig.h delete mode 100644 quantum/encoder.c delete mode 100644 quantum/encoder.h delete mode 100644 quantum/encoder/tests/config_mock.h delete mode 100644 quantum/encoder/tests/config_mock_split_left_eq_right.h delete mode 100644 quantum/encoder/tests/config_mock_split_left_gt_right.h delete mode 100644 quantum/encoder/tests/config_mock_split_left_lt_right.h delete mode 100644 quantum/encoder/tests/config_mock_split_no_left.h delete mode 100644 quantum/encoder/tests/config_mock_split_no_right.h delete mode 100644 quantum/encoder/tests/config_mock_split_role.h delete mode 100644 quantum/encoder/tests/encoder_tests.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_left_eq_right.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_left_gt_right.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_left_lt_right.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_no_left.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_no_right.cpp delete mode 100644 quantum/encoder/tests/encoder_tests_split_role.cpp delete mode 100644 quantum/encoder/tests/mock.c delete mode 100644 quantum/encoder/tests/mock.h delete mode 100644 quantum/encoder/tests/mock_split.c delete mode 100644 quantum/encoder/tests/mock_split.h delete mode 100644 quantum/encoder/tests/rules.mk delete mode 100644 quantum/encoder/tests/testlist.mk delete mode 100644 quantum/haptic.c delete mode 100644 quantum/haptic.h delete mode 100644 quantum/joystick.c delete mode 100644 quantum/joystick.h delete mode 100644 quantum/keyboard.c delete mode 100644 quantum/keyboard.h delete mode 100644 quantum/keycode.h delete mode 100644 quantum/keycode_config.c delete mode 100644 quantum/keycode_config.h delete mode 100644 quantum/keycodes.h delete mode 100644 quantum/keymap_common.c delete mode 100644 quantum/keymap_common.h delete mode 100644 quantum/keymap_extras/keymap_belgian.h delete mode 100644 quantum/keymap_extras/keymap_bepo.h delete mode 100644 quantum/keymap_extras/keymap_brazilian_abnt2.h delete mode 100644 quantum/keymap_extras/keymap_canadian_multilingual.h delete mode 100644 quantum/keymap_extras/keymap_colemak.h delete mode 100644 quantum/keymap_extras/keymap_croatian.h delete mode 100644 quantum/keymap_extras/keymap_czech.h delete mode 100644 quantum/keymap_extras/keymap_danish.h delete mode 100644 quantum/keymap_extras/keymap_dvorak.h delete mode 100644 quantum/keymap_extras/keymap_dvorak_fr.h delete mode 100644 quantum/keymap_extras/keymap_dvorak_programmer.h delete mode 100644 quantum/keymap_extras/keymap_estonian.h delete mode 100644 quantum/keymap_extras/keymap_finnish.h delete mode 100644 quantum/keymap_extras/keymap_french.h delete mode 100644 quantum/keymap_extras/keymap_french_afnor.h delete mode 100644 quantum/keymap_extras/keymap_french_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_german.h delete mode 100644 quantum/keymap_extras/keymap_german_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_greek.h delete mode 100644 quantum/keymap_extras/keymap_hebrew.h delete mode 100644 quantum/keymap_extras/keymap_hungarian.h delete mode 100644 quantum/keymap_extras/keymap_icelandic.h delete mode 100644 quantum/keymap_extras/keymap_irish.h delete mode 100644 quantum/keymap_extras/keymap_italian.h delete mode 100644 quantum/keymap_extras/keymap_italian_mac_ansi.h delete mode 100644 quantum/keymap_extras/keymap_italian_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_japanese.h delete mode 100644 quantum/keymap_extras/keymap_korean.h delete mode 100644 quantum/keymap_extras/keymap_latvian.h delete mode 100644 quantum/keymap_extras/keymap_lithuanian_azerty.h delete mode 100644 quantum/keymap_extras/keymap_lithuanian_qwerty.h delete mode 100644 quantum/keymap_extras/keymap_neo2.h delete mode 100644 quantum/keymap_extras/keymap_nordic.h delete mode 100644 quantum/keymap_extras/keymap_norman.h delete mode 100644 quantum/keymap_extras/keymap_norwegian.h delete mode 100644 quantum/keymap_extras/keymap_plover.h delete mode 100644 quantum/keymap_extras/keymap_plover_dvorak.h delete mode 100644 quantum/keymap_extras/keymap_polish.h delete mode 100644 quantum/keymap_extras/keymap_portuguese.h delete mode 100644 quantum/keymap_extras/keymap_portuguese_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_romanian.h delete mode 100644 quantum/keymap_extras/keymap_russian.h delete mode 100644 quantum/keymap_extras/keymap_serbian.h delete mode 100644 quantum/keymap_extras/keymap_serbian_latin.h delete mode 100644 quantum/keymap_extras/keymap_slovak.h delete mode 100644 quantum/keymap_extras/keymap_slovenian.h delete mode 100644 quantum/keymap_extras/keymap_spanish.h delete mode 100644 quantum/keymap_extras/keymap_spanish_dvorak.h delete mode 100644 quantum/keymap_extras/keymap_steno.h delete mode 100644 quantum/keymap_extras/keymap_swedish.h delete mode 100644 quantum/keymap_extras/keymap_swedish_mac_ansi.h delete mode 100644 quantum/keymap_extras/keymap_swedish_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_swedish_pro_mac_ansi.h delete mode 100644 quantum/keymap_extras/keymap_swedish_pro_mac_iso.h delete mode 100644 quantum/keymap_extras/keymap_swiss_de.h delete mode 100644 quantum/keymap_extras/keymap_swiss_fr.h delete mode 100644 quantum/keymap_extras/keymap_turkish_f.h delete mode 100644 quantum/keymap_extras/keymap_turkish_q.h delete mode 100644 quantum/keymap_extras/keymap_uk.h delete mode 100644 quantum/keymap_extras/keymap_ukrainian.h delete mode 100644 quantum/keymap_extras/keymap_us.h delete mode 100644 quantum/keymap_extras/keymap_us_extended.h delete mode 100644 quantum/keymap_extras/keymap_us_international.h delete mode 100644 quantum/keymap_extras/keymap_us_international_linux.h delete mode 100644 quantum/keymap_extras/keymap_workman.h delete mode 100644 quantum/keymap_extras/keymap_workman_zxcvm.h delete mode 100644 quantum/keymap_extras/sendstring_belgian.h delete mode 100644 quantum/keymap_extras/sendstring_bepo.h delete mode 100644 quantum/keymap_extras/sendstring_brazilian_abnt2.h delete mode 100644 quantum/keymap_extras/sendstring_canadian_multilingual.h delete mode 100644 quantum/keymap_extras/sendstring_colemak.h delete mode 100644 quantum/keymap_extras/sendstring_croatian.h delete mode 100644 quantum/keymap_extras/sendstring_czech.h delete mode 100644 quantum/keymap_extras/sendstring_danish.h delete mode 100644 quantum/keymap_extras/sendstring_dvorak.h delete mode 100644 quantum/keymap_extras/sendstring_dvorak_fr.h delete mode 100644 quantum/keymap_extras/sendstring_dvorak_programmer.h delete mode 100644 quantum/keymap_extras/sendstring_estonian.h delete mode 100644 quantum/keymap_extras/sendstring_finnish.h delete mode 100644 quantum/keymap_extras/sendstring_french.h delete mode 100644 quantum/keymap_extras/sendstring_french_afnor.h delete mode 100644 quantum/keymap_extras/sendstring_french_mac_iso.h delete mode 100644 quantum/keymap_extras/sendstring_german.h delete mode 100644 quantum/keymap_extras/sendstring_german_mac_iso.h delete mode 100644 quantum/keymap_extras/sendstring_hungarian.h delete mode 100644 quantum/keymap_extras/sendstring_icelandic.h delete mode 100644 quantum/keymap_extras/sendstring_italian.h delete mode 100644 quantum/keymap_extras/sendstring_italian_mac_ansi.h delete mode 100644 quantum/keymap_extras/sendstring_italian_mac_iso.h delete mode 100644 quantum/keymap_extras/sendstring_japanese.h delete mode 100644 quantum/keymap_extras/sendstring_latvian.h delete mode 100644 quantum/keymap_extras/sendstring_lithuanian_azerty.h delete mode 100644 quantum/keymap_extras/sendstring_lithuanian_qwerty.h delete mode 100644 quantum/keymap_extras/sendstring_norman.h delete mode 100644 quantum/keymap_extras/sendstring_norwegian.h delete mode 100644 quantum/keymap_extras/sendstring_portuguese.h delete mode 100644 quantum/keymap_extras/sendstring_portuguese_mac_iso.h delete mode 100644 quantum/keymap_extras/sendstring_romanian.h delete mode 100644 quantum/keymap_extras/sendstring_serbian_latin.h delete mode 100644 quantum/keymap_extras/sendstring_slovak.h delete mode 100644 quantum/keymap_extras/sendstring_slovenian.h delete mode 100644 quantum/keymap_extras/sendstring_spanish.h delete mode 100644 quantum/keymap_extras/sendstring_spanish_dvorak.h delete mode 100644 quantum/keymap_extras/sendstring_swedish.h delete mode 100644 quantum/keymap_extras/sendstring_swiss_de.h delete mode 100644 quantum/keymap_extras/sendstring_swiss_fr.h delete mode 100644 quantum/keymap_extras/sendstring_turkish_f.h delete mode 100644 quantum/keymap_extras/sendstring_turkish_q.h delete mode 100644 quantum/keymap_extras/sendstring_uk.h delete mode 100644 quantum/keymap_extras/sendstring_us_international.h delete mode 100644 quantum/keymap_extras/sendstring_workman.h delete mode 100644 quantum/keymap_extras/sendstring_workman_zxcvm.h delete mode 100644 quantum/keymap_introspection.c delete mode 100644 quantum/keymap_introspection.h delete mode 100644 quantum/leader.c delete mode 100644 quantum/leader.h delete mode 100644 quantum/led.c delete mode 100644 quantum/led.h delete mode 100644 quantum/led_matrix/animations/alpha_mods_anim.h delete mode 100644 quantum/led_matrix/animations/band_anim.h delete mode 100644 quantum/led_matrix/animations/band_pinwheel_anim.h delete mode 100644 quantum/led_matrix/animations/band_spiral_anim.h delete mode 100644 quantum/led_matrix/animations/breathing_anim.h delete mode 100644 quantum/led_matrix/animations/cycle_left_right_anim.h delete mode 100644 quantum/led_matrix/animations/cycle_out_in_anim.h delete mode 100644 quantum/led_matrix/animations/cycle_up_down_anim.h delete mode 100644 quantum/led_matrix/animations/dual_beacon_anim.h delete mode 100644 quantum/led_matrix/animations/led_matrix_effects.inc delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_dx_dy.h delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_i.h delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_reactive.h delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h delete mode 100644 quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h delete mode 100644 quantum/led_matrix/animations/runners/led_matrix_runners.inc delete mode 100644 quantum/led_matrix/animations/solid_anim.h delete mode 100644 quantum/led_matrix/animations/solid_reactive_cross.h delete mode 100644 quantum/led_matrix/animations/solid_reactive_nexus.h delete mode 100644 quantum/led_matrix/animations/solid_reactive_simple_anim.h delete mode 100644 quantum/led_matrix/animations/solid_reactive_wide.h delete mode 100644 quantum/led_matrix/animations/solid_splash_anim.h delete mode 100644 quantum/led_matrix/animations/wave_left_right_anim.h delete mode 100644 quantum/led_matrix/animations/wave_up_down_anim.h delete mode 100644 quantum/led_matrix/led_matrix.c delete mode 100644 quantum/led_matrix/led_matrix.h delete mode 100644 quantum/led_matrix/led_matrix_drivers.c delete mode 100644 quantum/led_matrix/led_matrix_types.h delete mode 100644 quantum/led_tables.c delete mode 100644 quantum/logging/debug.c delete mode 100644 quantum/logging/debug.h delete mode 100644 quantum/logging/print.c delete mode 100644 quantum/logging/print.h delete mode 100644 quantum/logging/print.mk delete mode 100644 quantum/logging/sendchar.c delete mode 100644 quantum/main.c delete mode 100644 quantum/matrix.c delete mode 100644 quantum/matrix.h delete mode 100644 quantum/matrix_common.c delete mode 100644 quantum/midi/Config/LUFAConfig.h delete mode 100755 quantum/midi/bytequeue/COPYING delete mode 100644 quantum/midi/bytequeue/bytequeue.c delete mode 100644 quantum/midi/bytequeue/bytequeue.h delete mode 100644 quantum/midi/bytequeue/interrupt_setting.c delete mode 100644 quantum/midi/bytequeue/interrupt_setting.h delete mode 100644 quantum/midi/midi.c delete mode 100644 quantum/midi/midi.h delete mode 100644 quantum/midi/midi_device.c delete mode 100644 quantum/midi/midi_device.h delete mode 100644 quantum/midi/midi_function_types.h delete mode 100644 quantum/midi/qmk_midi.c delete mode 100644 quantum/midi/qmk_midi.h delete mode 100644 quantum/midi/sysex_tools.c delete mode 100644 quantum/midi/sysex_tools.h delete mode 100644 quantum/modifiers.h delete mode 100644 quantum/mousekey.c delete mode 100644 quantum/mousekey.h delete mode 100644 quantum/os_detection.c delete mode 100644 quantum/os_detection.h delete mode 100644 quantum/os_detection/tests/os_detection.cpp delete mode 100644 quantum/os_detection/tests/rules.mk delete mode 100644 quantum/os_detection/tests/testlist.mk delete mode 100644 quantum/painter/lvgl/qp_lvgl.c delete mode 100644 quantum/painter/lvgl/qp_lvgl.h delete mode 100644 quantum/painter/lvgl/rules.mk delete mode 100644 quantum/painter/qff.c delete mode 100644 quantum/painter/qff.h delete mode 100644 quantum/painter/qgf.c delete mode 100644 quantum/painter/qgf.h delete mode 100644 quantum/painter/qp.c delete mode 100644 quantum/painter/qp.h delete mode 100644 quantum/painter/qp_comms.c delete mode 100644 quantum/painter/qp_comms.h delete mode 100644 quantum/painter/qp_draw.h delete mode 100644 quantum/painter/qp_draw_circle.c delete mode 100644 quantum/painter/qp_draw_codec.c delete mode 100644 quantum/painter/qp_draw_core.c delete mode 100644 quantum/painter/qp_draw_ellipse.c delete mode 100644 quantum/painter/qp_draw_image.c delete mode 100644 quantum/painter/qp_draw_text.c delete mode 100644 quantum/painter/qp_internal.c delete mode 100644 quantum/painter/qp_internal.h delete mode 100644 quantum/painter/qp_internal_driver.h delete mode 100644 quantum/painter/qp_internal_formats.h delete mode 100644 quantum/painter/qp_stream.c delete mode 100644 quantum/painter/qp_stream.h delete mode 100644 quantum/painter/rules.mk delete mode 100644 quantum/pointing_device/pointing_device.c delete mode 100644 quantum/pointing_device/pointing_device.h delete mode 100644 quantum/pointing_device/pointing_device_auto_mouse.c delete mode 100644 quantum/pointing_device/pointing_device_auto_mouse.h delete mode 100644 quantum/pointing_device/pointing_device_drivers.c delete mode 100644 quantum/pointing_device/pointing_device_gestures.c delete mode 100644 quantum/pointing_device/pointing_device_gestures.h delete mode 100644 quantum/pointing_device_internal.h delete mode 100644 quantum/process_keycode/autocorrect_data_default.h delete mode 100644 quantum/process_keycode/process_audio.c delete mode 100644 quantum/process_keycode/process_audio.h delete mode 100644 quantum/process_keycode/process_auto_shift.c delete mode 100644 quantum/process_keycode/process_auto_shift.h delete mode 100644 quantum/process_keycode/process_backlight.c delete mode 100644 quantum/process_keycode/process_backlight.h delete mode 100644 quantum/process_keycode/process_caps_word.c delete mode 100644 quantum/process_keycode/process_caps_word.h delete mode 100644 quantum/process_keycode/process_clicky.c delete mode 100644 quantum/process_keycode/process_clicky.h delete mode 100644 quantum/process_keycode/process_combo.c delete mode 100644 quantum/process_keycode/process_combo.h delete mode 100644 quantum/process_keycode/process_dynamic_tapping_term.c delete mode 100644 quantum/process_keycode/process_dynamic_tapping_term.h delete mode 100644 quantum/process_keycode/process_grave_esc.c delete mode 100644 quantum/process_keycode/process_grave_esc.h delete mode 100644 quantum/process_keycode/process_haptic.c delete mode 100644 quantum/process_keycode/process_haptic.h delete mode 100644 quantum/process_keycode/process_joystick.c delete mode 100644 quantum/process_keycode/process_joystick.h delete mode 100644 quantum/process_keycode/process_key_lock.c delete mode 100644 quantum/process_keycode/process_key_override.c delete mode 100644 quantum/process_keycode/process_key_override.h delete mode 100644 quantum/process_keycode/process_leader.c delete mode 100644 quantum/process_keycode/process_leader.h delete mode 100644 quantum/process_keycode/process_magic.c delete mode 100644 quantum/process_keycode/process_midi.c delete mode 100644 quantum/process_keycode/process_midi.h delete mode 100644 quantum/process_keycode/process_music.c delete mode 100644 quantum/process_keycode/process_music.h delete mode 100644 quantum/process_keycode/process_programmable_button.c delete mode 100644 quantum/process_keycode/process_programmable_button.h delete mode 100644 quantum/process_keycode/process_repeat_key.c delete mode 100644 quantum/process_keycode/process_repeat_key.h delete mode 100644 quantum/process_keycode/process_rgb.c delete mode 100644 quantum/process_keycode/process_rgb.h delete mode 100644 quantum/process_keycode/process_secure.c delete mode 100644 quantum/process_keycode/process_secure.h delete mode 100644 quantum/process_keycode/process_sequencer.c delete mode 100644 quantum/process_keycode/process_sequencer.h delete mode 100644 quantum/process_keycode/process_space_cadet.c delete mode 100644 quantum/process_keycode/process_space_cadet.h delete mode 100644 quantum/process_keycode/process_steno.c delete mode 100644 quantum/process_keycode/process_steno.h delete mode 100644 quantum/process_keycode/process_tap_dance.c delete mode 100644 quantum/process_keycode/process_tap_dance.h delete mode 100644 quantum/process_keycode/process_tri_layer.c delete mode 100644 quantum/process_keycode/process_tri_layer.h delete mode 100644 quantum/process_keycode/process_ucis.c delete mode 100644 quantum/process_keycode/process_ucis.h delete mode 100644 quantum/process_keycode/process_unicode.c delete mode 100644 quantum/process_keycode/process_unicode.h delete mode 100644 quantum/process_keycode/process_unicode_common.c delete mode 100644 quantum/process_keycode/process_unicode_common.h delete mode 100644 quantum/process_keycode/process_unicodemap.c delete mode 100644 quantum/process_keycode/process_unicodemap.h delete mode 100644 quantum/programmable_button.c delete mode 100644 quantum/programmable_button.h delete mode 100644 quantum/quantum.c delete mode 100644 quantum/quantum.h delete mode 100644 quantum/raw_hid.h delete mode 100644 quantum/repeat_key.c delete mode 100644 quantum/repeat_key.h delete mode 100644 quantum/rgb_matrix/animations/alpha_mods_anim.h delete mode 100644 quantum/rgb_matrix/animations/breathing_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_sat_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_spiral_val_anim.h delete mode 100644 quantum/rgb_matrix/animations/colorband_val_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_all_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_left_right_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_out_in_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_pinwheel_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_spiral_anim.h delete mode 100644 quantum/rgb_matrix/animations/cycle_up_down_anim.h delete mode 100644 quantum/rgb_matrix/animations/digital_rain_anim.h delete mode 100644 quantum/rgb_matrix/animations/dual_beacon_anim.h delete mode 100644 quantum/rgb_matrix/animations/gradient_left_right_anim.h delete mode 100644 quantum/rgb_matrix/animations/gradient_up_down_anim.h delete mode 100644 quantum/rgb_matrix/animations/hue_breathing_anim.h delete mode 100644 quantum/rgb_matrix/animations/hue_pendulum_anim.h delete mode 100644 quantum/rgb_matrix/animations/hue_wave_anim.h delete mode 100644 quantum/rgb_matrix/animations/jellybean_raindrops_anim.h delete mode 100644 quantum/rgb_matrix/animations/pixel_flow_anim.h delete mode 100644 quantum/rgb_matrix/animations/pixel_fractal_anim.h delete mode 100644 quantum/rgb_matrix/animations/pixel_rain_anim.h delete mode 100644 quantum/rgb_matrix/animations/rainbow_beacon_anim.h delete mode 100644 quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h delete mode 100644 quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h delete mode 100644 quantum/rgb_matrix/animations/raindrops_anim.h delete mode 100644 quantum/rgb_matrix/animations/rgb_matrix_effects.inc delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_i.h delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_reactive.h delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h delete mode 100644 quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h delete mode 100644 quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc delete mode 100644 quantum/rgb_matrix/animations/solid_color_anim.h delete mode 100644 quantum/rgb_matrix/animations/solid_reactive_anim.h delete mode 100644 quantum/rgb_matrix/animations/solid_reactive_cross.h delete mode 100644 quantum/rgb_matrix/animations/solid_reactive_nexus.h delete mode 100644 quantum/rgb_matrix/animations/solid_reactive_simple_anim.h delete mode 100644 quantum/rgb_matrix/animations/solid_reactive_wide.h delete mode 100644 quantum/rgb_matrix/animations/solid_splash_anim.h delete mode 100644 quantum/rgb_matrix/animations/splash_anim.h delete mode 100644 quantum/rgb_matrix/animations/typing_heatmap_anim.h delete mode 100644 quantum/rgb_matrix/rgb_matrix.c delete mode 100644 quantum/rgb_matrix/rgb_matrix.h delete mode 100644 quantum/rgb_matrix/rgb_matrix_drivers.c delete mode 100644 quantum/rgb_matrix/rgb_matrix_types.h delete mode 100644 quantum/rgblight/rgblight.c delete mode 100644 quantum/rgblight/rgblight.h delete mode 100644 quantum/rgblight/rgblight_breathe_table.h delete mode 100644 quantum/rgblight/rgblight_modes.h delete mode 100644 quantum/rgblight/rgblight_post_config.h delete mode 100644 quantum/ring_buffer.h delete mode 100644 quantum/secure.c delete mode 100644 quantum/secure.h delete mode 100644 quantum/send_string/send_string.c delete mode 100644 quantum/send_string/send_string.h delete mode 100644 quantum/send_string/send_string_keycodes.h delete mode 100644 quantum/sequencer/sequencer.c delete mode 100644 quantum/sequencer/sequencer.h delete mode 100644 quantum/sequencer/tests/midi_mock.c delete mode 100644 quantum/sequencer/tests/midi_mock.h delete mode 100644 quantum/sequencer/tests/rules.mk delete mode 100644 quantum/sequencer/tests/sequencer_tests.cpp delete mode 100644 quantum/sequencer/tests/testlist.mk delete mode 100644 quantum/split_common/eeprom-lefthand.eep delete mode 100644 quantum/split_common/eeprom-righthand.eep delete mode 100644 quantum/split_common/post_config.h delete mode 100644 quantum/split_common/split_util.c delete mode 100644 quantum/split_common/split_util.h delete mode 100644 quantum/split_common/transaction_id_define.h delete mode 100644 quantum/split_common/transactions.c delete mode 100644 quantum/split_common/transactions.h delete mode 100644 quantum/split_common/transport.c delete mode 100644 quantum/split_common/transport.h delete mode 100644 quantum/sync_timer.c delete mode 100644 quantum/sync_timer.h delete mode 100644 quantum/tri_layer.c delete mode 100644 quantum/tri_layer.h delete mode 100644 quantum/unicode/unicode.c delete mode 100644 quantum/unicode/unicode.h delete mode 100644 quantum/unicode/utf8.c delete mode 100644 quantum/util.h delete mode 100644 quantum/variable_trace.c delete mode 100644 quantum/variable_trace.h delete mode 100644 quantum/velocikey.c delete mode 100644 quantum/velocikey.h delete mode 100644 quantum/via.c delete mode 100644 quantum/via.h delete mode 100644 quantum/virtser.h delete mode 100644 quantum/wear_leveling/tests/backing_mocks.cpp delete mode 100644 quantum/wear_leveling/tests/backing_mocks.hpp delete mode 100644 quantum/wear_leveling/tests/rules.mk delete mode 100644 quantum/wear_leveling/tests/testlist.mk delete mode 100644 quantum/wear_leveling/tests/wear_leveling_2byte.cpp delete mode 100644 quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp delete mode 100644 quantum/wear_leveling/tests/wear_leveling_4byte.cpp delete mode 100644 quantum/wear_leveling/tests/wear_leveling_8byte.cpp delete mode 100644 quantum/wear_leveling/tests/wear_leveling_general.cpp delete mode 100644 quantum/wear_leveling/wear_leveling.c delete mode 100644 quantum/wear_leveling/wear_leveling.h delete mode 100644 quantum/wear_leveling/wear_leveling_internal.h delete mode 100644 quantum/wpm.c delete mode 100644 quantum/wpm.h delete mode 100644 readme.md diff --git a/docs/.nojekyll b/docs/.nojekyll deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/docs/CNAME b/docs/CNAME deleted file mode 100644 index e089843e0bcc..000000000000 --- a/docs/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.qmk.fm \ No newline at end of file diff --git a/docs/ChangeLog/20190830.md b/docs/ChangeLog/20190830.md deleted file mode 100644 index 298ec958c529..000000000000 --- a/docs/ChangeLog/20190830.md +++ /dev/null @@ -1,52 +0,0 @@ -# QMK Breaking Change - 2019 Aug 30 - -Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. - -This document marks the inaugural Breaking Change merge. A list of changes follows. - -## Core code formatting with clang-format - -* All core files (`drivers/`, `quantum/`, `tests/`, and `tmk_core/`) have been formatted with clang-format -* A travis process to reformat PRs on merge has been instituted -* You can use the new CLI command `qmk cformat` to format before submitting your PR if you wish. - -## LUFA USB descriptor cleanup - -* Some code cleanups related to the USB HID descriptors on AVR keyboards, to make them easier to read and understand -* More information: see https://github.com/qmk/qmk_firmware/pull/4871 -* No behaviour changes anticipated and no keymaps modified - -## Migrating `ACTION_LAYER_MOMENTARY()` entries in `fn_actions` to `MO()` keycodes - -* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` -* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity -* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features - -## Update Atreus to current code conventions - -* Duplicate include guards have bypassed the expected header processing behavior -* All keymaps affected are recommended to remove duplication of `/config.h` to `/keymaps//config.h` and only provide overrides at the keymap level - -## Backport changes to keymap language files from ZSA fork - -* Fixes an issue in the `keymap_br_abnt2.h` file that includes the wrong source (`keymap_common.h` instead of `keymap.h`) -* Updates the `keymap_swedish.h` file to be specific to swedish, and not just "nordic" in general. -* Any keymaps using this will need to remove `NO_*` and replace it with `SE_*`. - -## Update repo to use LUFA as a git submodule - -* `/lib/LUFA` removed from the repo -* LUFA set as a submodule, pointing to qmk/lufa -* This should allow more flexibility with LUFA, and allow us to keep the sub-module up to date, a lot more easily. It was ~2 years out of date with no easy path to fix that. This prevents that from being an issue in the future - -## Migrating `ACTION_BACKLIGHT_*()` entries in `fn_actions` to `BL_` keycodes - -* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` -* All keymaps using these actions have had the relevant `KC_FN*` keys replaced with the equivalent `BL_*` keys -* If you currently use `KC_FN*` you will need to replace `fn_actions` with the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features - -## Remove `KC_DELT` alias in favor of `KC_DEL` - -* `KC_DELT` was a redundant, undocumented alias for `KC_DELETE` -* It has been removed and all its uses replaced with the more common `KC_DEL` alias -* Around 90 keymaps (mostly for ErgoDox boards) have been modified as a result diff --git a/docs/ChangeLog/20200229.md b/docs/ChangeLog/20200229.md deleted file mode 100644 index 398fe01c0d04..000000000000 --- a/docs/ChangeLog/20200229.md +++ /dev/null @@ -1,75 +0,0 @@ -# QMK Breaking Change - 2020 Feb 29 Changelog - -Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. - - -## Update ChibiOS/ChibiOS-Contrib/uGFX submodules - -* General Notes - * A `make git-submodule` may be required after pulling the latest QMK firmware code to update affected submodules to the upgraded revisions - * Enabling link-time-optimization (`LINK_TIME_OPTIMIZATION_ENABLE = yes`) should work on a lot more boards -* Upgrade to ChibiOS ver19.1.3 - * This will allow QMK to update to upstream ChibiOS a lot easier -- the old version was ~2 years out of date. Automated update scripts have been made available to simplify future upgrades. - * Includes improved MCU support and bugfixes - * ChibiOS revision is now included in Command output - * Timers should now be more accurate -* Upgrade to newer ChibiOS-Contrib - * Also includes improved MCU support and bugfixes - * ChibiOS-Contrib revision is now included in Command output -* Upgrade to newer uGFX - * Required in order to support updated ChibiOS - - -## Fix ChibiOS timer overflow for 16-bit SysTick devices - -* On 16-bit SysTick devices, the timer subsystem in QMK was incorrectly dealing with overflow. - * When running at a 100000 SysTick frequency (possible on 16-bit devices, but uncommon), this overflow would occur after 0.65 seconds. -* Timers are now correctly handling this overflow case and timing should now be correct on ChibiOS/ARM. - - -## Update LUFA submodule - -* Updates the LUFA submodule to include updates from upstream (abcminiuser/lufa) -* Includes some cleanup for QMK DFU generation - - -## Encoder flip - -* Flips the encoder direction so that `clockwise == true` is for actually turning the knob clockwise -* Adds `ENCODER_DIRECTION_FLIP` define, so that reversing the expected dirction is simple for users. -* Cleans up documentation page for encoders - - -## Adding support for `BACKLIGHT_ON_STATE` for hardware PWM backlight - -* Previously, the define only affected software PWM, and hardware PWM always assumed an N-channel MOSFET. -* The hardware PWM backlight setup has been updated to respect this option. -* The default "on" state has been changed to `1` - **this impacts all keyboards using software PWM backlight that do not define it explicitly**. If your keyboard's backlight is acting strange, it may have a P-channel MOSFET, and will need to have `#define BACKLIGHT_ON_STATE 0` added to the keyboard-level `config.h`. Please see the PR for more detailed information. - - -## Migrating `ACTION_LAYER_TAP_KEY()` entries in `fn_actions` to `LT()` keycodes - -* `fn_actions` is deprecated, and its functionality has been superseded by direct keycodes and `process_record_user()` -* The end result of removing this obsolete feature should result in a decent reduction in firmware size and code complexity -* All keymaps affected are recommended to switch away from `fn_actions` in favour of the [custom keycode](https://docs.qmk.fm/#/custom_quantum_functions) and [macro](https://docs.qmk.fm/#/feature_macros) features - - -## Moving backlight keycode handling to `process_keycode/` - -* This refactors the backlight keycode logic to be clearer and more modular. -* All backlight-related keycodes are now actioned in a single file. -* The `ACTION_BACKLIGHT_*` macros have also been deleted. If you are still using these in a `fn_actions[]` block, please switch to using the backlight keycodes or functions directly. - - -## Refactor Planck keymaps to use Layout Macros - -* Refactor Planck keymaps to use layout macros instead of raw matrix assignments -* Makes keymaps revision-agnostic -* Should reduce noise and errors in Travis CI logs - - -## GON NerD codebase refactor - -* Splits the codebase for GON NerD 60 and NerdD TKL PCBs into two separate directories. -* If your keymap is for a NerD 60 PCB, your `make` command is now `make gon/nerd60:`. -* If your keymap is for a NerD TKL PCB, your `make` command is now `make gon/nerdtkl:`. diff --git a/docs/ChangeLog/20200530.md b/docs/ChangeLog/20200530.md deleted file mode 100644 index 9def9ae12350..000000000000 --- a/docs/ChangeLog/20200530.md +++ /dev/null @@ -1,239 +0,0 @@ -# QMK Breaking Change - 2020 May 30 Changelog - -Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. - -The list of changes follows. - - -## Core Changes - -### Converting V-USB usbdrv to a submodule - -[#8321](https://github.com/qmk/qmk_firmware/pull/8321) and [qmk_compiler#62](https://github.com/qmk/qmk_compiler/pull/62). - -These PRs move the V-USB driver code out of the qmk_firmware repository and into a submodule pointed at https://github.com/obdev/v-usb. This will make it easier to update the codebase if needed, while applying any potential QMK-specific modifications by forking it to the QMK GitHub organization. - -### Unify Tap Hold functions and documentation - -[#8348](https://github.com/qmk/qmk_firmware/pull/8348) - -Updates all of the per key tap-hold functions to pass the `keyrecord_t` structure, and include documentation changes. - -Any remaining versions or code outside of the main repo will need to be converted: -| Old function | New Function | -|------------------------------------------------------|---------------------------------------------------------------------------| -|`uint16_t get_tapping_term(uint16_t keycode)` |`uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record)` | -|`bool get_ignore_mod_tap_interrupt(uint16_t keycode)` |`bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record)` | - -### Python Required In The Build Process - -[#9000](https://github.com/qmk/qmk_firmware/pull/9000) - -This is the last release of QMK that will work without having Python 3.6 (or later) installed. If your environment is not fully setup you will get a warning instructing you to set it up. - -After the next breaking change you will not be able to build if `bin/qmk hello` does not work. - -### Upgrade from tinyprintf to mpaland/printf - -[#8269](https://github.com/qmk/qmk_firmware/pull/8269) - -- Provides debug functionality on ChibiOS/ARM that is more compliant than previous integrations. -- Less maintenence, fewer QMK customisations, and allows QMK to sidestep previous compile and runtime issues. -- A `make git-submodule` may be required after pulling the latest QMK Firmware code to update to the new dependency. - -### Fixed RGB_DISABLE_AFTER_TIMEOUT to be seconds based & small internals cleanup - -[#6480](https://github.com/qmk/qmk_firmware/pull/6480) - -- Changes `RGB_DISABLE_AFTER_TIMEOUT` to be based on milliseconds instead of ticks. -- Includes a code cleanup, resulting in a savings of 100 bytes, depending on features used. -- Fixed issues with timeouts / suspending at the wrong time not turning off all LEDs in some cases. - -The `RGB_DISABLE_AFTER_TIMEOUT` definition is now deprecated, and has been superseded by `RGB_DISABLE_TIMEOUT`. To use the new definition, rename `RGB_DISABLE_AFTER_TIMEOUT` to `RGB_DISABLE_TIMEOUT` in your `config.h` file, and multiply the value set by 1200. - -Before: `#define RGB_DISABLE_AFTER_TIMEOUT 100` -After: `#define RGB_DISABLE_TIMEOUT 120000` - -### Switch to qmk forks for everything - -[#9019](https://github.com/qmk/qmk_firmware/pull/9019) - -Fork all QMK submodules to protect against upstream repositories disappearing. - -### code cleanup regarding deprecated macro PLAY_NOTE_ARRAY by replacing it with PLAY_SONG - -[#8484](https://github.com/qmk/qmk_firmware/pull/8484) - -Removes the deprecated `PLAY_NOTE_ARRAY` macro. References to it are replaced with `PLAY_SONG`, which references the same function. - -### fixing wrong configuration of AUDIO feature - -[#8903](https://github.com/qmk/qmk_firmware/pull/8903) and [#8974](https://github.com/qmk/qmk_firmware/pull/8974) - -`audio_avr.c` does not default to any pin; there has to be a #define XX_AUDIO in config.h at some level for Audio to actually work. Otherwise, the Audio code ends up cluttering the firmware, possibly breaking builds because the maximum allowed firmware size is exceeded. - -These changes fix this by disabling Audio on keyboards that have the feature misconfigured, and therefore non-functional. - -Also, add a compile-time error to alert the user to a missing pin-configuration (on AVR boards) when `AUDIO_ENABLE = yes` is set. - - -## Keyboard Refactors - -### Migrating Lily58 to use split_common - -[#6260](https://github.com/qmk/qmk_firmware/pull/6260) - -Modifies the default firmware for Lily58 to use the `split_common` library, instead of including and depending on its own set of libraries for the following functionality: - -- SSD1306 display -- i2c for OLED -- Serial Communication - -This allows current lily58 firmware to advance with updates to the `split_common` library, which is shared with many other split keyboards. - -#### To migrate existing Lily58 firmware: - -[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-445ac369c8717dcd6fc6fc3630836fc1): -- Remove `#define SSD1306OLED` from config.h - - -[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7): -- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` -- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) -- Alternatively, if you did not change the OLED code from that in `default`, you may find it easier to simply copy the [relevant section](https://github.com/qmk/qmk_firmware/blob/4ac310668501ae6786c711ecc8f01f62ddaa1c0b/keyboards/lily58/keymaps/default/keymap.c#L138-L172). Otherwise, the changes you need to make are as follows (sample change [here](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7R138-R173)) -- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L138-L141) the block -```c -#ifdef SSD1306OLED - iota_gfx_init(!has_usb()); // turns on the display -#endif -``` -- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: -```c -oled_rotation_t oled_init_user(oled_rotation_t rotation) { - if (!is_keyboard_master()) - return OLED_ROTATION_180; // flips the display 180 degrees if offhand - return rotation; -} -``` -- Remove the functions `matrix_scan_user`, `matrix_update` and `iota_gfx_task_user` -- Find/Replace `matrix_render_user(struct CharacterMatrix *matrix)` with `iota_gfx_task_user(void)` -- Find/Replace `is_master` with `is_keyboard_master()` -- For each instance of `matrix_write_ln(matrix, display_fn())`, rewrite it as `oled_write_ln(read_layer_state(), false);` -- For each instance of `matrix_write(matrix, read_logo());`, replace with `oled_write(read_logo(), false);` - -### Refactor zinc to use split_common - -[#7114](https://github.com/qmk/qmk_firmware/pull/7114) and [#9171](https://github.com/qmk/qmk_firmware/pull/9171) - -* Refactor to use split_common and remove split codes under the zinc/revx/ -* Add - backlight RGB LED and/or underglow RGB LED option -* Add - continuous RGB animations feature (between L and R halves) -* Fix - keymap files to adapt to changes - * all authors of keymaps confirmed this PR -* Update - documents and rules.mk - -### Refactor of TKC1800 to use common OLED code - -[#8472](https://github.com/qmk/qmk_firmware/pull/8472) - -Modifies the default firmware for TKC1800 to use the in-built I2C and OLED drivers, instead of including and depending on its own set of libraries for the following functionality: - -- SSD1306 display -- i2c for OLED - -This allows current TKC1800 firmware to advance with updates to those drivers, which are shared with other keyboards. - -#### To migrate existing TKC1800 firmware: - -[Changes to `config.h`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-d10b26e676b4a55cbb00d71955116526): -- Remove `#define SSD1306OLED` from config.h - -[Changes to `tkc1800.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-3b35bd30abe89c8110717c6972cd2cc5): -- Add the following to avoid debug errors on HID_listen if the screen is not present -```c -void keyboard_pre_init_kb(void) { - setPinInputHigh(D0); - setPinInputHigh(D1); - - keyboard_pre_init_user(); -} -``` - -[Changes to `keymap.c`](https://github.com/qmk/qmk_firmware/pull/8472/files#diff-05a2a344ce27e4d045fe68520ccd4771): -- Find/Replace each instance of `#ifdef SSD1306OLED` with `#ifdef OLED_DRIVER_ENABLE` -- The following changes are for compatibility with the OLED driver. If you don't use the OLED driver you may safely delete [this section](https://github.com/qmk/qmk_firmware/blob/e6b9980bd45c186f7360df68c24b6e05a80c10dc/keyboards/lily58/keymaps/default/keymap.c#L144-L190) -- [Remove](https://github.com/qmk/qmk_firmware/pull/6260/files#diff-20943ea59856e9bdf3d99ecb2eee40b7L91-L158) the block -```c -#ifdef SSD1306OLED - iota_gfx_init(!has_usb()); // turns on the display -#endif -``` -- Within the block bounded by `#ifdef OLED_DRIVER_ENABLE` and `#endif // OLED_DRIVER_ENABLE`, add the following block to ensure that your two OLEDs are rotated correctly across the left and right sides: -```c -oled_rotation_t oled_init_user(oled_rotation_t rotation) { - if (!is_keyboard_master()) - return OLED_ROTATION_180; // flips the display 180 degrees if offhand - return rotation; -} -``` -- Remove the function `iota_gfx_task_user` - -### Split HHKB to ANSI and JP layouts and Add VIA support for each - -[#8582](https://github.com/qmk/qmk_firmware/pull/8582) - -- Splits the HHKB codebase into two separate folders `keyboards/hhkb/ansi` and `keyboards/hhkb/jp`. -- Adds VIA Configurator support for both versions. - -#### Migrating existing HHKB keymaps - -- Remove any checks for the `HHKB_JP` definition - - All checks for this definition have been removed, and each version uses the source that is appropriate to that version. -- Move the directory for your keymap into the appropriate `keymaps` directory - - `keyboards/hhkb/ansi/keymaps/` for ANSI HHKBs - - `keyboards/hhkb/jp/keymaps/` for HHKB JPs -- Compile with the new keyboard names - - This PR changes the compilation instructions for the HHKB Alternate Controller. To compile firmware for this controller moving forward, use: - - `make hhkb/ansi` for ANSI-layout HHKBs - - `make hhkb/jp` for HHKB JP keyboards - - -## Keyboard Moves - -- [#8412](https://github.com/qmk/qmk_firmware/pull/8412 "Changing board names to prevent confusion") by blindassassin111 -- [#8499](https://github.com/qmk/qmk_firmware/pull/8499 "Move the Keyboardio Model01 to a keyboardio/ subdir") by algernon -- [#8830](https://github.com/qmk/qmk_firmware/pull/8830 "Move spaceman keyboards") by Spaceman (formerly known as Rionlion100) -- [#8537](https://github.com/qmk/qmk_firmware/pull/8537 "Organizing my keyboards (plaid, tartan, ergoinu)") by hsgw - -Keyboards by Keyboardio, Spaceman, and hsgw move to vendor folders, while PCBs designed by blindassassin111 are renamed. - -Old Name | New Name -:----------------- | :----------------- -2_milk | spaceman/2_milk -at101_blackheart | at101_bh -ergoinu | dm9records/ergoinu -model01 | keyboardio/model01 -omnikey_blackheart | omnikey_bh -pancake | spaceman/pancake -plaid | dm9records/plaid -tartan | dm9records/tartan -z150_blackheart | z150_bh - -If you own one of these PCBs, please use the new names to compile your firmware moving forward. - - -## Keycode Migration PRs - -[#8954](https://github.com/qmk/qmk_firmware/pull/8954 "Migrate `ACTION_LAYER_TOGGLE` to `TG()`"), [#8957](https://github.com/qmk/qmk_firmware/pull/8957 "Migrate `ACTION_MODS_ONESHOT` to `OSM()`"), [#8958](https://github.com/qmk/qmk_firmware/pull/8958 "Migrate `ACTION_DEFAULT_LAYER_SET` to `DF()`"), [#8959](https://github.com/qmk/qmk_firmware/pull/8959 "Migrate `ACTION_LAYER_MODS` to `LM()`"), [#8968](https://github.com/qmk/qmk_firmware/pull/8968 "Migrate `ACTION_MODS_TAP_KEY` to `MT()`"), [#8977](https://github.com/qmk/qmk_firmware/pull/8977 "Migrate miscellaneous `fn_actions` entries"), and [#8979](https://github.com/qmk/qmk_firmware/pull/8979 "Migrate `ACTION_MODS_KEY` to chained mod keycodes") - -Authored by fauxpark, these pull requests remove references to deprecated TMK macros that have been superseded by native QMK keycodes. - -Old `fn_actions` action | New QMK keycode -:---------------------- | :-------------- -`ACTION_DEFAULT_LAYER_SET(layer)` | `DF(layer)` -`ACTION_LAYER_MODS(layer, mod)` | `LM(layer, mod)` -`ACTION_LAYER_ONESHOT(mod)` | `OSL(mod)` -`ACTION_LAYER_TOGGLE(layer)` | `TG(layer)` -`ACTION_MODS_ONESHOT(mod)` | `OSM(mod)` -`ACTION_MODS_TAP_KEY(mod, kc)` | `MT(mod, kc)` -`ACTION_MODS_KEY(mod, kc)`
e.g. `ACTION_MODS_KEY(MOD_LCTL, KC_0)` | `MOD(kc)`
e.g. `LCTL(KC_0)` diff --git a/docs/ChangeLog/20200829.md b/docs/ChangeLog/20200829.md deleted file mode 100644 index c6abed5b3023..000000000000 --- a/docs/ChangeLog/20200829.md +++ /dev/null @@ -1,148 +0,0 @@ -# QMK Breaking Change - 2020 Aug 29 Changelog - -Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. - - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Relocated Keyboards :id=relocated-keyboards - -#### The Key Company project consolidation ([#9547](https://github.com/qmk/qmk_firmware/pull/9547)) -#### relocating boards by flehrad to flehrad/ folder ([#9635](https://github.com/qmk/qmk_firmware/pull/9635)) - -Keyboards released by The Key Company and keyboards designed by flehrad have moved to vendor folders. If you own any of the keyboards listed below, please use the new names to compile your firmware moving forward. - -Old Name | New Name -:--------------------- | :------------------ -candybar/lefty | tkc/candybar/lefty -candybar/righty | tkc/candybar/righty -m0lly | tkc/m0lly -tkc1800 | tkc/tkc1800 -bigswitch | flehrad/bigswitch -handwired/downbubble | flehrad/downbubble -handwired/numbrero | flehrad/numbrero -snagpad | flehrad/snagpad -handwired/tradestation | flehrad/tradestation - -### Updated Keyboard Codebases :id=keyboard-updates - -#### Keebio RGB wiring update ([#7754](https://github.com/qmk/qmk_firmware/pull/7754)) - -This pull request changes the configuration for Keebio split boards to use the same RGB strip wiring for each half, which provides the following improvements: - -* Easier wiring due to one fewer wire needed (the wire between left DOut to extra data pin) and the fact that wiring is the same for both halves. -* RGB LEDs can be controlled by each half now instead of just master half. -* Extra data line is freed up to allow for I2C usage instead of serial. - -If you have customized the value of `RGBLED_SPLIT` for your keymap, you will need to undefine it using `#undef RGBLED_SPLIT` before defining it to your customized value. - -This change affects: - -* BFO-9000 -* Fourier -* Iris rev2 -* Levinson, revs. 1 and 2 -* Nyquist, revs. 1 and 2 -* Quefrency rev1 -* Viterbi, revs. 1 and 2 - -### Changes to Core Functionality :id=core-updates - -* Bigger Combo index ([#9318](https://github.com/qmk/qmk_firmware/pull/9318)) - -Allows the Combo feature to support more than 256 combos. - -Any fork that uses `process_combo_event` needs to update the function's first argument to `uint16_t`: - -* Old function: `void process_combo_event(uint8_t combo_index, bool pressed)` -* New function: `void process_combo_event(uint16_t combo_index, bool pressed)` - - -## Core Changes :id=core-changes - -### Fixes :id=core-fixes - -* Mousekeys: scrolling acceleration is no longer coupled to mouse movement acceleration ([#9174](https://github.com/qmk/qmk_firmware/pull/9174)) -* Keymap Extras: correctly assign Question Mark in Czech layout ([#9987](https://github.com/qmk/qmk_firmware/pull/9987)) - -### Additions and Enhancements :id=core-additions - -* allow for WS2812 PWM to work on DMAMUX-capable devices ([#9471](https://github.com/qmk/qmk_firmware/pull/9471)) - * Newer STM32 MCUs have a DMAMUX peripheral, which allows mapping of DMAs to different DMA streams, rather than hard-defining the target streams in silicon. - * Affects STM32L4+ devices, as well as the soon-to-be-supported-by-QMK STM32G4/H7 families. - * Tested on F303/Proton C (ChibiOS v19, non-DMAMUX), G474 (ChibiOS v20, with DMAMUX). -* dual-bank STM32 bootloader support ([#8778](https://github.com/qmk/qmk_firmware/pull/8778) and [#9738](https://github.com/qmk/qmk_firmware/pull/9738)) - * Adds support for STM32 dual-bank flash bootloaders, by toggling a GPIO during early init in order to charge an RC circuit attached to `BOOT0`. - * The main rationale behind this is that dual-bank STM32 devices unconditionally execute user-mode code, regardless of whether or not the user-mode code jumps to the bootloader. If either flash bank is valid (and `BOOT0` is low), then the built-in bootloader will skip any sort of DFU. - * This PR allows for the initialisation sequencing to charge the RC circuit based on the example circuit posted on Discord, effectively pulling `BOOT0` high before issuing the system reset. As the RC circuit takes a while to discharge, the system reset executes the ROM bootloader which subsequently sees `BOOT0` high, and starts executing the DFU routines. - * Tested with STM32L082 (with current QMK+current ChibiOS), and STM32G474 (against ChibiOS 20.x). -* update Space Cadet and Tap Dance features to use Custom Tapping Term when appropriate ([#6259](https://github.com/qmk/qmk_firmware/pull/6259)) - * For the Tap Dance feature, this completely removes the need for the `ACTION_TAP_DANCE_FN_ADVANCED_TIME` dance. -* HID Joystick Interface ([#4226](https://github.com/qmk/qmk_firmware/pull/4226) and [#9949](https://github.com/qmk/qmk_firmware/pull/9949 "Fix Joystick Compile Issues")) - * This implements a joystick feature, including a joystick_task function called from TMK, specific keycodes for joystick buttons and a USB HID interface. - * Tested on V-USB backend and Proton C; compiles but untested on LUFA. - * In order to test, you have to add `JOYSTICK_ENABLE = yes` to your `rules.mk` and - ```c - #define JOYSTICK_BUTTON_COUNT 8 - #define JOYSTICK_AXES_COUNT 2 - ``` - in your config.h. -* Christmas RGB Underglow animation now fades between green and red ([#7648](https://github.com/qmk/qmk_firmware/pull/7648)) - * `RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL` has been greatly decreased; please check your animation if you have customized this value. -* layer state now initializes on startup ([#8318](https://github.com/qmk/qmk_firmware/pull/8318)) - * This should produce more consistent behavior between the two functions and layer masks. -* added support for HSV->RGB conversion without using CIE curve ([#9856](https://github.com/qmk/qmk_firmware/pull/9856)) -* added NOEEPROM functions for RGB Matrix ([#9487](https://github.com/qmk/qmk_firmware/pull/9487)) - * Added eeprom_helpers for toggle, mode, sethsv, speed, similar to rgblight versions. - * Added set_speed function. - * Added helper functions, similar to those in rgblight, in order to add NOEEPROM versions of toggle, step, hue, sat, val, and speed. - * Minor: spelling correction for EEPROM in a debug message. -* flashing firmware using `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink) is now supported ([#9964](https://github.com/qmk/qmk_firmware/pull/9964)) -* add ability to dump all makefile variables for the specified target ([#8256](https://github.com/qmk/qmk_firmware/pull/8256)) - * Adds a new subtarget to builds, `dump_vars`, which allows for printing out all the variables that make knows about, after all substitutions occur. - * Example: `make handwired/onekey/proton_c:default:dump_vars` -* add ability to change the Auto Shift timeout in real time ([#8441](https://github.com/qmk/qmk_firmware/pull/8441)) -* added a timer implementation for backlight on ChibiOS ([#8291](https://github.com/qmk/qmk_firmware/pull/8291)) -* added a third endpoint to V-USB keyboards ([#9020](https://github.com/qmk/qmk_firmware/pull/9020)) -* added a method to read the OLED display buffer from user space ([#8777](https://github.com/qmk/qmk_firmware/pull/8777)) -* K-Type refactor ([#9864](https://github.com/qmk/qmk_firmware/pull/9864)) - * The K-Type has been refactored to use QMK's native matrix scanning routine, and now has partial support for the RGB Matrix feature. -* Joysticks can now be used without defining analog pins ([#10169](https://github.com/qmk/qmk_firmware/pull/10169)) - -### Clean-ups and Optimizations :id=core-optimizations - -* iWRAP protocol removed ([#9284](https://github.com/qmk/qmk_firmware/pull/9284)) -* work begun for consolidation of ChibiOS platform files ([#8327](https://github.com/qmk/qmk_firmware/pull/8327) and [#9315](https://github.com/qmk/qmk_firmware/pull/9315)) - * Start of the consolidation work to move the ChibiOS board definitions as well as the default set of configuration files for existing board definitions used by keyboards. - * Uses `/platforms/chibios` as previously discussed on discord. - * Consolidates the Proton C configs into the generic F303 definitions. - * Allows for defining a default set of `chconf.h`, `halconf.h`, and `mcuconf.h` files within the platform definition, which is able to be overridden by the keyboard directly, though include path ordering. - * Adds template `chconf.h`, `halconf.h`, `mcuconf.h`, and `board.h` that can be dropped into a keyboard directory, in order to override rather than replace the entire contents of the respective files. - * Removed Proton C QMK board definitions, falling back to ChibiOS board definitions with QMK overrides. -* Various tidy-ups for USB descriptor code ([#9005](https://github.com/qmk/qmk_firmware/pull/9005)) - * Renamed `keyboard_led_stats` in lufa.c and ChibiOS usb_main.c to `keyboard_led_state`, as well as `vusb_keyboard_leds`, for consistency - * Formatted CDC and MIDI descriptors better - * Removed `ENDPOINT_CONFIG` macro, it seems pointless and removes the need for endpoint address defines in the middle of the endpoint numbering enum - * Fixed (possibly?) V-USB `GET_REPORT` request handling. Not sure about this one, but the existing code appears to always return an empty report - now `send_keyboard` sets this variable to the current report, matching what the LUFA code does. -* converted `CONSUMER2BLUEFRUIT()` and `CONSUMER2RN42()` macros to static inline functions ([#9055](https://github.com/qmk/qmk_firmware/pull/9055)) -* Additional cleanups for V-USB code ([#9310](https://github.com/qmk/qmk_firmware/pull/9310)) - * Removing the UART stuff entirely, now that we have Console support. Also fixing up various other things; switching some `debug()` calls to `dprintf()`, moved `raw_hid_report` out of the way so that we can implement the shared endpoint stuff. -* removed inclusion of `adafruit_ble.h` from `ssd1306.c` ([#9355](https://github.com/qmk/qmk_firmware/pull/9355)) -* `outputselect.c` is no longer compiled if Bluetooth is disabled ([#9356](https://github.com/qmk/qmk_firmware/pull/9356)) -* `analogRead()` deprecated in favor of `analogReadPin()` ([#9023](https://github.com/qmk/qmk_firmware/pull/9023)) -* forcibly disable NKRO on V-USB controllers ([#9054](https://github.com/qmk/qmk_firmware/pull/9054)) -* removed warning if running backlight on STM32F072 ([#10040](https://github.com/qmk/qmk_firmware/pull/10040)) -* removed unused CORTEX_VTOR_INIT rules.mk option ([#10053](https://github.com/qmk/qmk_firmware/pull/10053)) -* improved handling for enabling Link Time Optimization ([#9832](https://github.com/qmk/qmk_firmware/pull/9832)) -* streamline rules for supporting Kiibohd bootloader ([#10129](https://github.com/qmk/qmk_firmware/pull/10129)) -* Define `STM32_DMA_REQUIRED` when using DMA-based WS2812 driver on STM32 ([#10127](https://github.com/qmk/qmk_firmware/pull/10127)) -* fix DMA stream ID calculation in ws2812_pwm ([#10008](https://github.com/qmk/qmk_firmware/pull/10008)) -* remove support for Adafruit EZ Key Bluetooth controller ([#10103](https://github.com/qmk/qmk_firmware/pull/10103)) - - -## QMK Infrastructure and Internals :id=qmk-internals - -* Attempt to fix CI for non-master branches. ([#9308](https://github.com/qmk/qmk_firmware/pull/9308)) - * Actually fetch the branch we're attempting to compare against. -* Run `qmk cformat` on `develop` branch ([#9501](https://github.com/qmk/qmk_firmware/pull/9501)) -* minor refactor of Bluetooth API ([#9905](https://github.com/qmk/qmk_firmware/pull/9905)) diff --git a/docs/ChangeLog/20201128.md b/docs/ChangeLog/20201128.md deleted file mode 100644 index 444132029532..000000000000 --- a/docs/ChangeLog/20201128.md +++ /dev/null @@ -1,150 +0,0 @@ -# QMK Breaking Change - 2020 Nov 28 Changelog - -Four times a year QMK runs a process for merging Breaking Changes. A Breaking Change is any change which modifies how QMK behaves in a way that is incompatible or potentially dangerous. We limit these changes to 4 times per year so that users can have confidence that updating their QMK tree will not break their keymaps. - - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Relocated Keyboards :id=relocated-keyboards - -#### Reduce Helix keyboard build variation ([#8669](https://github.com/qmk/qmk_firmware/pull/8669)) - -The build commands for the Helix keyboard are: - -``` -make : -``` - -For ``, specify the one in the rightmost column of the table below, such as `helix`,` helix/pico`. - -| before Oct 17 2019 | Oct 17 2019 | Mar 10 2020 | Nov 28 2020 | -| ---------------------|-------------------------|-------------------------| ------------------------| -| helix/rev1 | helix/rev1 | helix/rev1 | helix/rev1 | -| helix/pico | helix/pico | helix/pico | helix/pico | -| | helix/pico/back | helix/pico/back | helix/pico/back | -| | helix/pico/under | helix/pico/under | helix/pico/under | -| | | helix/pico/sc | -- | -| | | helix/pico/sc/back | helix/pico/sc | -| | | helix/pico/sc/under | -- | -| helix/rev2 (=helix) | helix/rev2 (=helix) | helix/rev2 (=helix) | -- | -| | helix/rev2/back | helix/rev2/back | -- | -| | helix/rev2/back/oled | helix/rev2/back/oled | ( --> helix/rev2/back) | -| | helix/rev2/oled | helix/rev2/oled | helix/rev2 (=helix) | -| | helix/rev2/oled/back | helix/rev2/oled/back | helix/rev2/back | -| | helix/rev2/oled/under | helix/rev2/oled/under | helix/rev2/under | -| | | helix/rev2/sc | -- | -| | | helix/rev2/sc/back | -- | -| | | helix/rev2/sc/oled | -- | -| | | helix/rev2/sc/oledback | helix/rev2/sc | -| | | helix/rev2/sc/oledunder | -- | -| | | helix/rev2/sc/under | -- | -| | helix/rev2/under | helix/rev2/under | -- | -| | helix/rev2/under/oled | helix/rev2/under/oled | ( --> helix/rev2/under) | - -#### Update the Speedo firmware for v3.0 ([#10657](https://github.com/qmk/qmk_firmware/pull/10657)) - -The Speedo keyboard has moved to `cozykeys/speedo/v2` as the designer prepares to release the Speedo v3.0. - -| Previous Name | New Name | -| :------------ | :------------------------- | -| speedo | cozykeys/speedo/v2 | -| -- | cozykeys/speedo/v3 **new** | - -#### Maartenwut/Maarten name change to evyd13/Evy ([#10274](https://github.com/qmk/qmk_firmware/pull/10274)) - -Maartenwut has rebranded as @evyd13, and all released Maartenwut boards have moved. - -| Previous Name | New Name | -| :--------------------- | :----------------- | -| maartenwut/atom47/rev2 | evyd13/atom47/rev2 | -| maartenwut/atom47/rev3 | evyd13/atom47/rev3 | -| maartenwut/eon40 | evyd13/eon40 | -| maartenwut/eon65 | evyd13/eon65 | -| maartenwut/eon75 | evyd13/eon75 | -| maartenwut/eon87 | evyd13/eon87 | -| maartenwut/eon95 | evyd13/eon95 | -| maartenwut/gh80_1800 | evyd13/gh80_1800 | -| maartenwut/gh80_3700 | evyd13/gh80_3700 | -| maartenwut/minitomic | evyd13/minitomic | -| maartenwut/mx5160 | evyd13/mx5160 | -| maartenwut/nt660 | evyd13/nt660 | -| maartenwut/omrontkl | evyd13/omrontkl | -| maartenwut/plain60 | evyd13/plain60 | -| maartenwut/pockettype | evyd13/pockettype | -| maartenwut/quackfire | evyd13/quackfire | -| maartenwut/solheim68 | evyd13/solheim68 | -| maartenwut/ta65 | evyd13/ta65 | -| maartenwut/wasdat | evyd13/wasdat | -| maartenwut/wasdat_code | evyd13/wasdat_code | -| maartenwut/wonderland | evyd13/wonderland | - -#### Xelus Valor and Dawn60 Refactors ([#10512](https://github.com/qmk/qmk_firmware/pull/10512), [#10584](https://github.com/qmk/qmk_firmware/pull/10584)) - -The Valor and Dawn60 keyboards by Xelus22 both now require their revisions to be specified when compiling. - -| Previous Name | New Name | -| :------------ | :---------------- | -| xelus/dawn60 | xelus/dawn60/rev1 | -| xelus/valor | xelus/valor/rev1 | - - -### Updated Keyboard Codebases :id=keyboard-updates - -#### AEboards EXT65 Refactor ([#10820](https://github.com/qmk/qmk_firmware/pull/10820)) - -The EXT65 codebase has been reworked so keymaps can be used with either revision. - - -## Core Changes :id=core-changes - -### Fixes :id=core-fixes - -* Reconnect the USB if users wake up a computer from the keyboard to restore the USB state ([#10088](https://github.com/qmk/qmk_firmware/pull/10088)) -* Fix cursor position bug in oled_write_raw functions ([#10800](https://github.com/qmk/qmk_firmware/pull/10800)) - -### Additions and Enhancements :id=core-additions - -* Allow MATRIX_ROWS to be greater than 32 ([#10183](https://github.com/qmk/qmk_firmware/pull/10183)) -* Add support for soft serial to ATmega32U2 ([#10204](https://github.com/qmk/qmk_firmware/pull/10204)) -* Allow direct control of MIDI velocity value ([#9940](https://github.com/qmk/qmk_firmware/pull/9940)) -* Joystick 16-bit support ([#10439](https://github.com/qmk/qmk_firmware/pull/10439)) -* Allow encoder resolutions to be set per encoder ([#10259](https://github.com/qmk/qmk_firmware/pull/10259)) -* Share button state from mousekey to pointing_device ([#10179](https://github.com/qmk/qmk_firmware/pull/10179)) -* Add advanced/efficient RGB Matrix Indicators ([#8564](https://github.com/qmk/qmk_firmware/pull/8564)) -* OLED display update interval support ([#10388](https://github.com/qmk/qmk_firmware/pull/10388)) -* Per-Key Retro Tapping ([#10622](https://github.com/qmk/qmk_firmware/pull/10622)) -* Allow backlight duty cycle limit ([#10260](https://github.com/qmk/qmk_firmware/pull/10260)) -* Add step sequencer feature ([#9703](https://github.com/qmk/qmk_firmware/pull/9703)) -* Added `add_oneshot_mods` & `del_oneshot_mods` ([#10549](https://github.com/qmk/qmk_firmware/pull/10549)) -* Add AT90USB support for serial.c ([#10706](https://github.com/qmk/qmk_firmware/pull/10706)) -* Auto shift: support repeats and early registration (#9826) - -### Clean-ups and Optimizations :id=core-optimizations - -* Haptic and solenoid cleanup ([#9700](https://github.com/qmk/qmk_firmware/pull/9700)) -* XD75 cleanup ([#10524](https://github.com/qmk/qmk_firmware/pull/10524)) -* Minor change to behavior allowing display updates to continue between task ticks ([#10750](https://github.com/qmk/qmk_firmware/pull/10750)) -* Change some GPIO manipulations in matrix.c to be atomic ([#10491](https://github.com/qmk/qmk_firmware/pull/10491)) -* combine repeated lines of code for ATmega32U2, ATmega16U2, ATmega328 and ATmega328P ([#10837](https://github.com/qmk/qmk_firmware/pull/10837)) -* Remove references to HD44780 ([#10735](https://github.com/qmk/qmk_firmware/pull/10735)) - - -## QMK Infrastructure and Internals :id=qmk-internals - -* Add ability to build a subset of all keyboards based on platform. ([#10420](https://github.com/qmk/qmk_firmware/pull/10420)) -* Initialise EEPROM drivers at startup, instead of upon first execution ([#10438](https://github.com/qmk/qmk_firmware/pull/10438)) -* Make bootloader_jump weak for ChibiOS ([#10417](https://github.com/qmk/qmk_firmware/pull/10417)) -* Support for STM32 GPIOF,G,H,I,J,K ([#10206](https://github.com/qmk/qmk_firmware/pull/10206)) -* Add milc as a dependency and remove the installed milc ([#10563](https://github.com/qmk/qmk_firmware/pull/10563)) -* ChibiOS upgrade: early init conversions ([#10214](https://github.com/qmk/qmk_firmware/pull/10214)) -* ChibiOS upgrade: configuration file migrator ([#9952](https://github.com/qmk/qmk_firmware/pull/9952)) -* Add definition based on currently-selected serial driver. ([#10716](https://github.com/qmk/qmk_firmware/pull/10716)) -* Allow for modification of output RGB values when using rgblight/rgb_matrix. ([#10638](https://github.com/qmk/qmk_firmware/pull/10638)) -* Allow keyboards/keymaps to execute code at each main loop iteration ([#10530](https://github.com/qmk/qmk_firmware/pull/10530)) -* qmk cformat ([#10767](https://github.com/qmk/qmk_firmware/pull/10767)) -* Add a Make variable to easily enable DEBUG_MATRIX_SCAN_RATE on the command line ([#10824](https://github.com/qmk/qmk_firmware/pull/10824)) -* update Chibios OS USB for the OTG driver ([#8893](https://github.com/qmk/qmk_firmware/pull/8893)) -* Fixup version.h writing when using `SKIP_VERSION=yes` ([#10972](https://github.com/qmk/qmk_firmware/pull/10972), [#10974](https://github.com/qmk/qmk_firmware/pull/10974)) -* Rename ledmatrix.h to match .c file ([#7949](https://github.com/qmk/qmk_firmware/pull/7949)) -* Split RGB_MATRIX_ENABLE into _ENABLE and _DRIVER ([#10231](https://github.com/qmk/qmk_firmware/pull/10231)) -* Split LED_MATRIX_ENABLE into _ENABLE and _DRIVER ([#10840](https://github.com/qmk/qmk_firmware/pull/10840)) diff --git a/docs/ChangeLog/20210227.md b/docs/ChangeLog/20210227.md deleted file mode 100644 index cb34edfd913a..000000000000 --- a/docs/ChangeLog/20210227.md +++ /dev/null @@ -1,169 +0,0 @@ -# QMK Breaking Changes - 2021 February 27 Changelog - -## Changes Requiring User Action - -The following keyboards have had their source moved within QMK: - -Old Keyboard Name | New Keyboard Name -:---------------- | :---------------- -bear_65 | jacky_studio/bear_65 -s7_elephant/rev1 | jacky_studio/s7_elephant/rev1 -s7_elephant/rev2 | jacky_studio/s7_elephant/rev2 -aplx6 | aplyard/aplx6/rev1 -southpaw75 | fr4/southpaw75 - -The [Aplyard Aplx6 rev2](https://github.com/qmk/qmk_firmware/tree/0.12.0/keyboards/aplyard/aplx6/rev1) and the [FR4Boards Unix60](https://github.com/qmk/qmk_firmware/tree/0.12.0/keyboards/fr4/unix60) have also been added as part of these changes. - -Additionally, the `handwired/bluepill/bluepill70` keyboard has been removed. - -## Core Changes - -### ChibiOS Update and Config Migration - -QMK's ChibiOS and ChibiOS-Contrib submodules have been updated to version 20.3.2. - -Along with this, QMK now provides default configuration files for all commonly-supported ARM microcontrollers running on ChibiOS. As such, keyboards are now only required to define settings which differ from the defaults, thereby reducing the size of pull requests for keyboards running atop ChibiOS. - -### QMK Infrastructure and Internals - -Python is now required to build QMK. The minimum Python version has been increased to 3.7. - -The power of `info.json` has been massively expanded. Most keyboard parameters can now be expressed in `info.json` instead of `config.h`/`rules.mk`. This should make maintaining keyboards easier, and will enable tooling that can allow non-technical users to add and maintain QMK keyboards without writing any code. - -To ease migration a new command has been provided, `qmk generate-info-json -kb `. You can use this command to generate a complete `info.json` file for a keyboard and then remove the duplicate information from `config.h` and `rules.mk`. - -Detailed example showing how to generate a new info.json and identify duplicate keys: - -``` -user@hostname:~/qmk_firmware/keyboards/lets_split:0$ qmk generate-info-json > new-info.json -user@hostname:~/qmk_firmware/keyboards/lets_split:0$ mv new-info.json info.json -user@hostname:~/qmk_firmware/keyboards/lets_split:0$ qmk info -⚠ lets_split/rev2: DEBOUNCE in config.h is overwriting debounce in info.json -⚠ lets_split/rev2: DEVICE_VER in config.h is overwriting usb.device_ver in info.json -⚠ lets_split/rev2: DIODE_DIRECTION in config.h is overwriting diode_direction in info.json -⚠ lets_split/rev2: MANUFACTURER in config.h is overwriting manufacturer in info.json -⚠ lets_split/rev2: RGB_DI_PIN in config.h is overwriting rgblight.pin in info.json -⚠ lets_split/rev2: RGBLED_NUM in config.h is overwriting rgblight.led_count in info.json -⚠ lets_split/rev2: PRODUCT_ID in config.h is overwriting usb.pid in info.json -⚠ lets_split/rev2: VENDOR_ID in config.h is overwriting usb.vid in info.json -⚠ lets_split/rev2: Matrix pins are specified in both info.json and config.h, the config.h values win. -⚠ lets_split/rev2: LAYOUTS in rules.mk is overwriting community_layouts in info.json -⚠ lets_split/rev2: Feature bootmagic is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature mousekey is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature extrakey is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature console is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature command is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature nkro is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature backlight is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature midi is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature audio is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature unicode is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature bluetooth is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature rgblight is specified in both info.json and rules.mk, the rules.mk value wins. -⚠ lets_split/rev2: Feature sleep_led is specified in both info.json and rules.mk, the rules.mk value wins. -Keyboard Name: Let's Split -Manufacturer: Wootpatoot -Website: -Maintainer: QMK Community -Keyboard Folder: lets_split/rev2 -Layouts: LAYOUT, LAYOUT_ortho_4x12 -Size: 13 x 4 -Processor: atmega32u4 -Bootloader: caterina -``` - -## Detailed Change List - -### Changes Requiring User Action - -* Refactor Jacky's boards (Bear65 and S7 Elephant) ([#10528](https://github.com/qmk/qmk_firmware/pull/10528), [#11981](https://github.com/qmk/qmk_firmware/pull/11981)) -* Remove handwired/bluepill ([#11415](https://github.com/qmk/qmk_firmware/pull/11415)) -* Aplyard Aplx6 Added rev2 & move rev1+rev2 to parent folder ([#10973](https://github.com/qmk/qmk_firmware/pull/10973)) -* added `unix60`, moved together with `southpaw75` into `fr4` folder ([#11195](https://github.com/qmk/qmk_firmware/pull/11195)) - -### Fixes - -* GCC 10 can now compile Drop Alt firmware ([#9485](https://github.com/qmk/qmk_firmware/pull/9485)) -* Fix compiling on `develop` branch ([#11409](https://github.com/qmk/qmk_firmware/pull/11409)) -* Fix broken keyboards and keymaps ([#11412](https://github.com/qmk/qmk_firmware/pull/11412), [#11427](https://github.com/qmk/qmk_firmware/pull/11427), [#11448](https://github.com/qmk/qmk_firmware/pull/11448), [#11447](https://github.com/qmk/qmk_firmware/pull/11447), [#11473](https://github.com/qmk/qmk_firmware/pull/11473), [#11584](https://github.com/qmk/qmk_firmware/pull/11584), [#11600](https://github.com/qmk/qmk_firmware/pull/11600)) -* Fixed up build dependencies so that generated files are made available before compiling any object files ([#11435](https://github.com/qmk/qmk_firmware/pull/11435)) -* Formatting fixes ([`378edd9`](https://github.com/qmk/qmk_firmware/commit/378edd9491f2ab0d3d8a970c9a8e64bc03ca15cf), [#11594](https://github.com/qmk/qmk_firmware/pull/11594), [`27749e1`](https://github.com/qmk/qmk_firmware/commit/27749e1c967c02c05e62a89a0ae2776dd7e5158c)) -* Include `stdbool.h` in `uart.h` to fix compiler errors ([#11728](https://github.com/qmk/qmk_firmware/pull/11728)) -* Decouple USB events from the USB interrupt handler in ChibiOS ([#10437](https://github.com/qmk/qmk_firmware/pull/10437)) - * Fixes an issue while using Backlight and External EEPROM at the same time that would cause the MCU to lock up. -* Address wake from sleep instability ([#11450](https://github.com/qmk/qmk_firmware/pull/11450)) -* Fix pressing media key on a momentarily activated layer may lead to missing key up events ([#11162](https://github.com/qmk/qmk_firmware/pull/11162)) -* Fix an RGB initialisation bug on Massdrop keyboards ([#12022](https://github.com/qmk/qmk_firmware/pull/12022)) -* Fix file encoding errors on Windows, and layouts not correctly merging into info.json ([#12039](https://github.com/qmk/qmk_firmware/pull/12039)) - -### Additions and Enhancements - -* Allow configuration of serial USART timeout ([#11057](https://github.com/qmk/qmk_firmware/pull/11057)) -* Added Sync Timer feature for Split Common keyboards ([#10997](https://github.com/qmk/qmk_firmware/pull/10997)) -* Add modifier state to the Split Common transport ([#10400](https://github.com/qmk/qmk_firmware/pull/10400)) -* Add Pix keyboard by sendz (`sendyyeah/pix`) ([#11154](https://github.com/qmk/qmk_firmware/pull/11154)) -* Implement option for kinetic mouse movement algorithm for mouse keys ([#6739](https://github.com/qmk/qmk_firmware/pull/6739)) -* Improved Language Specific Keycodes for US International and Extended Layouts ([#11307](https://github.com/qmk/qmk_firmware/pull/11307)) -* Modified `QWIIC_ENABLE` in `rules.mk` to be yes/no choice, adding `QWIIC_DRIVERS` to allow for inclusion of specific drivers ([#11426](https://github.com/qmk/qmk_firmware/pull/11426)) -* Allow AVR-based keyboards to override the `bootloader_jump` function ([#11418](https://github.com/qmk/qmk_firmware/pull/11418)) -* Refine RGBLight Twinkle effect to be smoother (use breathing curve) ([#11350](https://github.com/qmk/qmk_firmware/pull/11350)) -* Keep track of last matrix activity ([#10730](https://github.com/qmk/qmk_firmware/pull/10730), [`ab375d3`](https://github.com/qmk/qmk_firmware/commit/ab375d3d075c105f09a1ddd0e155f178225518bc), [#11552](https://github.com/qmk/qmk_firmware/pull/11552)) -* fix `matrix_io_delay()` timing in `quantum/matrix.c` ([#9603](https://github.com/qmk/qmk_firmware/pull/9603)) -* Keep track of encoder activity ([#11595](https://github.com/qmk/qmk_firmware/pull/11595)) -* Backport ChibiOS Audio changes from ZSA ([#11687](https://github.com/qmk/qmk_firmware/pull/11687)) -* Add support for 8 buttons to mouse report ([#10807](https://github.com/qmk/qmk_firmware/pull/10807)) -* Allow `post_config.h` to be implemented in userspace ([#11519](https://github.com/qmk/qmk_firmware/pull/11519)) -* Adds AT90USB162 support ([#11570](https://github.com/qmk/qmk_firmware/pull/11570)) -* Stop sounds when suspended ([#11553](https://github.com/qmk/qmk_firmware/pull/11553)) -* Revamp spidey3 userspace and keymaps ([#11768](https://github.com/qmk/qmk_firmware/pull/11768)) -* Add support for analog USBPD on STM32G4xx ([#11824](https://github.com/qmk/qmk_firmware/pull/11824)) -* Master matrix can now be transported to the slave side in Split Common keyboards ([#11046](https://github.com/qmk/qmk_firmware/pull/11046)) -* RGBLight: Allow configurable default settings ([#11912](https://github.com/qmk/qmk_firmware/pull/11912)) -* Add `tap_code_delay(code, delay)` ([#11913](https://github.com/qmk/qmk_firmware/pull/11913), [#11938](https://github.com/qmk/qmk_firmware/pull/11938)) - -### Clean-ups and Optimizations - -* Fix duplicate `I2C_KEYMAP_START` define ([#11237](https://github.com/qmk/qmk_firmware/pull/11237)) -* Rewrite APA102 support for RGBLight ([#10894](https://github.com/qmk/qmk_firmware/pull/10894)) -* Update ADB Protocol implementation in TMK Core ([#11168](https://github.com/qmk/qmk_firmware/pull/11168)) -* Remove unused `action_get_macro()` usages in user files ([#11165](https://github.com/qmk/qmk_firmware/pull/11165)) -* Remove `QMK_KEYBOARD_CONFIG_H` ([#11576](https://github.com/qmk/qmk_firmware/pull/11576)) -* Remove duplicated housekeeping in `arm_atsam` ([#11672](https://github.com/qmk/qmk_firmware/pull/11672)) -* UART driver refactor ([#11637](https://github.com/qmk/qmk_firmware/pull/11637)) -* Move `transport.c` to `QUANTUM_LIB_SRC` ([#11751](https://github.com/qmk/qmk_firmware/pull/11751)) -* Remove `MIDI_ENABLE_STRICT` from user keymaps ([#11750](https://github.com/qmk/qmk_firmware/pull/11750)) -* Remove legacy print backward compatiblitly ([#11805](https://github.com/qmk/qmk_firmware/pull/11805)) -* Migrate mousekey to quantum ([#11804](https://github.com/qmk/qmk_firmware/pull/11804)) -* remove deprecated `qmk json-keymap` ([#11823](https://github.com/qmk/qmk_firmware/pull/11823)) -* Remove FAUXCLICKY feature (deprecated) ([#11829](https://github.com/qmk/qmk_firmware/pull/11829)) -* Refactor platform logic within `print.h` ([#11863](https://github.com/qmk/qmk_firmware/pull/11863)) -* Audio system overhaul ([#11820](https://github.com/qmk/qmk_firmware/pull/11820)) -* Output selection: Remove "USB and BT" option for Bluetooth ([#11940](https://github.com/qmk/qmk_firmware/pull/11940)) -* `tmk_core/common/action.c`: refactor for code size; merge multiple `case`s into one ([#11943](https://github.com/qmk/qmk_firmware/pull/11943)) -* Remove rules and settings from user keymaps that are already defined at keyboard level ([#11966](https://github.com/qmk/qmk_firmware/pull/11966)) - -### QMK Infrastructure and Internals - -* bump to python 3.7 ([#11408](https://github.com/qmk/qmk_firmware/pull/11408)) -* `develop` branch is now formatted as part of CI tasks ([#11893](https://github.com/qmk/qmk_firmware/pull/11893), [#11905](https://github.com/qmk/qmk_firmware/pull/11905), [#11907](https://github.com/qmk/qmk_firmware/pull/11907), [#11928](https://github.com/qmk/qmk_firmware/pull/11928), [#11936](https://github.com/qmk/qmk_firmware/pull/11936)) -* Configure keyboard matrix from info.json ([#10817](https://github.com/qmk/qmk_firmware/pull/10817)) -* Validate our JSON data using json_schema ([#11101](https://github.com/qmk/qmk_firmware/pull/11101)) -* Use the schema to eliminate custom code ([#11108](https://github.com/qmk/qmk_firmware/pull/11108)) -* Add support for specifying BOARD in `info.json` ([#11492](https://github.com/qmk/qmk_firmware/pull/11492)) -* Document how to add data driven configurations ([#11502](https://github.com/qmk/qmk_firmware/pull/11502)) -* Process info.json rules ahead of userspace rules ([#11542](https://github.com/qmk/qmk_firmware/pull/11542)) -* Remove duplicate manufacturer definitions ([#11544](https://github.com/qmk/qmk_firmware/pull/11544)) -* Update list of MCUs in `keyboard.jsonschema` to mirror `qmk.constants.py` ([#11688](https://github.com/qmk/qmk_firmware/pull/11688)) -* Create a system to map between `info.json` and `config.h`/`rules.mk` ([#11548](https://github.com/qmk/qmk_firmware/pull/11548)) -* Make LAYOUT parsing more robust ([#12000](https://github.com/qmk/qmk_firmware/pull/12000)) - - -### ChibiOS Update and Config Migration - -* Add board specific to Proton-C, with usual defaults turned on to match Pro-Micro ([#10976](https://github.com/qmk/qmk_firmware/pull/10976)) -* Disable almost all ChibiOS subsystems in default configs ([#11111](https://github.com/qmk/qmk_firmware/pull/11111)) -* Config Migrations ([#10418](https://github.com/qmk/qmk_firmware/pull/10418), [#11123](https://github.com/qmk/qmk_firmware/pull/11123), [#11261](https://github.com/qmk/qmk_firmware/pull/11261), [#11413](https://github.com/qmk/qmk_firmware/pull/11413), [#11414](https://github.com/qmk/qmk_firmware/pull/11414), [#11495](https://github.com/qmk/qmk_firmware/pull/11495), [#11504](https://github.com/qmk/qmk_firmware/pull/11504), [#11529](https://github.com/qmk/qmk_firmware/pull/11529), [#11588](https://github.com/qmk/qmk_firmware/pull/11588), [#11598](https://github.com/qmk/qmk_firmware/pull/11598), [#11607](https://github.com/qmk/qmk_firmware/pull/11607), [#11617](https://github.com/qmk/qmk_firmware/pull/11617), [#11620](https://github.com/qmk/qmk_firmware/pull/11620), [#11630](https://github.com/qmk/qmk_firmware/pull/11630), [#11646](https://github.com/qmk/qmk_firmware/pull/11646), [#11689](https://github.com/qmk/qmk_firmware/pull/11689), [#11846](https://github.com/qmk/qmk_firmware/pull/11846), [#11927](https://github.com/qmk/qmk_firmware/pull/11927), [#12001](https://github.com/qmk/qmk_firmware/pull/12001)) -* Disable subsystems repo-wide ([#11449](https://github.com/qmk/qmk_firmware/pull/11449)) -* Leftover early initialisation conversions ([#11615](https://github.com/qmk/qmk_firmware/pull/11615)) -* Fix up comments showing how to execute config migration ([#11621](https://github.com/qmk/qmk_firmware/pull/11621)) -* Add STM32G431 and STM32G474 board definitions ([#11793](https://github.com/qmk/qmk_firmware/pull/11793)) diff --git a/docs/ChangeLog/20210529.md b/docs/ChangeLog/20210529.md deleted file mode 100644 index 2feeed64376c..000000000000 --- a/docs/ChangeLog/20210529.md +++ /dev/null @@ -1,227 +0,0 @@ -# QMK Breaking Changes - 2021 May 29 Changelog - -## Notable Changes :id=notable-changes - -### RGB Matrix support for split common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) :id=rgb-matrix-split-common - -Split boards can now use RGB Matrix without defining a custom matrix. - -### Teensy 3.6 support ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) :id=teensy-3-6-support - -Added support for MK66F18 (Teensy 3.6) microcontroller. - -### New command: qmk console ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) :id=new-command-qmk-console - -A new `qmk console` command has been added for attaching to your keyboard's console. It operates similiarly to QMK Toolbox by allowing you to connect to one or more keyboard consoles to display debugging messages. - -### Improved command: qmk config :id=improve-command-qmk-config - -We've updated the `qmk config` command to show only the configuration items you have actually set. You can now display (almost) all of the available configuration options, along with their default values, using `qmk config -a`. - -### LED Matrix Improvements ([#12509](https://github.com/qmk/qmk_firmware/pull/12509), [#12580](https://github.com/qmk/qmk_firmware/pull/12580), [#12588](https://github.com/qmk/qmk_firmware/pull/12588), [#12633](https://github.com/qmk/qmk_firmware/pull/12633), [#12651](https://github.com/qmk/qmk_firmware/pull/12651), [#12685](https://github.com/qmk/qmk_firmware/pull/12685)) :id=led-matrix-improvements - -LED Matrix has been improved with effects, CIE1931 curves, and a task system. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -* Durgod keyboard refactor in preparation for adding additional durgod keyboards ([#11978](https://github.com/qmk/qmk_firmware/pull/11978)) -* Updated Function96 with V2 files and removed chconf.h and halconf.h ([#12613](https://github.com/qmk/qmk_firmware/pull/12613)) -* [Keyboard] updated a vendor name / fixed minor keymap issues ([#12881](https://github.com/qmk/qmk_firmware/pull/12881)) -* [Keyboard] Corne - Remove legacy revision support ([#12226](https://github.com/qmk/qmk_firmware/pull/12226)) - -The following keyboards have had their source moved within QMK: - -Old Keyboard Name | New Keyboard Name -:---------------- | :---------------- -crkbd/rev1/common | crkbd/rev1 -function96 | function96/v1 -nckiibs/flatbread60 | delikeeb/flatbread60 -nckiibs/vaguettelite | delikeeb/vaguettelite -nckiibs/vanana/rev1 | delikeeb/vanana/rev1 -nckiibs/vanana/rev2 | delikeeb/vanana/rev2 -nckiibs/vaneela | delikeeb/vaneela -nckiibs/vaneelaex | delikeeb/vaneelaex -nckiibs/waaffle/rev3/elite_c | delikeeb/waaffle/rev3/elite_c -nckiibs/waaffle/rev3/pro_micro | delikeeb/waaffle/rev3/pro_micro - -The [Function96 V2](https://github.com/qmk/qmk_firmware/tree/0.13.0/keyboards/function96/v2) has also been added as part of these changes. - -The codebase for the [Durgod K320](https://github.com/qmk/qmk_firmware/tree/0.13.0/keyboards/durgod/k320) has been reworked in anticipation of additional Durgod keyboards gaining QMK support. - -Additionally, the `crkbd/rev1/legacy` keyboard has been removed. - -### Bootmagic Deprecation and Refactor ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) :id=bootmagic-deprecation-and-refactor - -QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. - -This pull request changes the behavior of `BOOTMAGIC_ENABLE` such that specifying `BOOTMAGIC_ENABLE = yes` enables Bootmagic Lite instead of full Bootmagic. - -If attempts to use Bootmagic functionality result in unexpected behavior, check your `rules.mk` file and change the `BOOTMAGIC_ENABLE` setting to specify either `lite` or `full`. - -#### Tentative Deprecation Schedule - -This is the current planned roadmap for the behavior of `BOOTMAGIC_ENABLE`: - -- From 2021 May 29, setting `BOOTMAGIC_ENABLE = yes` will enable Bootmagic Lite instead of full Bootmagic. -- From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. -- From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - -### Removal of LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) :id=removal-of-layout-kc - -We've removed support for `LAYOUT_kc` macros, if your keymap uses one you will need to update it use a regular `LAYOUT` macro. - -### Encoder callbacks are now boolean ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) :id=encoder-callback-boolean - -To allow for keyboards to override (or not) keymap level code the `encoder_update_kb` function has been changed from `void` to `bool`. You will need to update your function definition to reflect this and ensure that you return a `true` or `false` value. - -Example code before change: - -```c -void encoder_update_kb(uint8_t index, bool clockwise) { - encoder_update_user(index, clockwise); -} - -void encoder_update_user(uint8_t index, bool clockwise) { - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } else if (index == 1) { /* Second encoder */ - if (clockwise) { - tap_code(KC_DOWN); - } else { - tap_code(KC_UP); - } - } -} -``` - -Example code after change: - -```c -bool encoder_update_kb(uint8_t index, bool clockwise) { - return encoder_update_user(index, clockwise); -} - -bool encoder_update_user(uint8_t index, bool clockwise) { - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } else if (index == 1) { /* Second encoder */ - if (clockwise) { - tap_code(KC_DOWN); - } else { - tap_code(KC_UP); - } - } - return true; - // If you return true, this will allow the keyboard level code to run, as well. - //Returning false will override the keyboard level code. Depending on how the keyboard level function is set up. -} -``` - -## Core Changes :id=core-changes - -### Fixes :id=core-fixes - -* Fix connection issue in split keyboards when slave and OLED display are connected via I2C (fixes #9335) ([#11487](https://github.com/qmk/qmk_firmware/pull/11487)) -* Terrazzo: Fix wrong LED Matrix function names ([#12561](https://github.com/qmk/qmk_firmware/pull/12561)) -* Apply the "NO_LIMITED_CONTROLLER_CONNECT" fix to atmega16u2 ([#12482](https://github.com/qmk/qmk_firmware/pull/12482)) -* Fix comment parsing ([#12750](https://github.com/qmk/qmk_firmware/pull/12750)) -* Turn OLED off on suspend in soundmonster Corne keymap ([#10419](https://github.com/qmk/qmk_firmware/pull/10419)) -* Fixup build errors on `develop` branch. ([#12723](https://github.com/qmk/qmk_firmware/pull/12723)) -* Fix syntax error when compiling for ARM ([#12866](https://github.com/qmk/qmk_firmware/pull/12866)) -* Add missing LED Matrix suspend code to suspend.c ([#12878](https://github.com/qmk/qmk_firmware/pull/12878)) -* Fix spelling mistake regarding LED Matrix in split_common. ([#12888](https://github.com/qmk/qmk_firmware/pull/12888)) -* [Keymap] Fix QWERTY/DVORAK status output for kzar keymap ([#12895](https://github.com/qmk/qmk_firmware/pull/12895)) -* Fixup housekeeping from being invoked twice per loop. ([#12933](https://github.com/qmk/qmk_firmware/pull/12933)) -* wait for matrix row signal to go HIGH for every row ([#12945](https://github.com/qmk/qmk_firmware/pull/12945)) -* ensure we do not conflict with existing keymap aliases ([#12976](https://github.com/qmk/qmk_firmware/pull/12976)) -* [Keyboard] Fix Terrazzo build failure ([#12977](https://github.com/qmk/qmk_firmware/pull/12977)) -* Do not hard set config in CPTC files ([#11864](https://github.com/qmk/qmk_firmware/pull/11864)) - -### Additions and Enhancements :id=core-additions - -* ARM - Refactor SLEEP_LED to support more platforms ([#8403](https://github.com/qmk/qmk_firmware/pull/8403)) -* Add ability to toggle One Shot functionality ([#4198](https://github.com/qmk/qmk_firmware/pull/4198)) -* Add RGB Matrix support to Split Common ([#11055](https://github.com/qmk/qmk_firmware/pull/11055)) -* Add support for complementary outputs to the ChibiOS WS2812 PWM driver ([#11988](https://github.com/qmk/qmk_firmware/pull/11988)) -* Enable RGB Matrix for Corne ([#12091](https://github.com/qmk/qmk_firmware/pull/12091)) -* Set default OLED Update Interval for Split Keyboards to improve matrix scan performance ([#12107](https://github.com/qmk/qmk_firmware/pull/12107)) -* Add support for MK66F18 (Teensy 3.6) micro controller ([#12258](https://github.com/qmk/qmk_firmware/pull/12258)) -* Split RGB Matrix support for RGBKB Zygomorph ([#11083](https://github.com/qmk/qmk_firmware/pull/11083)) -* Add baudrate and circular buffer to ARM WS2812 SPI config ([#12216](https://github.com/qmk/qmk_firmware/pull/12216)) -* Add keyboard level weak function for slave matrix scan ([#12317](https://github.com/qmk/qmk_firmware/pull/12317)) -* Add link to schematic on EasyEDA for XD60 ([#12018](https://github.com/qmk/qmk_firmware/pull/12018)) -* Add Config functions for LED Matrix ([#12361](https://github.com/qmk/qmk_firmware/pull/12361)) -* Add pin definitions for MK66F18 ([#12419](https://github.com/qmk/qmk_firmware/pull/12419)) -* add kinesis/kint36 keyboard ([#10171](https://github.com/qmk/qmk_firmware/pull/10171)) -* Add support for producing UF2-format binaries. ([#12435](https://github.com/qmk/qmk_firmware/pull/12435)) -* Implement CIE1931 curve for LED Matrix ([#12417](https://github.com/qmk/qmk_firmware/pull/12417)) -* Change `BOOTMAGIC_ENABLE=yes` to use Bootmagic Lite ([#12172](https://github.com/qmk/qmk_firmware/pull/12172)) -* Add kzar keymap for Kinesis Advantage ([#12444](https://github.com/qmk/qmk_firmware/pull/12444)) -* LED Matrix: suspend code ([#12509](https://github.com/qmk/qmk_firmware/pull/12509)) -* LED Matrix: Task system ([#12580](https://github.com/qmk/qmk_firmware/pull/12580)) -* Add missing RGB_MODE_TWINKLE / RGB_M_TW keycodes ([#11935](https://github.com/qmk/qmk_firmware/pull/11935)) -* Enhancement of WPM feature ([#11727](https://github.com/qmk/qmk_firmware/pull/11727)) -* Add Per Key functionality for AutoShift ([#11536](https://github.com/qmk/qmk_firmware/pull/11536)) -* LED Matrix: Reactive effect buffers & advanced indicators ([#12588](https://github.com/qmk/qmk_firmware/pull/12588)) -* LED Matrix: support for Split keyboards ([#12633](https://github.com/qmk/qmk_firmware/pull/12633)) -* add setting to enable infinite timeout for leader key ([#6580](https://github.com/qmk/qmk_firmware/pull/6580), [#12721](https://github.com/qmk/qmk_firmware/pull/12721 "Fix bad PR merge for #6580")) -* Update ADC driver for STM32F1xx, STM32F3xx, STM32F4xx ([#12403](https://github.com/qmk/qmk_firmware/pull/12403)) -* Add initial support for tinyuf2 bootloader (when hosted on F411 blackpill) ([#12600](https://github.com/qmk/qmk_firmware/pull/12600)) -* Add support for STM32F446 MCU ([#12619](https://github.com/qmk/qmk_firmware/pull/12619)) -* Add STM32L433 and L443 support ([#12063](https://github.com/qmk/qmk_firmware/pull/12063)) -* Added OLED fade out support ([#12086](https://github.com/qmk/qmk_firmware/pull/12086)) -* New command: `qmk console` ([#12828](https://github.com/qmk/qmk_firmware/pull/12828)) -* LED Matrix: Effects! ([#12651](https://github.com/qmk/qmk_firmware/pull/12651)) -* Add setup, clone, and env to the list of commands we allow even with broken modules ([#12868](https://github.com/qmk/qmk_firmware/pull/12868)) -* LED Matrix: Documentation ([#12685](https://github.com/qmk/qmk_firmware/pull/12685)) -* Add function to allow repeated blinking of one layer ([#12237](https://github.com/qmk/qmk_firmware/pull/12237)) -* Add support for up to 4 IS31FL3733 drivers ([#12342](https://github.com/qmk/qmk_firmware/pull/12342)) -* Convert Encoder callbacks to be boolean functions ([#12805](https://github.com/qmk/qmk_firmware/pull/12805), [#12985](https://github.com/qmk/qmk_firmware/pull/12985)) -* [Keymap] Update to Drashna keymap and user code (based on develop) ([#12936](https://github.com/qmk/qmk_firmware/pull/12936)) -* Add Full-duplex serial driver for ARM boards ([#9842](https://github.com/qmk/qmk_firmware/pull/9842)) -* Document LED_MATRIX_FRAMEBUFFER_EFFECTS ([#12987](https://github.com/qmk/qmk_firmware/pull/12987)) -* Backlight: add defines for default level and breathing state ([#12560](https://github.com/qmk/qmk_firmware/pull/12560), [#13024](https://github.com/qmk/qmk_firmware/pull/13024)) -* Add dire message about LUFA mass storage bootloader ([#13014](https://github.com/qmk/qmk_firmware/pull/13014)) - -### Clean-ups and Optimizations :id=core-optimizations - -* Overhaul bootmagic logic to have single entrypoint ([#8532](https://github.com/qmk/qmk_firmware/pull/8532)) -* Refactor of USB code within split_common ([#11890](https://github.com/qmk/qmk_firmware/pull/11890)) -* Begin the process of deprecating `bin/qmk` in favor of the global CLI ([#12109](https://github.com/qmk/qmk_firmware/pull/12109)) -* LED Matrix: decouple from Backlight ([#12054](https://github.com/qmk/qmk_firmware/pull/12054)) -* Remove `FUNC()` ([#12161](https://github.com/qmk/qmk_firmware/pull/12161)) -* Move gpio wait logic to wait.h ([#12067](https://github.com/qmk/qmk_firmware/pull/12067)) -* LED Matrix: Clean up includes ([#12197](https://github.com/qmk/qmk_firmware/pull/12197)) -* Consistently use bin/qmk when that script is called ([#12286](https://github.com/qmk/qmk_firmware/pull/12286)) -* LED Matrix: Additional common_features.mk tweaks ([#12187](https://github.com/qmk/qmk_firmware/pull/12187)) -* LED Matrix: Fix up eeconfig code ([#12327](https://github.com/qmk/qmk_firmware/pull/12327)) -* Big quantum_keycodes cleanup ([#12249](https://github.com/qmk/qmk_firmware/pull/12249)) -* Fix up builds that are now too big for `develop` branch. ([#12495](https://github.com/qmk/qmk_firmware/pull/12495)) -* [Keyboard] kint36: switch to sym_eager_pk debouncing ([#12626](https://github.com/qmk/qmk_firmware/pull/12626)) -* [Keyboard] kint2pp: reduce input latency by ≈10ms ([#12625](https://github.com/qmk/qmk_firmware/pull/12625)) -* eeprom driver: Refactor where eeprom driver initialisation (and EEPROM emulation initialisation) occurs to make it non-target-specific. ([#12671](https://github.com/qmk/qmk_firmware/pull/12671)) -* Change RGB/LED Matrix to use a simple define for USB suspend ([#12697](https://github.com/qmk/qmk_firmware/pull/12697), [#12770](https://github.com/qmk/qmk_firmware/pull/12770 "Fixing transport's led/rgb matrix suspend state logic")) -* Remove pointless SERIAL_LINK_ENABLE rules ([#12846](https://github.com/qmk/qmk_firmware/pull/12846)) -* Make Swap Hands use PROGMEM ([#12284](https://github.com/qmk/qmk_firmware/pull/12284)) -* Remove KEYMAP and LAYOUT_kc ([#12160](https://github.com/qmk/qmk_firmware/pull/12160)) -* Rename `point_t` -> `led_point_t` ([#12864](https://github.com/qmk/qmk_firmware/pull/12864)) -* Deprecate `send_unicode_hex_string()` ([#12602](https://github.com/qmk/qmk_firmware/pull/12602)) -* [Keyboard] Remove redundant legacy and common headers for crkbd ([#13023](https://github.com/qmk/qmk_firmware/pull/13023)) - -### QMK Infrastructure and Internals :id=qmk-internals - -* trivial change to trigger api update ([`b15288fb87`](https://github.com/qmk/qmk_firmware/commit/b15288fb87)) -* fix some references to bin/qmk that slipped in ([#12832](https://github.com/qmk/qmk_firmware/pull/12832)) -* Resolve a number of warnings in `qmk generate-api` ([#12833](https://github.com/qmk/qmk_firmware/pull/12833)) -* Fix another bin/qmk reference ([#12856](https://github.com/qmk/qmk_firmware/pull/12856)) -* Use milc.subcommand.config instead of qmk.cli.config ([#12915](https://github.com/qmk/qmk_firmware/pull/12915)) diff --git a/docs/ChangeLog/20210828.md b/docs/ChangeLog/20210828.md deleted file mode 100644 index f96283e6ad48..000000000000 --- a/docs/ChangeLog/20210828.md +++ /dev/null @@ -1,557 +0,0 @@ -# QMK Breaking Changes - 2021 August 28 Changelog - -## Notable Features :id=notable-features - -### Combo processing improvements ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) :id=combo-processing-improvements - -Combo processing has been reordered with respect to keypress handling, allowing for much better compatibility with mod taps. - -It is also now possible to define combos that have keys overlapping with other combos, triggering only one. For example, a combo of `A`, `B` can coexist with a longer combo of `A`, `B`, `C` -- previous functionality would trigger both combos if all three keys were pressed. - -### Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) :id=key-overrides - -QMK now has a new feature: [key overrides](https://docs.qmk.fm/#/feature_key_overrides). This feature allows for overriding the output of key combinations involving modifiers. As an example, pressing Shift+2 normally results in an @ on US-ANSI keyboard layouts -- the new key overrides allow for adding similar functionality, but for any modifier + key press. - -To illustrate, it's now possible to use the key overrides feature to translate Shift + Backspace into Delete -- an often-requested example of where this functionality comes in handy. - -There's far more to describe that what lives in this changelog, so head over to the [key overrides documentation](https://docs.qmk.fm/#/feature_key_overrides) for more examples and info. - -### Digitizer support ([#12851](https://github.com/qmk/qmk_firmware/pull/12851)) - -QMK gained the ability to pretend to be a digitizer device -- much like a tablet device. A mouse uses delta-coordinates -- move up, move right -- but a digitizer works with absolute coordinates -- top left, bottom right. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -Old Keyboard Name | New Keyboard Name -------------------------------|--------------------------------------------------------- -aeboards/constellation | aeboards/constellation/rev1, aeboards/constellation/rev2 -bakeneko65 | bakeneko65/rev2, bakeneko65/rev3 -bm16a | kprepublic/bm16a -bm16s | kprepublic/bm16s -bm40hsrgb | kprepublic/bm40hsrgb -bm43a | kprepublic/bm43a -bm60poker | kprepublic/bm60poker -bm60rgb | kprepublic/bm60rgb -bm60rgb_iso | kprepublic/bm60rgb_iso -bm68rgb | kprepublic/bm68rgb -clawsome/gamebuddy | clawsome/gamebuddy/v1_0, clawsome/gamebuddy/v1_m -cospad | kprepublic/cospad -custommk/genesis | custommk/genesis/rev1, custommk/genesis/rev2 -daisy | ktec/daisy -durgod/k320 | durgod/k3x0/k320 -dztech/volcano660 | ilumkb/volcano660 -ergodone | ktec/ergodone -gmmk/pro | gmmk/pro/ansi, gmmk/pro/iso -handwired/p1800fl | team0110/p1800fl -jj40 | kprepublic/jj40 -jj4x4 | kprepublic/jj4x4 -jj50 | kprepublic/jj50 -kyria | splitkb/kyria -lazydesigners/the60 | lazydesigners/the60/rev1, lazydesigners/the60/rev2 -matrix/m12og | matrix/m12og/rev1, matrix/m12og/rev2 -mechlovin/hannah65/mechlovin9 | mechlovin/mechlovin9/rev1, mechlovin/mechlovin9/rev2 -peiorisboards/ixora | coarse/ixora -ramonimbao/mona | ramonimbao/mona/v1, ramonimbao/mona/v1_1 -staryu | ktec/staryu -tokyo60 | tokyokeyboard/tokyo60 -vinta | coarse/vinta -xd002 | xiudi/xd002 -xd004 | xiudi/xd004 -xd60 | xiudi/xd60 -xd68 | xiudi/xd68 -xd75 | xiudi/xd75 -xd84 | xiudi/xd84 -xd84pro | xiudi/xd84pro -xd87 | xiudi/xd87 -xd96 | xiudi/xd96 - -### Bootmagic Full Removal ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) :id=bootmagic-full-removal - -As noted during last breaking changes cycle, QMK has decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. - -This pull request changes the behavior of `BOOTMAGIC_ENABLE` such that specifying `full` results in an error, allowing only `no`, `yes`, or `lite`. - -Currently `lite` is the equivalent of `yes` in `rules.mk`. Next cycle the use of the `lite` keyword will be prevented in favour of `yes` -- any new submissions should now be using `yes` or `no` to minimise disruption. - -#### Bootmagic Full Deprecation Schedule - -This is the current roadmap for the behavior of `BOOTMAGIC_ENABLE`: - -- (done) From 2021 May 29, setting `BOOTMAGIC_ENABLE = yes` will enable Bootmagic Lite instead of full Bootmagic. -- (now) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. -- (next) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - -### DIP switch callbacks are now boolean ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) :id=dip-switch-boolean - -To match the encoder change last breaking changes cycle, DIP switch callbacks now return `bool`, too. - -Example code before change: - -```c -void dip_switch_update_kb(uint8_t index, bool active) { - dip_switch_update_user(index, active); -} - -void dip_switch_update_user(uint8_t index, bool active) { - switch (index) { - case 0: - if(active) { audio_on(); } else { audio_off(); } - break; - } -} - -void dip_switch_update_mask_kb(uint32_t state) { - dip_switch_update_mask_user(state); -} - -void dip_switch_update_mask_user(uint32_t state) { - if (state & (1UL<<0) && state & (1UL<<1)) { - layer_on(_ADJUST); // C on esc - } else { - layer_off(_ADJUST); - } -} -``` - -Example code after change: - -```c -bool dip_switch_update_kb(uint8_t index, bool active) { - if !(dip_switch_update_user(index, active)) { return false; } - return true; -} - -bool dip_switch_update_user(uint8_t index, bool active) { - switch (index) { - case 0: - if(active) { audio_on(); } else { audio_off(); } - break; - } - return true; // Returning true allows keyboard code to execute, false will tell the keyboard code "I've already handled it". -} - -bool dip_switch_update_mask_kb(uint32_t state) { - if (!dip_switch_update_mask_user(state)) { return false; } - return true; -} - -bool dip_switch_update_mask_user(uint32_t state) { - if (state & (1UL<<0) && state & (1UL<<1)) { - layer_on(_ADJUST); // C on esc - } else { - layer_off(_ADJUST); - } - return true; // Returning true allows keyboard code to execute, false will tell the keyboard code "I've already handled it". -} -``` - -## Notable core changes :id=notable-core - -### Split transport improvements :id=split-transport-improvements - -Split keyboards gained a significant amount of improvements during this breaking changes cycle, specifically: - -* Extensible split data sync ([#11930](https://github.com/qmk/qmk_firmware/pull/11930)) -- rewritten data sharing between sides, allowing for data transfer only when required, as well as enabling keyboards and keymaps to define their own shared data. -* Full-duplex ARM USART split ([#13081](https://github.com/qmk/qmk_firmware/pull/13081)) -- adds to the previous half-duplex driver and now allows for full-duplex support on ARM. -* Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -- allows the slave to be disconnected, enabling one-handed use. -* Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418)) - -!> If you're updating your split keyboard, you will need to flash both sides of the split with the your firmware. - -### Teensy 4.x support ([#13056](https://github.com/qmk/qmk_firmware/pull/13056), [#13076](https://github.com/qmk/qmk_firmware/pull/13076), [#13077](https://github.com/qmk/qmk_firmware/pull/13077)) :id=teensy-4-x-support - -Updated ChibiOS and ChibiOS-Contrib, which brought in support for Teensy 4.x dev boards, running NXP i.MX1062. - -### Data Driven Improvements ([#13366](https://github.com/qmk/qmk_firmware/pull/13366)) - -QMK's pursuit of data-driven keyboards has progressed, allowing substantially more configurable options to be specified in `info.json`. - -#### Tags - -Tags will let you categorize your keyboard, and will be used in the future to allow browsing and sorting through keyboards in QMK. Tags are free-form text identifiers that identify attributes about your keyboard. To add tags you simply add a `tags` key to your `info.json`: - - "tags": ["tkl", "backlight", "encoder"] - -#### Dot Notation - -With this release we are moving towards using JSON dot notation in more places. For example, when using `qmk info -f text`: - -``` -$ qmk info -f text -kb clueboard/card - bootloader: atmel-dfu - debounce: 20 - diode_direction: ROW2COL - features.audio: True - features.backlight: True - features.bluetooth: False - features.bootmagic: False - features.command: True - features.console: True - features.extrakey: True - features.lto: True - features.midi: False - features.mousekey: True - features.nkro: False - features.rgblight: True - features.unicode: False - height: 8 - keyboard_folder: clueboard/card - keyboard_name: Cluecard - layout_aliases.LAYOUT: LAYOUT_all - layouts: LAYOUT_all - maintainer: skullydazed - manufacturer: Clueboard - matrix_pins.cols: F1, F6, F7 - matrix_pins.rows: B4, F0, F4, F5 - platform: unknown - processor: atmega32u4 - processor_type: avr - protocol: LUFA - rgblight.brightness_steps: 17 - rgblight.hue_steps: 10 - rgblight.led_count: 4 - rgblight.pin: E6 - rgblight.saturation_steps: 17 - split.transport.protocol: serial - usb.device_ver: 0x0001 - usb.pid: 0x2330 - usb.vid: 0xC1ED - width: 10 -``` - -#### New configuration keys - -We've added dozens of new keys to `info.json` so that you can configure more than ever without writing a single line of code. A quick overview of the new items you can configure: - -* `audio.pins`, `audio.voices` -* `backlight.breathing`, `backlight.breathing_period`, `backlight.levels`, `backlight.pin`, -* `bluetooth.driver`, `bluetooth.lto` -* `bootloader_instructions` -* `build.debounce_type`, `build.firmware_format`, `build.lto` -* `combo.count`, `combo.term` -* `leader_key.timing`, `leader_key.strict_processing`, `leader_key.timeout` -* `matrix.custom`, `matrix.custom_lite`, `matrix.ghost`, `matrix.io_delay` -* `mouse_key.enabled`, `mouse_key.delay`, `mouse_key.interval`, `mouse_key.max_speed`, `mouse_key.time_to_max`, `mouse_key.wheel_delay` -* `oneshot.tap_toggle`, `oneshot.timeout` -* `rgblight.layers.blink`, `rgblight.layers.enabled`, `rgblight.layers.max`, `rgblight.layers.override_rgb`, `rgblight.rgbw` -* `split.enabled`, `split.matrix_grid`, `split.matrix_pins`, `split.main`, `split.soft_serial_pin`, `split.soft_serial_speed`, `split.transport.protocol`, `split.transport.sync_matrix_state`, `split.transport.sync_modifiers`, `split.usb_detect` -* `tapping.force_hold`, `tapping.force_hold_per_key`, `tapping.ignore_mod_tap_interrupt`, `tapping.ignore_mod_tap_interrupt_per_key`, `tapping.permissive_hold`, `tapping.permissive_hold_per_key`, `tapping.retro`, `tapping.retro_per_key`, `tapping.term`, `tapping.term_per_key`, `tapping.toggle` -* `usb.force_nkro`, `usb.max_power`, `usb.no_startup_check`, `usb.polling_interval`, `usb.shared_endpoint.keyboard`, `usb.shared_endpoint.mouse`, `usb.suspend_wakeup_delay`, `usb.wait_for` -* `qmk.keys_per_scan`, `qmk.tap_keycode_delay`, `qmk.tap_capslock_delay` - -### Codebase restructure and cleanup :id=codebase-restructure - -QMK was originally based on TMK, and has grown in size considerably since its first inception. To keep moving things forward, restructure of some of the core areas of the code is needed to support new concepts and new hardware, and progress is happening along those lines: - -* Move RGBLight code into its own folder ([#13312](https://github.com/qmk/qmk_firmware/pull/13312)) -* Migrate platform independent code from tmk_core -> quantum ([#13673](https://github.com/qmk/qmk_firmware/pull/13673)) -* matrix_scan_x -> x_task ([#13748](https://github.com/qmk/qmk_firmware/pull/13748)) -* Move some led drivers to common folder ([#13749](https://github.com/qmk/qmk_firmware/pull/13749)) -* Move chibios board files to allow tmk_core platform migration ([#13777](https://github.com/qmk/qmk_firmware/pull/13777)) -* Begin to carve out platform/protocol API - Single main loop ([#13843](https://github.com/qmk/qmk_firmware/pull/13843)) -* Relocate platform specific drivers ([#13894](https://github.com/qmk/qmk_firmware/pull/13894)) -* Move all the flash logic from tmk_core ([#13927](https://github.com/qmk/qmk_firmware/pull/13927)) -* Move USB Host Shield and Arduino core to `lib/` ([#13973](https://github.com/qmk/qmk_firmware/pull/13973)) -* Unify behaviour of wait on AVR ([#14025](https://github.com/qmk/qmk_firmware/pull/14025)) -* Move nix folder alongside vagrant ([#14132](https://github.com/qmk/qmk_firmware/pull/14132)) -* Align some quantum sub-directories ([#14134](https://github.com/qmk/qmk_firmware/pull/14134)) - ---- - -## Full changelist - -Core: -* Arm ps2 mouse interrupt ([#6490](https://github.com/qmk/qmk_firmware/pull/6490)) -* Process combos earlier & overlapping combos ([#8591](https://github.com/qmk/qmk_firmware/pull/8591)) -* Swap buttons on PS2 Mouse/Trackball ([#9205](https://github.com/qmk/qmk_firmware/pull/9205)) -* Add HOLD_ON_OTHER_KEY_PRESS option for dual-role keys ([#9404](https://github.com/qmk/qmk_firmware/pull/9404)) -* add yaml_build_options target ([#10533](https://github.com/qmk/qmk_firmware/pull/10533)) -* Warn when building a board that uses arm_atsam ([#10904](https://github.com/qmk/qmk_firmware/pull/10904)) -* Key Overrides ([#11422](https://github.com/qmk/qmk_firmware/pull/11422)) -* Refactor `quantum/command.{c,h}` for code size & {read,maintain}ability ([#11842](https://github.com/qmk/qmk_firmware/pull/11842)) -* Extensible split data sync ([#11930](https://github.com/qmk/qmk_firmware/pull/11930)) -* Move print/debug files to quantum ([#12069](https://github.com/qmk/qmk_firmware/pull/12069)) -* Unconditionally call led_init_ports ([#12116](https://github.com/qmk/qmk_firmware/pull/12116)) -* Support using a timer for wait_us() on ChibiOS-based boards ([#12211](https://github.com/qmk/qmk_firmware/pull/12211)) -* Add support for NO_PIN to all matrix types ([#12238](https://github.com/qmk/qmk_firmware/pull/12238)) -* Avoid 8-bit timer overflows in debounce algorithms ([#12240](https://github.com/qmk/qmk_firmware/pull/12240)) -* Add Per Key exclusions for Haptic Feedback ([#12386](https://github.com/qmk/qmk_firmware/pull/12386)) -* Steno combinedkeys ([#12538](https://github.com/qmk/qmk_firmware/pull/12538)) -* eeprom_stm32: implement high density wear leveling ([#12567](https://github.com/qmk/qmk_firmware/pull/12567)) -* eeprom_i2c driver: added EXTERNAL_EEPROM_WP_PIN configuration option. ([#12617](https://github.com/qmk/qmk_firmware/pull/12617)) -* Add CRC8 calculation subsystem to quantum ([#12641](https://github.com/qmk/qmk_firmware/pull/12641)) -* Limit saturation for RGB_MATRIX_JELLYBEAN_RAINDROPS ([#12669](https://github.com/qmk/qmk_firmware/pull/12669)) -* Add asym_eager_defer_pk debounce type ([#12689](https://github.com/qmk/qmk_firmware/pull/12689)) -* Include lib8tion.c into RGB/LED matrix build list ([#12699](https://github.com/qmk/qmk_firmware/pull/12699)) -* Add readPort() and some API to 'tmk_core/common/*/gpio.h' ([#12754](https://github.com/qmk/qmk_firmware/pull/12754)) -* add wait_cpuclock() macro for AVR and CPU_CLOCK macro ([#12755](https://github.com/qmk/qmk_firmware/pull/12755)) -* Trigger a wakeup after USB Reset on ChibiOS. ([#12831](https://github.com/qmk/qmk_firmware/pull/12831)) -* Add sync_timer support over serial_link (i.e. Ergodox Infinity) ([#12845](https://github.com/qmk/qmk_firmware/pull/12845)) -* Digitizer HID interface : absolute coordinates for mouse cursor ([#12851](https://github.com/qmk/qmk_firmware/pull/12851)) -* Add config.h and rules.mk support for data driven keymaps ([#12859](https://github.com/qmk/qmk_firmware/pull/12859)) -* Add alternate ldscript for STM32duino (F103xB) ([#12914](https://github.com/qmk/qmk_firmware/pull/12914)) -* `keymap_extras`: Remove deprecated defines ([#12949](https://github.com/qmk/qmk_firmware/pull/12949)) -* Retain brightness with lighting layers ([#13025](https://github.com/qmk/qmk_firmware/pull/13025)) -* Move optical sensor code to drivers folder ([#13044](https://github.com/qmk/qmk_firmware/pull/13044)) -* Change the prototype of matrix_output_unselect_delay() ([#13045](https://github.com/qmk/qmk_firmware/pull/13045)) -* Add weak refs on reading rows/cols. ([#13062](https://github.com/qmk/qmk_firmware/pull/13062)) -* Use single memcmp to determine if matrix changed. ([#13064](https://github.com/qmk/qmk_firmware/pull/13064)) -* Improve layer mask handling ([#13065](https://github.com/qmk/qmk_firmware/pull/13065)) -* mousekey: expose current report to users ([#13069](https://github.com/qmk/qmk_firmware/pull/13069)) -* ChibiOS SVN mirror script. ([#13070](https://github.com/qmk/qmk_firmware/pull/13070)) -* Added right vs left specific pin assignments for dip switch ([#13074](https://github.com/qmk/qmk_firmware/pull/13074)) -* make RESET key work with Teensy 4.x ([#13076](https://github.com/qmk/qmk_firmware/pull/13076)) -* wire up flash make target for Teensy 4.x ([#13077](https://github.com/qmk/qmk_firmware/pull/13077)) -* bump USB spec version in device descriptor to 2.0 ([#13078](https://github.com/qmk/qmk_firmware/pull/13078)) -* Unite half-duplex and full-duplex serial drivers ([#13081](https://github.com/qmk/qmk_firmware/pull/13081)) -* Add ST7565 LCD driver ([#13089](https://github.com/qmk/qmk_firmware/pull/13089)) -* `spi_master` Kinetis support ([#13098](https://github.com/qmk/qmk_firmware/pull/13098)) -* GMMK Pro RGB Support ([#13147](https://github.com/qmk/qmk_firmware/pull/13147)) -* Remove dfu-util arguments from mcu_selection ([#13150](https://github.com/qmk/qmk_firmware/pull/13150)) -* Add subcommand to generate version.h ([#13151](https://github.com/qmk/qmk_firmware/pull/13151)) -* Add oled_invert ([#13172](https://github.com/qmk/qmk_firmware/pull/13172)) -* ST7565 invert ([#13237](https://github.com/qmk/qmk_firmware/pull/13237)) -* RGB Matrix eeprom write limiting ([#13238](https://github.com/qmk/qmk_firmware/pull/13238)) -* Temporary disable of CRC ([#13252](https://github.com/qmk/qmk_firmware/pull/13252)) -* Move LED/RGB Matrix code into their own directories ([#13257](https://github.com/qmk/qmk_firmware/pull/13257)) -* Skip EEPROM writes once done. ([#13293](https://github.com/qmk/qmk_firmware/pull/13293)) -* Remove rgblight stubs ([#13302](https://github.com/qmk/qmk_firmware/pull/13302)) -* Allow settable SPI divisor for AW20216 driver, set default to 4 ([#13309](https://github.com/qmk/qmk_firmware/pull/13309)) -* Move RGBLight code into its own folder ([#13312](https://github.com/qmk/qmk_firmware/pull/13312)) -* Unify matrix for split common and regular matrix ([#13330](https://github.com/qmk/qmk_firmware/pull/13330)) -* Relocate RGB/HSV color defs to a more fitting place ([#13377](https://github.com/qmk/qmk_firmware/pull/13377)) -* Adds support for STM32L412xB, STM32L422xB. ([#13383](https://github.com/qmk/qmk_firmware/pull/13383)) -* Convert Dip Switch callbacks to boolean functions ([#13399](https://github.com/qmk/qmk_firmware/pull/13399)) -* Use string literals for `SERIAL_NUMBER` ([#13403](https://github.com/qmk/qmk_firmware/pull/13403)) -* Switch split_common to CRC subsystem ([#13418](https://github.com/qmk/qmk_firmware/pull/13418)) -* Improve 'show_build_options' target ([#13425](https://github.com/qmk/qmk_firmware/pull/13425)) -* AW20216 use register increment for framebuffer flushes ([#13430](https://github.com/qmk/qmk_firmware/pull/13430)) -* Allow invert of SPLIT_HAND_PIN logic ([#13433](https://github.com/qmk/qmk_firmware/pull/13433)) -* chibios: bootloader: use integer pointers as volatile ([#13450](https://github.com/qmk/qmk_firmware/pull/13450)) -* Refactor OLED to allow easy addition of other types ([#13454](https://github.com/qmk/qmk_firmware/pull/13454)) -* Dual RGB Matrix IS31FL3737 driver support to address #13442 ([#13457](https://github.com/qmk/qmk_firmware/pull/13457)) -* Enable g_is31_leds PROGMEM for RGB Matrix IS31FL3737 driver ([#13480](https://github.com/qmk/qmk_firmware/pull/13480)) -* Switch Ergodox Infinity over to split_common ([#13481](https://github.com/qmk/qmk_firmware/pull/13481)) -* Make solo half of split keyboards (more) usable. ([#13523](https://github.com/qmk/qmk_firmware/pull/13523)) -* Enable sync of OLED/ST7565 display on/off state on Splits ([#13542](https://github.com/qmk/qmk_firmware/pull/13542)) -* Revert "Add rgblight to RGB Matrix VPATH" ([#13559](https://github.com/qmk/qmk_firmware/pull/13559)) -* Move `SENDSTRING_BELL` code to `send_string.h` ([#13566](https://github.com/qmk/qmk_firmware/pull/13566)) -* Migrate platform independent code from tmk_core -> quantum ([#13673](https://github.com/qmk/qmk_firmware/pull/13673)) -* Avoid LTO conficts on arm_atsam ([#13676](https://github.com/qmk/qmk_firmware/pull/13676)) -* Allow for removal of hysteresis on 4x encoders ([#13698](https://github.com/qmk/qmk_firmware/pull/13698)) -* Port new_keyboard.sh to CLI ([#13706](https://github.com/qmk/qmk_firmware/pull/13706)) -* Align AW20216 driver ([#13712](https://github.com/qmk/qmk_firmware/pull/13712)) -* Haptic: driver-> feature ([#13713](https://github.com/qmk/qmk_firmware/pull/13713)) -* Add support for STM32F407x MCUs. ([#13718](https://github.com/qmk/qmk_firmware/pull/13718)) -* Remove legacy BACKLIGHT_CUSTOM_DRIVER option ([#13731](https://github.com/qmk/qmk_firmware/pull/13731)) -* Minor tidy up of key overrides ([#13747](https://github.com/qmk/qmk_firmware/pull/13747)) -* matrix_scan_x -> x_task ([#13748](https://github.com/qmk/qmk_firmware/pull/13748)) -* Move some led drivers to common folder ([#13749](https://github.com/qmk/qmk_firmware/pull/13749)) -* Allow for higher USB Polling rate on ATSAM boards ([#13755](https://github.com/qmk/qmk_firmware/pull/13755)) -* Rgb matrix/enable modes explicitly ([#13758](https://github.com/qmk/qmk_firmware/pull/13758)) -* Move chibios board files to allow tmk_core platform migration ([#13777](https://github.com/qmk/qmk_firmware/pull/13777)) -* __flash? ([#13799](https://github.com/qmk/qmk_firmware/pull/13799)) -* `--parallel` improvements ([#13800](https://github.com/qmk/qmk_firmware/pull/13800)) -* Speed up pimoroni trackball driver ([#13823](https://github.com/qmk/qmk_firmware/pull/13823)) -* Add a toggle key for GUI On/Off in Magic feature ([#13830](https://github.com/qmk/qmk_firmware/pull/13830)) -* Begin to carve out platform/protocol API - Single main loop ([#13843](https://github.com/qmk/qmk_firmware/pull/13843)) -* Remove Full Bootmagic ([#13846](https://github.com/qmk/qmk_firmware/pull/13846)) -* Remove backwards compatibility of debounce names ([#13877](https://github.com/qmk/qmk_firmware/pull/13877)) -* Relocate platform specific drivers ([#13894](https://github.com/qmk/qmk_firmware/pull/13894)) -* Remove ONEHAND_ENABLE ([#13920](https://github.com/qmk/qmk_firmware/pull/13920)) -* Move all the flash logic from tmk_core ([#13927](https://github.com/qmk/qmk_firmware/pull/13927)) -* adding uf2 flash support for blackpill 401 ([#13968](https://github.com/qmk/qmk_firmware/pull/13968)) -* Unify behaviour of wait on AVR ([#14025](https://github.com/qmk/qmk_firmware/pull/14025)) -* Add qmk-hid bootloader detection support to `qmk console` ([#14038](https://github.com/qmk/qmk_firmware/pull/14038)) -* Align DIP_SWITCH_PINS_RIGHT implementation with encoders ([#14079](https://github.com/qmk/qmk_firmware/pull/14079)) -* Tidy up quantum.c now some of tmk_core has been merged ([#14083](https://github.com/qmk/qmk_firmware/pull/14083)) -* Improve pmw3360 sensor and make it more hardware agnostic ([#14097](https://github.com/qmk/qmk_firmware/pull/14097)) -* Move nix folder alongside vagrant ([#14132](https://github.com/qmk/qmk_firmware/pull/14132)) -* Align some quantum sub-directories ([#14134](https://github.com/qmk/qmk_firmware/pull/14134)) -* Revert 14083 && 14144 ([#14150](https://github.com/qmk/qmk_firmware/pull/14150)) - -CLI: -* allow LINE_PINxx for Teensy 4.x pins ([#13247](https://github.com/qmk/qmk_firmware/pull/13247)) -* Remove the redundant pin name validation ([#13251](https://github.com/qmk/qmk_firmware/pull/13251)) -* Move all our CLI file formatters to the format dir ([#13296](https://github.com/qmk/qmk_firmware/pull/13296)) -* Refactor doctor.py into a directory ([#13298](https://github.com/qmk/qmk_firmware/pull/13298)) -* Add git and venv info to doctor's output ([#13405](https://github.com/qmk/qmk_firmware/pull/13405)) -* Matrix consistency check ([#13470](https://github.com/qmk/qmk_firmware/pull/13470)) -* Remove references to info.json `width` and `height` in CLI ([#13728](https://github.com/qmk/qmk_firmware/pull/13728)) -* Make `qmk doctor` more lenient about system config ([#13804](https://github.com/qmk/qmk_firmware/pull/13804)) -* Defer the expensive search for layout macros until info.json has been processed ([#14007](https://github.com/qmk/qmk_firmware/pull/14007)) - -Submodule updates: -* Update ChibiOS, ChibiOS-Contrib. ([#13056](https://github.com/qmk/qmk_firmware/pull/13056)) -* Update LUFA (18-07-2021) and add QMK-HID Bootloader support ([#13588](https://github.com/qmk/qmk_firmware/pull/13588)) -* Update LUFA Submodule (2021-07-30) ([#13819](https://github.com/qmk/qmk_firmware/pull/13819)) -* Bump gtest ([#13885](https://github.com/qmk/qmk_firmware/pull/13885)) -* Update ChibiOS-Contrib, mirroring script. ([#13896](https://github.com/qmk/qmk_firmware/pull/13896)) -* Move USB Host Shield and Arduino core to `lib/` ([#13973](https://github.com/qmk/qmk_firmware/pull/13973)) - -Keyboards: -* Migrate keyboards using uGFX to LED_MATRIX ([#9657](https://github.com/qmk/qmk_firmware/pull/9657)) -* Remove MIDI Configuration boilerplate ([#11151](https://github.com/qmk/qmk_firmware/pull/11151)) -* manyboard macro ([#11896](https://github.com/qmk/qmk_firmware/pull/11896)) -* Moved tokyo60/ into tokyokeyboard/tokyo60/. ([#12023](https://github.com/qmk/qmk_firmware/pull/12023)) -* Organize KPrepublic, K.T.E.C, xiudi boards into directories ([#12159](https://github.com/qmk/qmk_firmware/pull/12159)) -* Add Durgod Taurus K310 keyboard ([#12314](https://github.com/qmk/qmk_firmware/pull/12314)) -* add support for m65 and simple 5x13 ortholinear ([#12315](https://github.com/qmk/qmk_firmware/pull/12315)) -* Relocalize and Update p1800fl ([#12425](https://github.com/qmk/qmk_firmware/pull/12425)) -* GameBuddy v1.M ([#12637](https://github.com/qmk/qmk_firmware/pull/12637)) -* Add mechlovin9 rev2 PCB ([#12767](https://github.com/qmk/qmk_firmware/pull/12767)) -* Add RGB matrix support for Kyria ([#12789](https://github.com/qmk/qmk_firmware/pull/12789)) -* RGB Matrix working for Sofle RGB ([#12861](https://github.com/qmk/qmk_firmware/pull/12861)) -* Add Durgod Hades, Galaxy and Venus Keyboards ([#12893](https://github.com/qmk/qmk_firmware/pull/12893)) -* kint36: set correct EEPROM size ([#12946](https://github.com/qmk/qmk_firmware/pull/12946)) -* Updated encoder_update_user on my keymap to follow the new signature on quantum ([#13152](https://github.com/qmk/qmk_firmware/pull/13152)) -* Add Creator Pro by SergioPoverony ([#13154](https://github.com/qmk/qmk_firmware/pull/13154)) -* Use the new ST7565 driver on Ergodox Infinity ([#13165](https://github.com/qmk/qmk_firmware/pull/13165)) -* Refactor atom47 and add rev4 and rev5 ([#13201](https://github.com/qmk/qmk_firmware/pull/13201)) -* Add Bakeneko65 V3 and revision folders ([#13228](https://github.com/qmk/qmk_firmware/pull/13228)) -* Keyboards/RGBKB/Mün ([#13239](https://github.com/qmk/qmk_firmware/pull/13239)) -* Optimize our jsonschema by using refs ([#13271](https://github.com/qmk/qmk_firmware/pull/13271)) -* Handwired/Stream_Cheap/2x4: Add via support ([#13297](https://github.com/qmk/qmk_firmware/pull/13297)) -* ez_maker/directpins for easy one-offs in qmk_configurator ([#13321](https://github.com/qmk/qmk_firmware/pull/13321)) -* add kinT kinesis keyboard controller (kint41 variant) ([#13333](https://github.com/qmk/qmk_firmware/pull/13333)) -* Error log cleanup ([#13349](https://github.com/qmk/qmk_firmware/pull/13349)) -* Drashna's split updates ([#13350](https://github.com/qmk/qmk_firmware/pull/13350)) -* Migrate SHIFT_ESC and RGB `fn_actions` to Grave Escape and RGB keycodes ([#13360](https://github.com/qmk/qmk_firmware/pull/13360)) -* Add a lot more data to info.json ([#13366](https://github.com/qmk/qmk_firmware/pull/13366)) -* Remove `API_SYSEX_ENABLE`s from rules.mk ([#13389](https://github.com/qmk/qmk_firmware/pull/13389)) -* gmmk/pro/mike1808 keymap ([#13398](https://github.com/qmk/qmk_firmware/pull/13398)) -* Remove deprecated callbacks for encoders and dip switches ([#13404](https://github.com/qmk/qmk_firmware/pull/13404)) -* first pass: matrix consistency improvements ([#13471](https://github.com/qmk/qmk_firmware/pull/13471)) -* Migrate more `fn_actions` stuff ([#13502](https://github.com/qmk/qmk_firmware/pull/13502)) -* add simple gmmk pro macos keymap with rgb ([#13504](https://github.com/qmk/qmk_firmware/pull/13504)) -* move volcano660 to ilumkb folder ([#13550](https://github.com/qmk/qmk_firmware/pull/13550)) -* Valor Rev 2 ([#13551](https://github.com/qmk/qmk_firmware/pull/13551)) -* Split GMMK Pro PCBs into separate revisions ([#13570](https://github.com/qmk/qmk_firmware/pull/13570)) -* Remove the vision_division keyboard ([#13571](https://github.com/qmk/qmk_firmware/pull/13571)) -* Develop - Change uint32_t to layer_state_t ([#13596](https://github.com/qmk/qmk_firmware/pull/13596)) -* Develop - DC01 left ([#13597](https://github.com/qmk/qmk_firmware/pull/13597)) -* Created "paddlegame" keymap ([#13629](https://github.com/qmk/qmk_firmware/pull/13629)) -* Add timer_avr to includes for broken builds ([#13641](https://github.com/qmk/qmk_firmware/pull/13641)) -* Disable console by default on all Keebio boards ([#13649](https://github.com/qmk/qmk_firmware/pull/13649)) -* Enable LTO by default on BastardKB Scylla ([#13664](https://github.com/qmk/qmk_firmware/pull/13664)) -* Reduce compile size for dz60rgb v2.1 ([#13680](https://github.com/qmk/qmk_firmware/pull/13680)) -* Clean up remaining RGB_DISABLE_WHEN_USB_SUSPENDED defines ([#13689](https://github.com/qmk/qmk_firmware/pull/13689)) -* Remove some legacy files ([#13715](https://github.com/qmk/qmk_firmware/pull/13715)) -* [Keyboard Update] Change to L422 ([#13717](https://github.com/qmk/qmk_firmware/pull/13717)) -* Update kyria make path example ([#13720](https://github.com/qmk/qmk_firmware/pull/13720)) -* Drashna's Defaults cleanup ([#13722](https://github.com/qmk/qmk_firmware/pull/13722)) -* Reduce firmware size in prep for #12670 ([#13724](https://github.com/qmk/qmk_firmware/pull/13724)) -* Tidy up rgbkb/mun ([#13801](https://github.com/qmk/qmk_firmware/pull/13801)) -* Make default keymap for GMMK Pro reflect stock ([#13850](https://github.com/qmk/qmk_firmware/pull/13850)) -* Rework as per 9824 ([#13898](https://github.com/qmk/qmk_firmware/pull/13898)) -* Remove console from keebio via keyboards ([#13901](https://github.com/qmk/qmk_firmware/pull/13901)) -* Drashna split transport improvement ([#13905](https://github.com/qmk/qmk_firmware/pull/13905)) -* Copy GMMK Pro screw specs to ISO readme ([#13908](https://github.com/qmk/qmk_firmware/pull/13908)) -* Clean up remaining RGB_DISABLE_WHEN_USB_SUSPENDED defines Part 2 ([#13912](https://github.com/qmk/qmk_firmware/pull/13912)) -* Add andrebrait layout for GMMK Pro ([#13932](https://github.com/qmk/qmk_firmware/pull/13932)) -* Updated RGB Matrix suspend define part 3 ([#13954](https://github.com/qmk/qmk_firmware/pull/13954)) -* Improve andrebrait keymap ([#13985](https://github.com/qmk/qmk_firmware/pull/13985)) -* Drashna's Improve OLEDs and custom Split code ([#14063](https://github.com/qmk/qmk_firmware/pull/14063)) -* Kyria default reformat ([#14080](https://github.com/qmk/qmk_firmware/pull/14080)) -* Feature rich keymap for GMMK Pro (ANSI) ([#14120](https://github.com/qmk/qmk_firmware/pull/14120)) - -Keyboard fixes: -* Fix LED mapping for GMMK Pro ([#13189](https://github.com/qmk/qmk_firmware/pull/13189)) -* Fix up SplitKB keyboards ([#13511](https://github.com/qmk/qmk_firmware/pull/13511)) -* Keyboards/sol rev2 fix ([#13533](https://github.com/qmk/qmk_firmware/pull/13533)) -* Fix MATRIX_COLS for aeboards/constellation/rev2 ([#13633](https://github.com/qmk/qmk_firmware/pull/13633)) -* Fix errors with matrix_output_unselect_delay function calls ([#13645](https://github.com/qmk/qmk_firmware/pull/13645)) -* Fix default keymap for 0xCB 1337 keyboard ([#13646](https://github.com/qmk/qmk_firmware/pull/13646)) -* Fix Matrix Row number for ggkeyboards/genisis ([#13647](https://github.com/qmk/qmk_firmware/pull/13647)) -* Fix matrix issues with Promethium ([#13648](https://github.com/qmk/qmk_firmware/pull/13648)) -* Fix dc01/left so that it doesn't throw a warning ([#13653](https://github.com/qmk/qmk_firmware/pull/13653)) -* Remove broken, unmaintained converter/ibm_5291 ([#13658](https://github.com/qmk/qmk_firmware/pull/13658)) -* Quick hack to fix Astro65 board ([#13665](https://github.com/qmk/qmk_firmware/pull/13665)) -* Fix symmetric70_proto build break on develop branch ([#13667](https://github.com/qmk/qmk_firmware/pull/13667)) -* Fix matrix delay on Drop boards ([#13671](https://github.com/qmk/qmk_firmware/pull/13671)) -* Fix split matrix for sekigon grs 70ec ([#13672](https://github.com/qmk/qmk_firmware/pull/13672)) -* Fix type on pandora via keymap ([#13681](https://github.com/qmk/qmk_firmware/pull/13681)) -* Fix & clean up tronguylabs/m122_3270 ([#13684](https://github.com/qmk/qmk_firmware/pull/13684)) -* Fix up xd002 rgb keymaps ([#13685](https://github.com/qmk/qmk_firmware/pull/13685)) -* Dactyl Manuform cleanup ([#13686](https://github.com/qmk/qmk_firmware/pull/13686)) -* Fix Q1 change dip switch to bool ([#13687](https://github.com/qmk/qmk_firmware/pull/13687)) -* Fix compile size for the Merge UM70 via keymap ([#13690](https://github.com/qmk/qmk_firmware/pull/13690)) -* Fix compile size for the Lets Split Sockets via keymap ([#13691](https://github.com/qmk/qmk_firmware/pull/13691)) -* Fix Compile size on ungodly Launch Pad ([#13692](https://github.com/qmk/qmk_firmware/pull/13692)) -* dirty fix ([#13695](https://github.com/qmk/qmk_firmware/pull/13695)) -* Fix compile size for the Vitamins Included via keymap ([#13696](https://github.com/qmk/qmk_firmware/pull/13696)) -* Fix typo in Dactyl Manuform ([#13740](https://github.com/qmk/qmk_firmware/pull/13740)) -* Fix compile issues due to LED changes ([#13821](https://github.com/qmk/qmk_firmware/pull/13821)) -* Fix SRC include for matrix/m20add issi driver ([#13826](https://github.com/qmk/qmk_firmware/pull/13826)) -* fix develop branch move file ([#13832](https://github.com/qmk/qmk_firmware/pull/13832)) -* Fix knops keymaps ([#13872](https://github.com/qmk/qmk_firmware/pull/13872)) -* Switch Draculad to using WPM char hack ([#13886](https://github.com/qmk/qmk_firmware/pull/13886)) -* Fix up builds after #8591 ([#13900](https://github.com/qmk/qmk_firmware/pull/13900)) -* Fix matrix_output_unselect_delay for handwired/xealousbrown ([#13913](https://github.com/qmk/qmk_firmware/pull/13913)) -* Fixup rgb matrix config for KBD67 mkII boards ([#13931](https://github.com/qmk/qmk_firmware/pull/13931)) -* Fix compliation for ferris 0.2 bling ([#13937](https://github.com/qmk/qmk_firmware/pull/13937)) -* Fix some additional bootmagic settings ([#13979](https://github.com/qmk/qmk_firmware/pull/13979)) -* Fix default keymap for GMMK Pro Iso ([#13980](https://github.com/qmk/qmk_firmware/pull/13980)) -* Fixup Ungodly Launch Pad config ([#13992](https://github.com/qmk/qmk_firmware/pull/13992)) -* Fix errors that have cropped up in develop ([#14005](https://github.com/qmk/qmk_firmware/pull/14005)) -* Fix wait_us overflow in matrix for dactyl based boards ([#14039](https://github.com/qmk/qmk_firmware/pull/14039)) -* Fixup Neson Design N6 ISSI includes ([#14045](https://github.com/qmk/qmk_firmware/pull/14045)) -* Fixup `massdrop/alt`, `cest73/tkm`. ([#14048](https://github.com/qmk/qmk_firmware/pull/14048)) -* fix helix:fraanrosi compile error caused by #13677. ([#14061](https://github.com/qmk/qmk_firmware/pull/14061)) -* Fix compile issues for Tractyl Manuform ([#14105](https://github.com/qmk/qmk_firmware/pull/14105)) -* Disable Console on Keebio Quefrency ([#14108](https://github.com/qmk/qmk_firmware/pull/14108)) -* Fixed GMMK Pro -> stickandgum keymap readme.md ([#14123](https://github.com/qmk/qmk_firmware/pull/14123)) -* Drashna keymap fixups ([#14140](https://github.com/qmk/qmk_firmware/pull/14140)) -* fix ([#14142](https://github.com/qmk/qmk_firmware/pull/14142)) -* Fix merge artifacts ([#14146](https://github.com/qmk/qmk_firmware/pull/14146)) -* Update readme files ([#14172](https://github.com/qmk/qmk_firmware/pull/14172)) - -Others: -* Add examples to RGB Matrix Indicators docs ([#12797](https://github.com/qmk/qmk_firmware/pull/12797)) - -Bugs: -* Fix Indicator LED issues ([#12097](https://github.com/qmk/qmk_firmware/pull/12097)) -* Fixing incorrect keymap build when switching between multiple keymap.jsons ([#12632](https://github.com/qmk/qmk_firmware/pull/12632)) -* Fix LED Hit Counter for LED/RGB Matrix ([#12674](https://github.com/qmk/qmk_firmware/pull/12674)) -* ChibiOS fix O3 and LTO breakage of extra keys and joystick ([#12819](https://github.com/qmk/qmk_firmware/pull/12819)) -* Remove the #10088 hotfix for Teensy 3.1-like Input:Club keyboards ([#12870](https://github.com/qmk/qmk_firmware/pull/12870)) -* Fix firmware size check with avr-libc 1:2.0.0+Atmel3.6.2-1.1 (Debian bullseye) ([#12951](https://github.com/qmk/qmk_firmware/pull/12951)) -* Fix RGB/LED Suspend defines ([#13146](https://github.com/qmk/qmk_firmware/pull/13146)) -* Fix overrun in st7565_write_raw when not at (0, 0) ([#13209](https://github.com/qmk/qmk_firmware/pull/13209)) -* Upgrades Vagrant box to Debian 10 to fix Docker build error on Debian 9. ([#13236](https://github.com/qmk/qmk_firmware/pull/13236)) -* Fix issues with VIA EEPROM init and bring in line with eeconfig functionality ([#13243](https://github.com/qmk/qmk_firmware/pull/13243)) -* Fix CRC for AVR and enable again. ([#13253](https://github.com/qmk/qmk_firmware/pull/13253)) -* Fix linker error when rgblight and RGB Matrix are both enabled ([#13304](https://github.com/qmk/qmk_firmware/pull/13304)) -* Fix building layouts from JSON ([#13310](https://github.com/qmk/qmk_firmware/pull/13310)) -* Add rgblight to RGB Matrix VPATH ([#13371](https://github.com/qmk/qmk_firmware/pull/13371)) -* Fix two out of bounds accesses from #13330. ([#13525](https://github.com/qmk/qmk_firmware/pull/13525)) -* Fixes for clang not being able to run unit tests ([#13546](https://github.com/qmk/qmk_firmware/pull/13546)) -* Fixup Audio startup and add to documents ([#13606](https://github.com/qmk/qmk_firmware/pull/13606)) -* CLI/Docs: Fix the format commands' name ([#13668](https://github.com/qmk/qmk_firmware/pull/13668)) -* Disables rgblight twinkle by default. ([#13677](https://github.com/qmk/qmk_firmware/pull/13677)) -* Fix typo in dip switch example ([#13688](https://github.com/qmk/qmk_firmware/pull/13688)) -* docs/cli_commands: fix typo ([#13697](https://github.com/qmk/qmk_firmware/pull/13697)) -* Include gpio.h in solenoid driver for GPIO Control functions ([#13716](https://github.com/qmk/qmk_firmware/pull/13716)) -* Fix pimoroni trackball read address ([#13810](https://github.com/qmk/qmk_firmware/pull/13810)) -* Fix Key Override includes ([#13831](https://github.com/qmk/qmk_firmware/pull/13831)) -* Fix alignment of USB out report buffer 2 -> 4 ([#13838](https://github.com/qmk/qmk_firmware/pull/13838)) -* Fix compilation issue. ([#13926](https://github.com/qmk/qmk_firmware/pull/13926)) -* Fix `combo_disable` ([#13988](https://github.com/qmk/qmk_firmware/pull/13988)) -* Fix pmw3360 code to only output debug info if mouse debugging is enabled ([#13993](https://github.com/qmk/qmk_firmware/pull/13993)) -* Fix ifdefs for OLED split sync code ([#14017](https://github.com/qmk/qmk_firmware/pull/14017)) -* Various fixes from reorg of files ([#14051](https://github.com/qmk/qmk_firmware/pull/14051)) -* Fixup atsam builds. ([#14052](https://github.com/qmk/qmk_firmware/pull/14052)) -* Fix RGB/LED Matrix Suspend code ([#14084](https://github.com/qmk/qmk_firmware/pull/14084)) -* Fix issues with recent keymap.json changes ([#14089](https://github.com/qmk/qmk_firmware/pull/14089)) -* Fix LED Matrix suspend code ([#14090](https://github.com/qmk/qmk_firmware/pull/14090)) -* Fix up compilation issues. ([#14095](https://github.com/qmk/qmk_firmware/pull/14095)) -* Fix copypasta issue with pmw3360 sensor config ([#14106](https://github.com/qmk/qmk_firmware/pull/14106)) -* Fix typo ([#14118](https://github.com/qmk/qmk_firmware/pull/14118)) -* Fix bootloadHID comments breaking :flash ([#14133](https://github.com/qmk/qmk_firmware/pull/14133)) -* Fix Mouse Shared EP functionality ([#14136](https://github.com/qmk/qmk_firmware/pull/14136)) -* Short term bodge for firmware size bloat ([#14144](https://github.com/qmk/qmk_firmware/pull/14144)) -* Move to correct location ([#14171](https://github.com/qmk/qmk_firmware/pull/14171)) diff --git a/docs/ChangeLog/20211127.md b/docs/ChangeLog/20211127.md deleted file mode 100644 index 0780ab6a44c6..000000000000 --- a/docs/ChangeLog/20211127.md +++ /dev/null @@ -1,457 +0,0 @@ -# QMK Breaking Changes - 2021 November 27 Changelog - -## 2000 keyboards! :id=qmk-2000th-keyboard - -QMK had it's 2000th keyboard submitted during this breaking changes cycle.... and it only _just_ made the cut-off! - -```shell -% qmk list-keyboards | wc -l -2003 -``` - -From the whole QMK team, a major thankyou to the community for embracing QMK as your preferred keyboard firmware! - -## Notable Features :id=notable-features - -### Expanded Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) :id=expanded-pointing-device - -Pointing device support has been reworked and reimplemented to allow for easier integration of new peripherals. - -Usages of `POINTING_DEVICE_ENABLE = yes` in `rules.mk` files now need to be accompanied by a corresponding `POINTING_DEVICE_DRIVER = ???` line, specifying which driver to use during the build. Existing keyboards have already been migrated across to the new usage pattern, so most likely no change is required by users. - -QMK now has core-supplied support for the following pointing device peripherals: - -| `rules.mk` line | Supported device | -|------------------------------------------------|-----------------------------------------| -| `POINTING_DEVICE_DRIVER = analog_joystick` | Analog joysticks, such as PSP joysticks | -| `POINTING_DEVICE_DRIVER = adns5050` | ADNS 5050 sensor | -| `POINTING_DEVICE_DRIVER = adns9800` | ADNS 9800 laser sensor | -| `POINTING_DEVICE_DRIVER = cirque_pinnacle_i2c` | Cirque touchpad, I2C mode | -| `POINTING_DEVICE_DRIVER = cirque_pinnacle_spi` | Cirque Touchpad, SPI mode | -| `POINTING_DEVICE_DRIVER = pimoroni_trackball` | Pimoroni Trackball | -| `POINTING_DEVICE_DRIVER = pmw3360` | PMW 3360 | - -See the new documentation for the [Pointing Device](../feature_pointing_device.md) feature for more information on specific configuration for each driver. - -### Dynamic Tapping Term ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) :id=dynamic-tapping-term - -For people who are starting out with tapping keys, or for people who think tapping keys don't "feel right", it's sometimes quite difficult to determine what duration of tapping term to use to make things seem natural. - -If you're in this stage of discovery, you can now add `DYNAMIC_TAPPING_TERM_ENABLE = yes` to your `rules.mk`, which enables the use of the following keycodes in your keymap: - -| Key | Description | -|-----------|-------------------------------------------------------------------------------| -| `DT_PRNT` | "Dynamic Tapping Term Print": Types the current tapping term, in milliseconds | -| `DT_UP` | "Dynamic Tapping Term Up": Increases the current tapping term by 5ms | -| `DT_DOWN` | "Dynamic Tapping Term Down": Decreases the current tapping term by 5ms | - -Coupled with the use of `qmk console` or QMK Toolbox to show console output from your keyboard, you can tweak the tapping term dynamically in order to narrow down what "feels right" to you. Once you're happy, drop in the resulting number into your keymap's `config.h` and you're good to go! - -### Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) :id=macros-in-keymap-json - -You can now define up to 32 macros in your `keymap.json` file, as used by [QMK Configurator](newbs_building_firmware_configurator.md), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this: - -```json -{ - "keyboard": "handwired/my_macropad", - "keymap": "my_keymap", - "macros": [ - [ // first listed is QK_MACRO_0... - {"action":"down", "keycodes": ["LSFT"]}, - "hello world1", - {"action": "up","keycodes": ["LSFT"]} - ], - [ // ...then QK_MACRO_1... - {"action":"tap", "keycodes": ["LCTL", "LALT", "DEL"]} - ], - [ // ...then QK_MACRO_2... - "ding!", - {"action":"beep"} - ], - [ // ...and QK_MACRO_3. - {"action":"tap", "keycodes": ["F1"]}, - {"action":"delay", "duration": "1000"}, - {"action":"tap", "keycodes": ["PGDN"]} - ] - ], - "layout": "LAYOUT_all", - "layers": [ - ["QK_MACRO_0", "QK_MACRO_1", "QK_MACRO_2", "QK_MACRO_3"] - ] -} -``` - -In due course, [QMK Configurator](https://config.qmk.fm/) will pick up support for defining these in its UI, but for now the json is the only way to define macros. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|------------------------|---------------------------------| -| aozora/hotswap | aozora | -| gskt00 | kapcave/gskt00 | -| handwired/dtisaac01 | dtisaac/dtisaac01 | -| kprepublic/bm60poker | kprepublic/bm60hsrgb_poker/rev1 | -| kprepublic/bm60rgb | kprepublic/bm60hsrgb/rev1 | -| kprepublic/bm60rgb_iso | kprepublic/bm60hsrgb_iso/rev1 | -| kprepublic/bm65iso | kprepublic/bm65hsrgb_iso | -| kprepublic/bm68rgb | kprepublic/bm68hsrgb | -| paladin64 | kapcave/paladin64 | -| portal_66 | portal_66/soldered | -| signum/3_0/elitec | signum/3_0 | -| tgr/jane | tgr/jane/v2 | - -### Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) :id=squeezing-space-from-avr - -The AVR platform has been problematic for some time, in the sense that it is severely resource-constrained -- this makes life difficult for anyone attempting to add new functionality such as display panels to their keymap code. The illustrious Drashna has contributed some newer documentation on how to attempt to free up some space on AVR-based keyboards that are in short supply. - -Of course, there are much fewer constraints with ARM chips... ;) - -### Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) :id=explicit-rgb-modes - -Related to the previous section -- RGB Matrix modes have now been made to be opt-in, rather than opt-out. As these animations are now opt-in, you may find that your keyboard no longer has all the RGB modes you're expecting -- you may need to configure and recompile your firmware and enable your animations of choice... with any luck they'll still fit in the space available. - -Most keyboards keep their original functionality, but over time the QMK maintainers have found that removal of animations ends up being the quickest way to free up space... and some keyboards have had animations such as reactive effects disabled by default in order to still fit within the flash space available. - -The full list of configurables to turn specific animations back on can be found at on the [RGB Matrix documentation](feature_rgb_matrix.md#rgb-matrix-effects) page. - -### OLED task refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) :id=oled-task-refactor - -OLED display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done. - -This changes the standard OLED drawing function model to allow for a base implementation to be provided by a keyboard, but also still allow for keymap-level overrides without needing to modify the keyboard's code. - -The old keymap code went something like this: - -```c -void oled_task_user(void) { - // keymap drawing code -} -``` - -...but the new keymap code looks like this: -```c -bool oled_task_user(void) { - // keymap drawing code - return false; -} -``` - -Keyboard designers should now structure their keyboard-level drawing routines like the following, in order to allow for keymap overrides: - -```c -bool oled_task_kb(void) { - // Defer to the keymap if they want to override - if(!oled_task_user()) { return false; } - - // default keyboard drawing code - return false; -} -``` - -### Bootmagic Full Removal ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) :id=bootmagic-full-removal - -As noted during previous breaking changes cycles, QMK decided to deprecate the full Bootmagic feature and leave Bootmagic Lite as the only remaining option. - -This removal is now complete! - -This pull request changes the behavior of `BOOTMAGIC_ENABLE` such that specifying `lite` or `full` results in an error, allowing only `yes` or `no`, with `yes` mirroring historical `lite` functionality. - -All use of the `lite` keyword within the repository has been migrated to `yes` -- any new submissions using `lite` will now fail to build and should be updated accordingly. - -#### Bootmagic Full Deprecation Schedule: Complete! - -This is the historical timeline for the behavior of `BOOTMAGIC_ENABLE`: - -- (done) From 2021 May 29, setting `BOOTMAGIC_ENABLE = yes` will enable Bootmagic Lite instead of full Bootmagic. -- (done) From 2021 Aug 28, `BOOTMAGIC_ENABLE` must be either `yes`, `lite`, or `no` – setting `BOOTMAGIC_ENABLE = full` will cause compilation to fail. -- (now) From 2021 Nov 27, `BOOTMAGIC_ENABLE` must be either `yes` or `no` – setting `BOOTMAGIC_ENABLE = lite` will cause compilation to fail. - -### Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) :id=remove-qwiic - -Due to minimal QWIIC adoption and other options for similar functionality, the QWIIC drivers were removed from QMK. Existing OLED usages have been migrated across to the normal QMK OLED driver instead. - -## Notable core changes :id=notable-core - -### New MCU Support :id=new-mcu-support - -QMK firmware picked up support for a handful of new MCU families, potentially making it a bit easier to source components. - -QMK firmware is now no longer limited to AVR and ARM - it also picked up support for our first RISC-V chip, the GD32VF103. - -* Add support for RISC-V builds and GD32VF103 MCU ([#12508](https://github.com/qmk/qmk_firmware/pull/12508)) -* Add HT32 support to core ([#14388](https://github.com/qmk/qmk_firmware/pull/14388)) -* Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422)) -* Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584)) - -### EEPROM Changes :id=eeprom-changes - -There were a few EEPROM-related changes that landed during this breaking changes cycle, most prominently the long-awaited ability for the Drop boards to gain persistent storage. Any users of the Drop CTRL or Drop ALT should update QMK Toolbox as well -- coupled with a QMK firmware update settings should now be saved. - -* massdrop alt/ctrl: support saving into nvm ([#6068](https://github.com/qmk/qmk_firmware/pull/6068)) -* Implement F4 eeprom ([#14195](https://github.com/qmk/qmk_firmware/pull/14195)) -* make the full 4096 bytes of EEPROM work on Teensy 3.6 ([#12947](https://github.com/qmk/qmk_firmware/pull/12947)) -* Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591)) -* Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752)) - -### Compilation Database :id=compile-commands - -A clang-compatible compilation database generator has been added as an option in order to help development environments such as Visual Studio Code. - -Running `qmk generate-compilation-database -kb -km ` from within the QMK firmware directory will generate a `compile_commands.json` file -- using a compatible IDE will likely see this and correctly start detecting the correct locations for source files as well as type and function information that are relevant to your build. - -Do note that switching keyboards will require re-generation of this file. - -* New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370)) -* compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462)) - -### Codebase restructure and cleanup :id=codebase-restructure - -QMK continues on its restructuring journey, in order to make it easier to integrate newer features and add support for new hardware. This quarter's batch of changes include: - -* add 'include keyboard_features.mk' into build_keyboard.mk ([#8422](https://github.com/qmk/qmk_firmware/pull/8422)) -* Infer more when building features ([#13890](https://github.com/qmk/qmk_firmware/pull/13890)) -* Move `tmk_core/common/` ([#13918](https://github.com/qmk/qmk_firmware/pull/13918)) -* Move feature suspend logic out of platform specific code ([#14210](https://github.com/qmk/qmk_firmware/pull/14210)) -* Remove bin/qmk ([#14231](https://github.com/qmk/qmk_firmware/pull/14231)) -* Move Audio drivers from quantum to platform drivers folder ([#14308](https://github.com/qmk/qmk_firmware/pull/14308)) -* Remove Arduino-style `analogRead()` ([#14348](https://github.com/qmk/qmk_firmware/pull/14348)) -* Remove unreferenced IBM4704, Sony NEWS, NeXT keyboard code. ([#14380](https://github.com/qmk/qmk_firmware/pull/14380)) -* Move Bluetooth config to common_features.mk ([#14404](https://github.com/qmk/qmk_firmware/pull/14404)) -* Relocate Adafruit BLE code ([#14530](https://github.com/qmk/qmk_firmware/pull/14530)) -* Change `MK66F18` -> `MK66FX1M0` ([#14659](https://github.com/qmk/qmk_firmware/pull/14659)) -* Remove sysex API ([#14723](https://github.com/qmk/qmk_firmware/pull/14723)) -* Basic keycode overhaul ([#14726](https://github.com/qmk/qmk_firmware/pull/14726)) -* Remove SERIAL_LINK feature ([#14727](https://github.com/qmk/qmk_firmware/pull/14727)) -* Move converter specific tmk_core protocols ([#14743](https://github.com/qmk/qmk_firmware/pull/14743)) -* Align PS/2 GPIO defines ([#14745](https://github.com/qmk/qmk_firmware/pull/14745)) -* Clean up LED/RGB Matrix driver config ([#14760](https://github.com/qmk/qmk_firmware/pull/14760)) -* Update UART driver API ([#14839](https://github.com/qmk/qmk_firmware/pull/14839)) -* Tidy up LCD_ENABLE/visualizer references ([#14855](https://github.com/qmk/qmk_firmware/pull/14855)) -* Remove legacy Makefile functionality ([#14858](https://github.com/qmk/qmk_firmware/pull/14858)) -* Begin to carve out platform/protocol API - Migrate keyboard_* calls ([#14888](https://github.com/qmk/qmk_firmware/pull/14888)) -* Rename platform SRC variable ([#14894](https://github.com/qmk/qmk_firmware/pull/14894)) -* Relocate PS2 code ([#14895](https://github.com/qmk/qmk_firmware/pull/14895)) -* Move USE_CCACHE logic to common location ([#14899](https://github.com/qmk/qmk_firmware/pull/14899)) -* Migrate makefile utilities to sub-directory ([#14917](https://github.com/qmk/qmk_firmware/pull/14917)) -* Remove SERIAL_MOUSE ([#14969](https://github.com/qmk/qmk_firmware/pull/14969)) -* Relocate protocol files within tmk_core/common/ ([#14972](https://github.com/qmk/qmk_firmware/pull/14972)) -* More platform/protocol alignment ([#14976](https://github.com/qmk/qmk_firmware/pull/14976)) -* Fix uart function prototypes ([#15162](https://github.com/qmk/qmk_firmware/pull/15162)) -* Remove deprecated KEYMAP alias ([#15037](https://github.com/qmk/qmk_firmware/pull/15037)) -* Move non-assignment code to post_rules.mk ([#14207](https://github.com/qmk/qmk_firmware/pull/14207)) -* Helix use `post_rules.mk` ([#14216](https://github.com/qmk/qmk_firmware/pull/14216)) -* Make ChibiOS PAL interactions less STM32 specific - Round 2 ([#14456](https://github.com/qmk/qmk_firmware/pull/14456)) - ---- - -## Full changelist - -Core: -* massdrop alt/ctrl: support saving into nvm ([#6068](https://github.com/qmk/qmk_firmware/pull/6068)) -* Made AVR backlight pwm resolution configurable ([#7521](https://github.com/qmk/qmk_firmware/pull/7521)) -* add 'include keyboard_features.mk' into build_keyboard.mk ([#8422](https://github.com/qmk/qmk_firmware/pull/8422)) -* New feature: `DYNAMIC_TAPPING_TERM_ENABLE` ([#11036](https://github.com/qmk/qmk_firmware/pull/11036)) -* Add Retro Shift (Auto Shift for Tap Hold via Retro Tapping) and Custom Auto Shifts ([#11059](https://github.com/qmk/qmk_firmware/pull/11059)) -* Add support for RISC-V builds and GD32VF103 MCU ([#12508](https://github.com/qmk/qmk_firmware/pull/12508)) -* Add Fractal RGB matrix effects ([#12670](https://github.com/qmk/qmk_firmware/pull/12670)) -* Added power tracking api ([#12691](https://github.com/qmk/qmk_firmware/pull/12691)) -* haptic: Feature to disable it when usb port is not configured or suspended. ([#12692](https://github.com/qmk/qmk_firmware/pull/12692)) -* make the full 4096 bytes of EEPROM work on Teensy 3.6 ([#12947](https://github.com/qmk/qmk_firmware/pull/12947)) -* Add Support for USB programmable buttons ([#12950](https://github.com/qmk/qmk_firmware/pull/12950)) -* [Tests] Increase QMK test coverage ([#13789](https://github.com/qmk/qmk_firmware/pull/13789)) -* Add support for ISSI drivers on both sides of a split keyboard ([#13842](https://github.com/qmk/qmk_firmware/pull/13842)) -* Infer more when building features ([#13890](https://github.com/qmk/qmk_firmware/pull/13890)) -* Reimplements WPM feature to be smaller & precise ([#13902](https://github.com/qmk/qmk_firmware/pull/13902)) -* Move `tmk_core/common/` ([#13918](https://github.com/qmk/qmk_firmware/pull/13918)) -* Improvements to handling of disconnected split keyboards. ([#14033](https://github.com/qmk/qmk_firmware/pull/14033)) -* Add Pixel Rain RGB Matrix effect ([#14155](https://github.com/qmk/qmk_firmware/pull/14155)) -* Remove QWIIC_DRIVERS ([#14174](https://github.com/qmk/qmk_firmware/pull/14174)) -* Add LM() keys to the list of keys disabled by NO_HAPTIC_MOD ([#14181](https://github.com/qmk/qmk_firmware/pull/14181)) -* Implement F4 eeprom ([#14195](https://github.com/qmk/qmk_firmware/pull/14195)) -* define to AUTO_SHIFT_DISABLED_AT_STARTUP ([#14201](https://github.com/qmk/qmk_firmware/pull/14201)) -* Move feature suspend logic out of platform specific code ([#14210](https://github.com/qmk/qmk_firmware/pull/14210)) -* Remove bin/qmk ([#14231](https://github.com/qmk/qmk_firmware/pull/14231)) -* Change keyboard level include guards to `pragma once` ([#14248](https://github.com/qmk/qmk_firmware/pull/14248)) -* i2c_master: Add support for reading/writing to 16-bit registers ([#14289](https://github.com/qmk/qmk_firmware/pull/14289)) -* Move Audio drivers from quantum to platform drivers folder ([#14308](https://github.com/qmk/qmk_firmware/pull/14308)) -* Add RGBW support to PWM and SPI drivers for ChibiOS ([#14327](https://github.com/qmk/qmk_firmware/pull/14327)) -* Rework and expand Pointing Device support ([#14343](https://github.com/qmk/qmk_firmware/pull/14343)) -* Remove Arduino-style `analogRead()` ([#14348](https://github.com/qmk/qmk_firmware/pull/14348)) -* Macros in JSON keymaps ([#14374](https://github.com/qmk/qmk_firmware/pull/14374)) -* Remove unreferenced IBM4704, Sony NEWS, NeXT keyboard code. ([#14380](https://github.com/qmk/qmk_firmware/pull/14380)) -* Add HT32 support to core ([#14388](https://github.com/qmk/qmk_firmware/pull/14388)) -* Align ChibiOS I2C defs with other drivers ([#14399](https://github.com/qmk/qmk_firmware/pull/14399)) -* Move Bluetooth config to common_features.mk ([#14404](https://github.com/qmk/qmk_firmware/pull/14404)) -* Westberrytech pr ([#14422](https://github.com/qmk/qmk_firmware/pull/14422)) -* Refactor use of STM32_SYSCLK ([#14430](https://github.com/qmk/qmk_firmware/pull/14430)) -* Migrate STM32_EEPROM_ENABLE to use EEPROM_DRIVER ([#14433](https://github.com/qmk/qmk_firmware/pull/14433)) -* Refactor use of _STM32_ defines ([#14439](https://github.com/qmk/qmk_firmware/pull/14439)) -* Add i2c defaults for Convert to Proton C ([#14470](https://github.com/qmk/qmk_firmware/pull/14470)) -* Use opendrain pin with external pullup again ([#14474](https://github.com/qmk/qmk_firmware/pull/14474)) -* Add ability to use numpad digits for unicode mode UC_WIN ([#14496](https://github.com/qmk/qmk_firmware/pull/14496)) -* Enable de-ghosting for RGB/LED matrix on all ISSI LED drivers ([#14508](https://github.com/qmk/qmk_firmware/pull/14508)) -* Relocate Adafruit BLE code ([#14530](https://github.com/qmk/qmk_firmware/pull/14530)) -* Initial pass of F405 support ([#14584](https://github.com/qmk/qmk_firmware/pull/14584)) -* Further tidy up of STM32 eeprom emulation ([#14591](https://github.com/qmk/qmk_firmware/pull/14591)) -* Remove GCC version check from song list inclusion ([#14600](https://github.com/qmk/qmk_firmware/pull/14600)) -* Change `MK66F18` -> `MK66FX1M0` ([#14659](https://github.com/qmk/qmk_firmware/pull/14659)) -* Add ifndef to WS2812 timing constraints ([#14678](https://github.com/qmk/qmk_firmware/pull/14678)) -* Reuse of EEPROM debounce logic ([#14699](https://github.com/qmk/qmk_firmware/pull/14699)) -* Remove sysex API ([#14723](https://github.com/qmk/qmk_firmware/pull/14723)) -* Basic keycode overhaul ([#14726](https://github.com/qmk/qmk_firmware/pull/14726)) -* Remove SERIAL_LINK feature ([#14727](https://github.com/qmk/qmk_firmware/pull/14727)) -* Enable CLI flashing via mdloader ([#14729](https://github.com/qmk/qmk_firmware/pull/14729)) -* Correct the Turkish F '?' keycode (TR_QUES) ([#14740](https://github.com/qmk/qmk_firmware/pull/14740)) -* Move converter specific tmk_core protocols ([#14743](https://github.com/qmk/qmk_firmware/pull/14743)) -* Align PS/2 GPIO defines ([#14745](https://github.com/qmk/qmk_firmware/pull/14745)) -* Improve Adafruit BLE configuration defines ([#14749](https://github.com/qmk/qmk_firmware/pull/14749)) -* Enable eeprom with F401xE ld ([#14752](https://github.com/qmk/qmk_firmware/pull/14752)) -* Clean up LED/RGB Matrix driver config ([#14760](https://github.com/qmk/qmk_firmware/pull/14760)) -* Initial USB2422 driver ([#14835](https://github.com/qmk/qmk_firmware/pull/14835)) -* Update UART driver API ([#14839](https://github.com/qmk/qmk_firmware/pull/14839)) -* Split out arm_atsam shift register logic ([#14848](https://github.com/qmk/qmk_firmware/pull/14848)) -* Split out HAPTIC_ENABLE to have separate DRIVER option ([#14854](https://github.com/qmk/qmk_firmware/pull/14854)) -* Tidy up LCD_ENABLE/visualizer references ([#14855](https://github.com/qmk/qmk_firmware/pull/14855)) -* Remove legacy Makefile functionality ([#14858](https://github.com/qmk/qmk_firmware/pull/14858)) -* Add support for deferred executors. ([#14859](https://github.com/qmk/qmk_firmware/pull/14859)) -* Change OLED task function to be boolean ([#14864](https://github.com/qmk/qmk_firmware/pull/14864)) -* Add a new led driver for Keychron's keyboards. ([#14872](https://github.com/qmk/qmk_firmware/pull/14872)) -* Begin to carve out platform/protocol API - Migrate keyboard_* calls ([#14888](https://github.com/qmk/qmk_firmware/pull/14888)) -* Rename platform SRC variable ([#14894](https://github.com/qmk/qmk_firmware/pull/14894)) -* Relocate PS2 code ([#14895](https://github.com/qmk/qmk_firmware/pull/14895)) -* Move USE_CCACHE logic to common location ([#14899](https://github.com/qmk/qmk_firmware/pull/14899)) -* Migrate makefile utilities to sub-directory ([#14917](https://github.com/qmk/qmk_firmware/pull/14917)) -* Remove legacy handling for ErgoDox Infinity handedness ([#14919](https://github.com/qmk/qmk_firmware/pull/14919)) -* Align usbasp flashing behaviour ([#14928](https://github.com/qmk/qmk_firmware/pull/14928)) -* Optimize matrix scanning by removing variable shifts ([#14947](https://github.com/qmk/qmk_firmware/pull/14947)) -* Stop-gap forward-port Drop LED features for CTRL and ALT ([#14967](https://github.com/qmk/qmk_firmware/pull/14967)) -* Remove SERIAL_MOUSE ([#14969](https://github.com/qmk/qmk_firmware/pull/14969)) -* Relocate protocol files within tmk_core/common/ ([#14972](https://github.com/qmk/qmk_firmware/pull/14972)) -* Move LTO logic from common.mk ([#14973](https://github.com/qmk/qmk_firmware/pull/14973)) -* More platform/protocol alignment ([#14976](https://github.com/qmk/qmk_firmware/pull/14976)) -* Add support to persist MD LED framework settings ([#14980](https://github.com/qmk/qmk_firmware/pull/14980)) -* Enable configuration of PWM frequency for IS31FL3733B ([#14983](https://github.com/qmk/qmk_firmware/pull/14983)) -* Remove `BOOTMAGIC_ENABLE = lite` option ([#15002](https://github.com/qmk/qmk_firmware/pull/15002)) -* Manually format develop ([#15003](https://github.com/qmk/qmk_firmware/pull/15003)) -* Require explicit enabling of RGB Matrix modes ([#15018](https://github.com/qmk/qmk_firmware/pull/15018)) -* Remove deprecated KEYMAP alias ([#15037](https://github.com/qmk/qmk_firmware/pull/15037)) -* Fix uart function prototypes ([#15162](https://github.com/qmk/qmk_firmware/pull/15162)) -* Rename RGB fractal ([#15174](https://github.com/qmk/qmk_firmware/pull/15174)) -* Format code according to conventions ([#15195](https://github.com/qmk/qmk_firmware/pull/15195)) -* Format code according to conventions ([#15196](https://github.com/qmk/qmk_firmware/pull/15196)) -* Add uint to char functions ([#15244](https://github.com/qmk/qmk_firmware/pull/15244)) -* [Tests] Increase QMK test coverage take 2 ([#15269](https://github.com/qmk/qmk_firmware/pull/15269)) -* Tidy up adjustable ws2812 timing ([#15299](https://github.com/qmk/qmk_firmware/pull/15299)) -* Add script for performing compilation size regression investigations. ([#15303](https://github.com/qmk/qmk_firmware/pull/15303)) -* WB32F3G71 config migration with removal of unnecessary items. ([#15309](https://github.com/qmk/qmk_firmware/pull/15309)) -* Re-add encoder tests ([#15312](https://github.com/qmk/qmk_firmware/pull/15312)) - -CLI: -* Add check for non-assignment code in rules.mk ([#12108](https://github.com/qmk/qmk_firmware/pull/12108)) -* Export list of `develop` PRs to be merged into `master` ([#13944](https://github.com/qmk/qmk_firmware/pull/13944)) -* remove qmk console, which is now part of the global cli ([#14206](https://github.com/qmk/qmk_firmware/pull/14206)) -* New CLI subcommand to create clang-compatible compilation database (`compile_commands.json`) ([#14370](https://github.com/qmk/qmk_firmware/pull/14370)) -* compiledb: query include paths from gcc directly. ([#14462](https://github.com/qmk/qmk_firmware/pull/14462)) - -Submodule updates: -* Update to ChibiOS 20.3.4, support builds against trunk ([#14208](https://github.com/qmk/qmk_firmware/pull/14208)) -* Update ChibiOS-Contrib ([#14408](https://github.com/qmk/qmk_firmware/pull/14408)) -* Update ChibiOS-Contrib ([#14419](https://github.com/qmk/qmk_firmware/pull/14419)) -* Purge uGFX. ([#14720](https://github.com/qmk/qmk_firmware/pull/14720)) - -Keyboards: -* Add support for PaladinPad, Arya pcb and move keyboards by KapCave into their own directory ([#14194](https://github.com/qmk/qmk_firmware/pull/14194)) -* Move non-assignment code to post_rules.mk ([#14207](https://github.com/qmk/qmk_firmware/pull/14207)) -* Helix use `post_rules.mk` ([#14216](https://github.com/qmk/qmk_firmware/pull/14216)) -* handwired/symmetric70_proto use post_rules.mk ([#14235](https://github.com/qmk/qmk_firmware/pull/14235)) -* Add Adelais PCB. Adelais RGB rev.3, Adelais rev. 4 APM32F103, Adelais AVR rev. 1 ([#14252](https://github.com/qmk/qmk_firmware/pull/14252)) -* GMMK Pro keymap ([#14389](https://github.com/qmk/qmk_firmware/pull/14389)) -* Migrate boston_meetup/2019 away from QWIIC_DRIVERS ([#14413](https://github.com/qmk/qmk_firmware/pull/14413)) -* Migrate hadron away from QWIIC_DRIVERS ([#14415](https://github.com/qmk/qmk_firmware/pull/14415)) -* Enable Proton C defaults for SplitKB Kyria ([#14490](https://github.com/qmk/qmk_firmware/pull/14490)) -* Set USB max power consumption of kint* controllers to 100mA ([#14546](https://github.com/qmk/qmk_firmware/pull/14546)) -* Remove complex `fn_actions` macros ([#14662](https://github.com/qmk/qmk_firmware/pull/14662)) -* New Keyboard: TGR Jane CE ([#14713](https://github.com/qmk/qmk_firmware/pull/14713)) -* Migrate satisfaction75 away from QWIIC_DRIVERS ([#14747](https://github.com/qmk/qmk_firmware/pull/14747)) -* add Lefty keyboard ([#14898](https://github.com/qmk/qmk_firmware/pull/14898)) -* overnumpad controller: Add support for turning off solenoid enable in low power. ([#15021](https://github.com/qmk/qmk_firmware/pull/15021)) -* Reduce compile size for melgeek mach80 ([#15034](https://github.com/qmk/qmk_firmware/pull/15034)) -* Update updated KPrepublic boards to be prepared for the update ([#15040](https://github.com/qmk/qmk_firmware/pull/15040)) -* rename kprepublic bm keyboards to have a standardized naming format ([#15047](https://github.com/qmk/qmk_firmware/pull/15047)) -* matrix/abelx - Update ChibiOS conf files ([#15130](https://github.com/qmk/qmk_firmware/pull/15130)) -* Disable console on Keebio foldkb and iris rev3 ([#15260](https://github.com/qmk/qmk_firmware/pull/15260)) -* Disable console on Sofle default keymap ([#15261](https://github.com/qmk/qmk_firmware/pull/15261)) -* Disable features on SplitKB boards to fit under size ([#15262](https://github.com/qmk/qmk_firmware/pull/15262)) -* Enable LTO on viktus/sp_mini via keymap ([#15263](https://github.com/qmk/qmk_firmware/pull/15263)) - -Keyboard fixes: -* Fix number of elements in info.json does not match errors ([#14213](https://github.com/qmk/qmk_firmware/pull/14213)) -* Fix typos from 14248 ([#14261](https://github.com/qmk/qmk_firmware/pull/14261)) -* Stream cheap via fixes/updates ([#14325](https://github.com/qmk/qmk_firmware/pull/14325)) -* Map `PRODUCT` define to `keyboard_name` ([#14372](https://github.com/qmk/qmk_firmware/pull/14372)) -* Fix BT rules for dosa40rgb ([#14497](https://github.com/qmk/qmk_firmware/pull/14497)) -* Fix typo in mechloving adelais header files ([#14590](https://github.com/qmk/qmk_firmware/pull/14590)) -* Fix for mechlovin/adelais/standard_led/arm/rev4 ([#14639](https://github.com/qmk/qmk_firmware/pull/14639)) -* Fix OLED timeout on recent qwiic migrations ([#14775](https://github.com/qmk/qmk_firmware/pull/14775)) -* Fix OLED timeout on satisfaction75 after migration from QWIIC ([#14780](https://github.com/qmk/qmk_firmware/pull/14780)) -* Fix Compile issues for lefty ([#14982](https://github.com/qmk/qmk_firmware/pull/14982)) -* Fix missing return for oled task on Lefty ([#15010](https://github.com/qmk/qmk_firmware/pull/15010)) -* Fix missing return for oled task on Arabica37 ([#15011](https://github.com/qmk/qmk_firmware/pull/15011)) -* Fix missing return for oled task in drashna userspace ([#15012](https://github.com/qmk/qmk_firmware/pull/15012)) -* Fix size issues on pistachio pro via keymap ([#15017](https://github.com/qmk/qmk_firmware/pull/15017)) -* Fix keycode collision in craftwalk keymap ([#15055](https://github.com/qmk/qmk_firmware/pull/15055)) -* Fix compilation issues for yanghu Unicorne ([#15068](https://github.com/qmk/qmk_firmware/pull/15068)) -* Fixup broken build after #15040 ([#15073](https://github.com/qmk/qmk_firmware/pull/15073)) -* Fix compilation issues for Lime ([#15116](https://github.com/qmk/qmk_firmware/pull/15116)) -* Fix additional board sizes for RGB Matrix ([#15170](https://github.com/qmk/qmk_firmware/pull/15170)) -* Fix bandominedoni via keymap compilation ([#15171](https://github.com/qmk/qmk_firmware/pull/15171)) -* Fix handful of boards compiling too large due to RGB matrix changes ([#15184](https://github.com/qmk/qmk_firmware/pull/15184)) -* Fix oled_task_user for ffkeebs/puca ([#15185](https://github.com/qmk/qmk_firmware/pull/15185)) -* More headroom. ([#15301](https://github.com/qmk/qmk_firmware/pull/15301)) -* More headroom. ([#15302](https://github.com/qmk/qmk_firmware/pull/15302)) - -Others: -* Clean up some code block languages ([#14434](https://github.com/qmk/qmk_firmware/pull/14434)) -* Clarify "nested" and "rolling" key sequences ([#14655](https://github.com/qmk/qmk_firmware/pull/14655)) -* CI: Create GitHub Actions unit test workflow ([#15223](https://github.com/qmk/qmk_firmware/pull/15223)) -* Squeezing space out of AVR ([#15243](https://github.com/qmk/qmk_firmware/pull/15243)) - -Bugs: -* Fix parallel builds w/ LTO on systems where make is not GNU make. ([#13955](https://github.com/qmk/qmk_firmware/pull/13955)) -* fix automatic directory for qmk lint ([#14215](https://github.com/qmk/qmk_firmware/pull/14215)) -* RN42 Bluetooth typo fix ([#14421](https://github.com/qmk/qmk_firmware/pull/14421)) -* fix typo in backlight code from #14439 ([#14442](https://github.com/qmk/qmk_firmware/pull/14442)) -* fix compilation issues with USB programmable buttons ([#14454](https://github.com/qmk/qmk_firmware/pull/14454)) -* Fix descriptor for USB Programmable Buttons ([#14455](https://github.com/qmk/qmk_firmware/pull/14455)) -* Make ChibiOS PAL interactions less STM32 specific - Round 2 ([#14456](https://github.com/qmk/qmk_firmware/pull/14456)) -* fix logical minimum in Programmable Button rdesc ([#14464](https://github.com/qmk/qmk_firmware/pull/14464)) -* Fix i2c_readReg16 ([#14730](https://github.com/qmk/qmk_firmware/pull/14730)) -* Put back eeconfig_update_ functions ([#14751](https://github.com/qmk/qmk_firmware/pull/14751)) -* Fix misplaced endif in led_matrix_drivers.c ([#14785](https://github.com/qmk/qmk_firmware/pull/14785)) -* Fix builds for ChibiOS + Cortex-M0[+] ([#14879](https://github.com/qmk/qmk_firmware/pull/14879)) -* Fix ccache default ([#14906](https://github.com/qmk/qmk_firmware/pull/14906)) -* Fix issues with Oneshot disabling ([#14934](https://github.com/qmk/qmk_firmware/pull/14934)) -* Fix develop after recent changes ([#14975](https://github.com/qmk/qmk_firmware/pull/14975)) -* Fix up issues shown by clang-format of vusb ([#15004](https://github.com/qmk/qmk_firmware/pull/15004)) -* Fix unterminated ifdef in ISSI 3733 driver ([#15014](https://github.com/qmk/qmk_firmware/pull/15014)) -* Fix build failures caused by #12947. ([#15019](https://github.com/qmk/qmk_firmware/pull/15019)) -* Fixup LED matrix. ([#15020](https://github.com/qmk/qmk_firmware/pull/15020)) -* Revert to old init order for host driver ([#15029](https://github.com/qmk/qmk_firmware/pull/15029)) -* Fixup #15029 ([#15031](https://github.com/qmk/qmk_firmware/pull/15031)) -* RISC-V toolchain and picolibc fixes ([#15109](https://github.com/qmk/qmk_firmware/pull/15109)) -* gcc10 LTO - Only specify adhlns assembler options at link time ([#15115](https://github.com/qmk/qmk_firmware/pull/15115)) -* Add needed include to pointing_device.c ([#15167](https://github.com/qmk/qmk_firmware/pull/15167)) -* Fix missing variable for Backlight Breathing ([#15199](https://github.com/qmk/qmk_firmware/pull/15199)) -* Revert backlight pins on function call ([#15205](https://github.com/qmk/qmk_firmware/pull/15205)) -* Fix timer include in override_wiring.c ([#15221](https://github.com/qmk/qmk_firmware/pull/15221)) -* fix broken macro in transport.h ([#15239](https://github.com/qmk/qmk_firmware/pull/15239)) -* Short term bodge for PRODUCT warning ([#15240](https://github.com/qmk/qmk_firmware/pull/15240)) -* Remove use of __flash due to LTO issues ([#15268](https://github.com/qmk/qmk_firmware/pull/15268)) -* Documentation typo fix ([#15298](https://github.com/qmk/qmk_firmware/pull/15298)) -* [Core] Hotfix for HOLD_ON_OTHER_KEY_PRESS after #11059 ([#15307](https://github.com/qmk/qmk_firmware/pull/15307)) -* Fix call to pointing_device_handle_buttons ([#15313](https://github.com/qmk/qmk_firmware/pull/15313)) -* [Develop] Fix ploopy readme typos ([#15316](https://github.com/qmk/qmk_firmware/pull/15316)) diff --git a/docs/ChangeLog/20220226.md b/docs/ChangeLog/20220226.md deleted file mode 100644 index a469612fe8b3..000000000000 --- a/docs/ChangeLog/20220226.md +++ /dev/null @@ -1,489 +0,0 @@ -# QMK Breaking Changes - 2022 February 26 Changelog - -## Notable Features :id=notable-features - -### Default USB Polling rate now 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352)) - -The default USB Polling rate has been aligned across supported platforms to now be 1ms/1kHz. - -Something something *Lets go gamers!* - -### Split support for pointing devices ([#15304](https://github.com/qmk/qmk_firmware/pull/15304)) - -Pointing devices can now be shared across a split keyboard with support for a single pointing device or a pointing device on each side. - -See the [Pointing Device](feature_pointing_device.md) documentation for further configuration options. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Legacy macro and action_function system removed ([#16025](https://github.com/qmk/qmk_firmware/pull/16025)) - -The long time deprecated `MACRO()` and `action_get_macro` methods have been removed. Where possible, existing usages have been migrated over to core [Macros](feature_macros.md). - -### Create a build error if no bootloader is specified ([#16181](https://github.com/qmk/qmk_firmware/pull/16181)) - -Bootloader configuration is no longer assumed. Keyboards must now set either: - -* `BOOTLOADER` within `rules.mk` -* `bootloader` within `info.json` - -### Rename `AdafruitBLE` to `BluefruitLE` ([#16127](https://github.com/qmk/qmk_firmware/pull/16127)) - -In preparation of future bluetooth work, the `AdafruitBLE` integration has been renamed to allow potential for any other Adafruit BLE products. - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|----------------------------|------------------------------------| -| 6ball | maple_computing/6ball | -| 7skb | salicylic_acid3/7skb | -| 7splus | salicylic_acid3/7splus | -| acr60 | mechkeys/acr60 | -| adalyn | tominabox1/adalyn | -| ajisai74 | salicylic_acid3/ajisai74 | -| aleth42 | 25keys/aleth42 | -| alicia_cook | ibnuda/alicia_cook | -| allison_numpad | prototypist/allison_numpad | -| allison | prototypist/allison | -| alu84 | mechkeys/alu84 | -| angel17 | kakunpc/angel17 | -| angel64/alpha | kakunpc/angel64/alpha | -| angel64/rev1 | kakunpc/angel64/rev1 | -| arch_36 | obosob/arch_36 | -| bakeneko60 | kkatano/bakeneko60 | -| bakeneko65/rev2 | kkatano/bakeneko65/rev2 | -| bakeneko65/rev3 | kkatano/bakeneko65/rev3 | -| bakeneko80 | kkatano/bakeneko80 | -| barleycorn | yiancardesigns/barleycorn | -| bat43/rev1 | dailycraft/bat43/rev1 | -| bat43/rev2 | dailycraft/bat43/rev2 | -| bigseries/1key | woodkeys/bigseries/1key | -| bigseries/2key | woodkeys/bigseries/2key | -| bigseries/3key | woodkeys/bigseries/3key | -| bigseries/4key | woodkeys/bigseries/4key | -| bkf | drhigsby/bkf | -| business_card/alpha | kakunpc/business_card/alpha | -| business_card/beta | kakunpc/business_card/beta | -| butterstick | gboards/butterstick | -| c39 | maple_computing/c39 | -| cassette42 | 25keys/cassette42 | -| chidori | kagizaraya/chidori | -| chili | ydkb/chili | -| chimera_ergo | glenpickle/chimera_ergo | -| chimera_ls | glenpickle/chimera_ls | -| chimera_ortho | glenpickle/chimera_ortho | -| chimera_ortho_plus | glenpickle/chimera_ortho_plus | -| choco60 | recompile_keys/choco60 | -| choc_taro | kakunpc/choc_taro | -| christmas_tree | maple_computing/christmas_tree | -| claw44/rev1 | dailycraft/claw44/rev1 | -| cocoa40 | recompile_keys/cocoa40 | -| comet46 | satt/comet46 | -| cu24 | capsunlocked/cu24 | -| cu75 | capsunlocked/cu75 | -| cu80 | capsunlocked/cu80/v1 | -| delilah | rainkeebs/delilah | -| diverge3 | unikeyboard/diverge3 | -| divergetm2 | unikeyboard/divergetm2 | -| dozen0 | yynmt/dozen0 | -| dubba175 | drhigsby/dubba175 | -| eggman | qpockets/eggman | -| ergo42 | biacco42/ergo42 | -| ergoarrows | salicylic_acid3/ergoarrows | -| ergodash/mini | omkbd/ergodash/mini | -| ergodash/rev1 | omkbd/ergodash/rev1 | -| ergodox_infinity | input_club/ergodox_infinity | -| ergotaco | gboards/ergotaco | -| espectro | mechkeys/espectro | -| felix | unikeyboard/felix | -| four_banger | bpiphany/four_banger | -| freyr | hnahkb/freyr | -| geminate60 | weirdo/geminate60 | -| georgi | gboards/georgi | -| gergo | gboards/gergo | -| getta25 | salicylic_acid3/getta25 | -| gingham | yiancardesigns/gingham | -| gurindam | ibnuda/gurindam | -| halberd | kagizaraya/halberd | -| hecomi/alpha | takashiski/hecomi/alpha | -| hid_liber | bpiphany/hid_liber | -| id67/default_rgb | idobao/id67/default_rgb | -| id67/rgb | idobao/id67/rgb | -| id80 | idobao/id80/v1 | -| id87 | idobao/id87/v1 | -| idobo | idobao/id75/v1 | -| infinity60 | input_club/infinity60 | -| ivy/rev1 | maple_computing/ivy/rev1 | -| jisplit89 | salicylic_acid3/jisplit89 | -| jnao | maple_computing/jnao | -| just60 | ydkb/just60 | -| kagamidget | yynmt/kagamidget | -| kelowna/rgb64 | weirdo/kelowna/rgb64 | -| kprepublic/bm65hsrgb_iso | kprepublic/bm65hsrgb_iso/rev1 | -| kprepublic/bm68hsrgb | kprepublic/bm68hsrgb/rev1 | -| k_type | input_club/k_type | -| latin17rgb | latincompass/latin17rgb | -| latin47ble | latincompass/latin47ble | -| latin60rgb | latincompass/latin60rgb | -| latin64ble | latincompass/latin64ble | -| latin6rgb | latincompass/latin6rgb | -| latinpadble | latincompass/latinpadble | -| latinpad | latincompass/latinpad | -| launchpad/rev1 | maple_computing/launchpad/rev1 | -| lck75 | lyso1/lck75 | -| le_chiffre | tominabox1/le_chiffre | -| lefishe | lyso1/lefishe | -| lets_split_eh/eh | maple_computing/lets_split_eh/eh | -| ls_60 | weirdo/ls_60 | -| m3n3van | matthewdias/m3n3van | -| mechmini/v1 | mechkeys/mechmini/v1 | -| mechmini/v2 | mechkeys/mechmini/v2 | -| meira | woodkeys/meira | -| meishi2 | biacco42/meishi2 | -| meishi | biacco42/meishi | -| minidox/rev1 | maple_computing/minidox/rev1 | -| minim | matthewdias/minim | -| mio | recompile_keys/mio | -| model_v | matthewdias/model_v | -| montex | idobao/montex/v1 | -| nafuda | salicylic_acid3/nafuda | -| naiping/np64 | weirdo/naiping/np64 | -| naiping/nphhkb | weirdo/naiping/nphhkb | -| naiping/npminila | weirdo/naiping/npminila | -| naked48 | salicylic_acid3/naked48 | -| naked60 | salicylic_acid3/naked60 | -| naked64 | salicylic_acid3/naked64 | -| namecard2x4 | takashiski/namecard2x4 | -| nebula12 | spaceholdings/nebula12 | -| nebula68b | spaceholdings/nebula68b | -| nebula68 | spaceholdings/nebula68 | -| niu_mini | kbdfans/niu_mini | -| nk1 | novelkeys/nk1 | -| nk65 | novelkeys/nk65 | -| nk87 | novelkeys/nk87 | -| nknl7en | salicylic_acid3/nknl7en | -| nknl7jp | salicylic_acid3/nknl7jp | -| nomu30 | recompile_keys/nomu30 | -| novelpad | novelkeys/novelpad | -| ogurec | drhigsby/ogurec | -| otaku_split/rev0 | takashiski/otaku_split/rev0 | -| otaku_split/rev1 | takashiski/otaku_split/rev1 | -| owl8 | dailycraft/owl8 | -| packrat | drhigsby/packrat | -| pistachio_mp | rate/pistachio_mp | -| pistachio_pro | rate/pistachio_pro | -| pistachio | rate/pistachio | -| plexus75 | checkerboards/plexus75 | -| pursuit40 | checkerboards/pursuit40 | -| qaz | tominabox1/qaz | -| quark | checkerboards/quark | -| rabbit_capture_plan | kakunpc/rabbit_capture_plan | -| rainkeeb | rainkeebs/rainkeeb | -| reviung33 | reviung/reviung33 | -| reviung34 | reviung/reviung34 | -| reviung39 | reviung/reviung39 | -| reviung41 | reviung/reviung41 | -| reviung53 | reviung/reviung53 | -| reviung5 | reviung/reviung5 | -| reviung61 | reviung/reviung61 | -| runner3680/3x6 | omkbd/runner3680/3x6 | -| runner3680/3x7 | omkbd/runner3680/3x7 | -| runner3680/3x8 | omkbd/runner3680/3x8 | -| runner3680/4x6 | omkbd/runner3680/4x6 | -| runner3680/4x7 | omkbd/runner3680/4x7 | -| runner3680/4x8 | omkbd/runner3680/4x8 | -| runner3680/5x6_5x8 | omkbd/runner3680/5x6_5x8 | -| runner3680/5x6 | omkbd/runner3680/5x6 | -| runner3680/5x7 | omkbd/runner3680/5x7 | -| runner3680/5x8 | omkbd/runner3680/5x8 | -| scarletbandana | woodkeys/scarletbandana | -| scythe | kagizaraya/scythe | -| seigaiha | yiancardesigns/seigaiha | -| setta21 | salicylic_acid3/setta21 | -| space_space/rev1 | qpockets/space_space/rev1 | -| space_space/rev2 | qpockets/space_space/rev2 | -| spiderisland/winry25tc | winry/winry25tc | -| splitreus62 | nacly/splitreus62 | -| squiggle/rev1 | ibnuda/squiggle/rev1 | -| standaside | edi/standaside | -| steal_this_keyboard | obosob/steal_this_keyboard | -| stella | hnahkb/stella | -| suihankey/alpha | kakunpc/suihankey/alpha | -| suihankey/rev1 | kakunpc/suihankey/rev1 | -| suihankey/split | kakunpc/suihankey/split | -| thedogkeyboard | kakunpc/thedogkeyboard | -| the_ruler | maple_computing/the_ruler | -| tiger910 | weirdo/tiger910 | -| treadstone32 | marksard/treadstone32 | -| treadstone48/rev1 | marksard/treadstone48/rev1 | -| treadstone48/rev2 | marksard/treadstone48/rev2 | -| txuu | matthewdias/txuu | -| ua62 | nacly/ua62 | -| underscore33/rev1 | tominabox1/underscore33/rev1 | -| underscore33/rev2 | tominabox1/underscore33/rev2 | -| vn66 | hnahkb/vn66 | -| wallaby | kkatano/wallaby | -| wanten | qpockets/wanten | -| whitefox | input_club/whitefox | -| wings42/rev1 | dailycraft/wings42/rev1 | -| wings42/rev1_extkeys | dailycraft/wings42/rev1_extkeys | -| wings42/rev2 | dailycraft/wings42/rev2 | -| yasui | rainkeebs/yasui | -| yd60mq | ymdk/yd60mq | -| yd68 | ydkb/yd68 | -| ymd75 | ymdk/ymd75 | -| ymd96 | ymdk/ymd96 | -| ymdk_np21 | ymdk/np21 | -| yurei | kkatano/yurei | -| zinc | 25keys/zinc | -| zinc/rev1 | 25keys/zinc/rev1 | -| zinc/reva | 25keys/zinc/reva | - -## Notable core changes :id=notable-core - -### New MCU Support :id=new-mcu-support - -Building on previous cycles, QMK firmware picked up support for a couple extra MCU variants: - -* STM32L432 -* STM32L442 - -### New Drivers - -QMK now has core-supplied support for the following device peripherals: - -#### LED - -* IS31FL3742A -* IS31FL3743A -* IS31FL3745 -* IS31FL3746A - -#### GPIO - -* SN74x138 -* mcp23018 - ---- - -## Full changelist - -Core: -* Initial pass at data driven new-keyboard subcommand ([#12795](https://github.com/qmk/qmk_firmware/pull/12795)) -* Don't send keyboard reports that propagate no changes to the host ([#14065](https://github.com/qmk/qmk_firmware/pull/14065)) -* Custom matrix lite support for split keyboards ([#14674](https://github.com/qmk/qmk_firmware/pull/14674)) -* Add sym_defer_pr debouncer type ([#14948](https://github.com/qmk/qmk_firmware/pull/14948)) -* Add RGB matrix & LED Matrix support for IS31FL3742A, IS31FL3743A, IS31FL3745, IS31FL3746A ([#14989](https://github.com/qmk/qmk_firmware/pull/14989)) -* New combo configuration options ([#15083](https://github.com/qmk/qmk_firmware/pull/15083)) -* IS31FL3733 driver for LED Matrix ([#15088](https://github.com/qmk/qmk_firmware/pull/15088)) -* Add open-drain GPIO support. ([#15282](https://github.com/qmk/qmk_firmware/pull/15282)) -* Make (un)register code functions weak ([#15285](https://github.com/qmk/qmk_firmware/pull/15285)) -* Split support for pointing devices. ([#15304](https://github.com/qmk/qmk_firmware/pull/15304)) -* Added cancel_key_lock function ([#15321](https://github.com/qmk/qmk_firmware/pull/15321)) -* Remove matrix_is_modified() and debounce_is_active() ([#15349](https://github.com/qmk/qmk_firmware/pull/15349)) -* Change default USB Polling rate to 1kHz ([#15352](https://github.com/qmk/qmk_firmware/pull/15352)) -* Implement MAGIC_TOGGLE_CONTROL_CAPSLOCK ([#15368](https://github.com/qmk/qmk_firmware/pull/15368)) -* Tidy up existing i2c_master implementations ([#15376](https://github.com/qmk/qmk_firmware/pull/15376)) -* Generalize Unicode defines ([#15409](https://github.com/qmk/qmk_firmware/pull/15409)) -* Added external spi flash driver. ([#15419](https://github.com/qmk/qmk_firmware/pull/15419)) -* Remove Deprecated USB Polling comment from vusb.c ([#15420](https://github.com/qmk/qmk_firmware/pull/15420)) -* Expand rotational range for PMW3360 Optical Sensor ([#15431](https://github.com/qmk/qmk_firmware/pull/15431)) -* ChibiOS SVN mirror script update ([#15435](https://github.com/qmk/qmk_firmware/pull/15435)) -* Refactor `bootloader_jump()` implementations ([#15450](https://github.com/qmk/qmk_firmware/pull/15450)) -* added missing audio_off_user() callback ([#15457](https://github.com/qmk/qmk_firmware/pull/15457)) -* Migrate serial_uart usages to UART driver ([#15479](https://github.com/qmk/qmk_firmware/pull/15479)) -* Migrate RN42 to UART driver and refactor ([#15492](https://github.com/qmk/qmk_firmware/pull/15492)) -* pwm3360 driver cleanup and diff reduction to adns9800 ([#15559](https://github.com/qmk/qmk_firmware/pull/15559)) -* Advanced deferred_exec for core-side code. ([#15579](https://github.com/qmk/qmk_firmware/pull/15579)) -* Adjust tap_code16 to account for TAP_HOLD_CAPS_DELAY ([#15635](https://github.com/qmk/qmk_firmware/pull/15635)) -* Slight tidy up of keyboard task loop ([#15725](https://github.com/qmk/qmk_firmware/pull/15725)) -* Unify the key up/down behaviour of RGB keycodes ([#15730](https://github.com/qmk/qmk_firmware/pull/15730)) -* Add PMW3389 optical sensor Support (Updated) ([#15740](https://github.com/qmk/qmk_firmware/pull/15740)) -* ChibiOS: add support for HID Programmable Buttons ([#15787](https://github.com/qmk/qmk_firmware/pull/15787)) -* ChibiOS: shorten USB disconnect state on boot to 50ms ([#15805](https://github.com/qmk/qmk_firmware/pull/15805)) -* Add init function to clear previous matrix effect ([#15815](https://github.com/qmk/qmk_firmware/pull/15815)) -* Optimize initialization of PMW3360 Sensor ([#15821](https://github.com/qmk/qmk_firmware/pull/15821)) -* Add Pixel Flow RGB matrix effect ([#15829](https://github.com/qmk/qmk_firmware/pull/15829)) -* PMW3389 Revert Firmware load during Initilization ([#15859](https://github.com/qmk/qmk_firmware/pull/15859)) -* Combo `TAP_CODE_DELAY` and `clear_weak_mods` ([#15866](https://github.com/qmk/qmk_firmware/pull/15866)) -* Relocate matrix_scan_quantum tasks ([#15882](https://github.com/qmk/qmk_firmware/pull/15882)) -* Adjust mouse key defaults ([#15883](https://github.com/qmk/qmk_firmware/pull/15883)) -* RGB Matrix: Reload from EEPROM ([#15923](https://github.com/qmk/qmk_firmware/pull/15923)) -* Enable a default task throttle for split pointing. ([#15925](https://github.com/qmk/qmk_firmware/pull/15925)) -* Move mcp23018 driver to core ([#15944](https://github.com/qmk/qmk_firmware/pull/15944)) -* Relocate matrix_init_quantum content ([#15953](https://github.com/qmk/qmk_firmware/pull/15953)) -* Align location of some host led logic ([#15954](https://github.com/qmk/qmk_firmware/pull/15954)) -* Rename some Quantum keycodes ([#15968](https://github.com/qmk/qmk_firmware/pull/15968)) -* Migrate more makefile utilities to builddefs sub-directory ([#16002](https://github.com/qmk/qmk_firmware/pull/16002)) -* Various Makefile optimisations ([#16015](https://github.com/qmk/qmk_firmware/pull/16015)) -* Add support for STM32L432, STM32L442. ([#16016](https://github.com/qmk/qmk_firmware/pull/16016)) -* EEPROM refactor: remove `eeprom_teensy.c` by default, use transient instead ([#16020](https://github.com/qmk/qmk_firmware/pull/16020)) -* Deprecate Split Transaction status field ([#16023](https://github.com/qmk/qmk_firmware/pull/16023)) -* Rip out old macro and action_function system ([#16025](https://github.com/qmk/qmk_firmware/pull/16025)) -* Add a script that simplifies running commands under docker. ([#16028](https://github.com/qmk/qmk_firmware/pull/16028)) -* Add support for Q-series on the ckled2001 LED driver ([#16051](https://github.com/qmk/qmk_firmware/pull/16051)) -* Remove unused suspend_idle ([#16063](https://github.com/qmk/qmk_firmware/pull/16063)) -* Initial migration of suspend callbacks ([#16067](https://github.com/qmk/qmk_firmware/pull/16067)) -* Add layout change callbacks to VIA ([#16087](https://github.com/qmk/qmk_firmware/pull/16087)) -* Rename `AdafruitBLE` to `BluefruitLE` ([#16127](https://github.com/qmk/qmk_firmware/pull/16127)) -* Update outputselect to use platform connected state API ([#16185](https://github.com/qmk/qmk_firmware/pull/16185)) -* Remove default pointing device driver. ([#16190](https://github.com/qmk/qmk_firmware/pull/16190)) -* Add SN74x138 demultiplexer driver ([#16217](https://github.com/qmk/qmk_firmware/pull/16217)) -* Standardise error output. ([#16220](https://github.com/qmk/qmk_firmware/pull/16220)) -* Followup to #16220, more test error output. ([#16221](https://github.com/qmk/qmk_firmware/pull/16221)) -* Misc size regression script improvements. ([#16268](https://github.com/qmk/qmk_firmware/pull/16268)) -* Align existing pca9555 driver to better match mcp23018 API ([#16277](https://github.com/qmk/qmk_firmware/pull/16277)) -* Size checks print out target firmware file instead ([#16290](https://github.com/qmk/qmk_firmware/pull/16290)) - -CLI: -* `develop` changelog generator: use the PR title instead ([#15537](https://github.com/qmk/qmk_firmware/pull/15537)) -* `develop` changelog generator: skip code formatting in listing ([#16215](https://github.com/qmk/qmk_firmware/pull/16215)) - -Keyboards: -* Durgod: Increase scan rate by using wait_us timer ([#14091](https://github.com/qmk/qmk_firmware/pull/14091)) -* Add another GMMK Pro ANSI Keymap with custom RGB. ([#14243](https://github.com/qmk/qmk_firmware/pull/14243)) -* Parse USB device version BCD ([#14580](https://github.com/qmk/qmk_firmware/pull/14580)) -* Add vitoni keymap for GMMK Pro (ISO) ([#15006](https://github.com/qmk/qmk_firmware/pull/15006)) -* Move bm65hsrgb_iso and bm68hsrgb to rev1/ to prepare for updates to the boards ([#15132](https://github.com/qmk/qmk_firmware/pull/15132)) -* Convert ergoinu to SPLIT_KEYBOARD ([#15305](https://github.com/qmk/qmk_firmware/pull/15305)) -* Convert not_so_minidox to SPLIT_KEYBOARD ([#15306](https://github.com/qmk/qmk_firmware/pull/15306)) -* Added new handwired keyboard Wakizashi 40 ([#15336](https://github.com/qmk/qmk_firmware/pull/15336)) -* Convert ai03/orbit to SPLIT_KEYBOARD ([#15340](https://github.com/qmk/qmk_firmware/pull/15340)) -* Remove manual enable of LTO within user keymaps ([#15378](https://github.com/qmk/qmk_firmware/pull/15378)) -* Move to organization folder ([#15481](https://github.com/qmk/qmk_firmware/pull/15481)) -* Convert some more boards to Matrix Lite ([#15489](https://github.com/qmk/qmk_firmware/pull/15489)) -* Organize Reviung boards into a directory ([#15636](https://github.com/qmk/qmk_firmware/pull/15636)) -* move winry25tc to winry/ ([#15637](https://github.com/qmk/qmk_firmware/pull/15637)) -* Rename ymdk_np21 to np21 + move to ymdk vendor folder ([#15641](https://github.com/qmk/qmk_firmware/pull/15641)) -* move ymd96 to ymdk vendor folder ([#15643](https://github.com/qmk/qmk_firmware/pull/15643)) -* move ymd75 to ymdk vendor folder ([#15645](https://github.com/qmk/qmk_firmware/pull/15645)) -* move yd60mq to ymdk vendor folder ([#15647](https://github.com/qmk/qmk_firmware/pull/15647)) -* rename idobo to idobao/id75, move to vendor folder ([#15661](https://github.com/qmk/qmk_firmware/pull/15661)) -* move ID67 to IDOBAO vendor folder ([#15662](https://github.com/qmk/qmk_firmware/pull/15662)) -* move ID80 to IDOBAO vendor folder ([#15665](https://github.com/qmk/qmk_firmware/pull/15665)) -* move ID87 to IDOBAO vendor folder ([#15667](https://github.com/qmk/qmk_firmware/pull/15667)) -* move montex to IDOBAO vendor folder ([#15668](https://github.com/qmk/qmk_firmware/pull/15668)) -* move @yangdigi 's keyboards to a YDKB folder ([#15681](https://github.com/qmk/qmk_firmware/pull/15681)) -* move @kkatano 's keyboards to kkatano user folder ([#15684](https://github.com/qmk/qmk_firmware/pull/15684)) -* Sol 3 Keyboard from RGBKB ([#15687](https://github.com/qmk/qmk_firmware/pull/15687)) -* move cu24, cu75, cu80/v1 into capsunlocked folder ([#15758](https://github.com/qmk/qmk_firmware/pull/15758)) -* move mechkeys keyboards into the mechkeys/ vendor folder ([#15760](https://github.com/qmk/qmk_firmware/pull/15760)) -* move @lyso1 's boards into lyso1/ ([#15767](https://github.com/qmk/qmk_firmware/pull/15767)) -* move prototypist boards into vendor folder ([#15780](https://github.com/qmk/qmk_firmware/pull/15780)) -* move @yiancar 's boards into yiancardesigns/ ([#15781](https://github.com/qmk/qmk_firmware/pull/15781)) -* move novelkeys keyboards to vendor folder ([#15783](https://github.com/qmk/qmk_firmware/pull/15783)) -* move @weirdo-f 's keyboards into weirdo/ ([#15785](https://github.com/qmk/qmk_firmware/pull/15785)) -* move @marksard 's boards to marksard/ ([#15786](https://github.com/qmk/qmk_firmware/pull/15786)) -* move input club keyboards into vendor folder ([#15788](https://github.com/qmk/qmk_firmware/pull/15788)) -* move @monksoffunk 's boards into 25keys/ ([#15789](https://github.com/qmk/qmk_firmware/pull/15789)) -* move @Salicylic-acid3 's keyboards to salicylic-acid3/ ([#15791](https://github.com/qmk/qmk_firmware/pull/15791)) -* move @rainkeebs 's keyboards to rainkeebs/ ([#15797](https://github.com/qmk/qmk_firmware/pull/15797)) -* move standaside into edi/ ([#15798](https://github.com/qmk/qmk_firmware/pull/15798)) -* move @obosob 's boards into obosob/ ([#15799](https://github.com/qmk/qmk_firmware/pull/15799)) -* move @nacly 's boards to nacly/ ([#15801](https://github.com/qmk/qmk_firmware/pull/15801)) -* move @kakunpc 's keebs into kakunpc/ ([#15814](https://github.com/qmk/qmk_firmware/pull/15814)) -* move @qpocket 's keyboards to qpocket/ ([#15827](https://github.com/qmk/qmk_firmware/pull/15827)) -* BDN9 keymap ([#15924](https://github.com/qmk/qmk_firmware/pull/15924)) -* move @matthewdias 's keebs into matthewdias/ ([#15991](https://github.com/qmk/qmk_firmware/pull/15991)) -* move id80 and id75 to v1 to accommodate for id75 v2 and id80 v3 ([#15992](https://github.com/qmk/qmk_firmware/pull/15992)) -* Remove `action_function()` from LFKeyboards boards ([#15993](https://github.com/qmk/qmk_firmware/pull/15993)) -* move @latincompass (aka @18438880 , @haierwangwei2005)'s boards to /latincompass ([#16039](https://github.com/qmk/qmk_firmware/pull/16039)) -* move g heavy industry boards into /gboards ([#16040](https://github.com/qmk/qmk_firmware/pull/16040)) -* move @drhigsby 's boards into /drhigsby ([#16041](https://github.com/qmk/qmk_firmware/pull/16041)) -* More keyboard rules.mk cleanups ([#16044](https://github.com/qmk/qmk_firmware/pull/16044)) -* move @That-Canadian 's boards into /maple_computing ([#16050](https://github.com/qmk/qmk_firmware/pull/16050)) -* move @takai 's keyboards into /recompile_keys ([#16053](https://github.com/qmk/qmk_firmware/pull/16053)) -* move @satt99 's comet46 to satt/ ([#16059](https://github.com/qmk/qmk_firmware/pull/16059)) -* move @ka2hiro 's boards into /kagizaraya ([#16070](https://github.com/qmk/qmk_firmware/pull/16070)) -* move @GlenPickle 's chimera* boards into a folder ([#16072](https://github.com/qmk/qmk_firmware/pull/16072)) -* move @yynmt 's boards into /yynmt ([#16075](https://github.com/qmk/qmk_firmware/pull/16075)) -* move @Biacco42 's keebs into /biacco42 ([#16080](https://github.com/qmk/qmk_firmware/pull/16080)) -* move unikeyboard boards to /unikeyboard ([#16081](https://github.com/qmk/qmk_firmware/pull/16081)) -* move four_banger to bpiphany ([#16082](https://github.com/qmk/qmk_firmware/pull/16082)) -* move @takashiski 's keebs into /takashiski ([#16089](https://github.com/qmk/qmk_firmware/pull/16089)) -* move hid_liber to /bpiphany ([#16091](https://github.com/qmk/qmk_firmware/pull/16091)) -* move spaceholdings boards into /spaceholdings ([#16096](https://github.com/qmk/qmk_firmware/pull/16096)) -* move @7-rate 's keebs to /rate ([#16099](https://github.com/qmk/qmk_firmware/pull/16099)) -* move @npspears 's boards into /checkerboards ([#16100](https://github.com/qmk/qmk_firmware/pull/16100)) -* move @vuhopkep 's keebs into /hnahkb ([#16102](https://github.com/qmk/qmk_firmware/pull/16102)) -* move @ibnuda 's keebs into /ibnuda ([#16108](https://github.com/qmk/qmk_firmware/pull/16108)) -* move @tominabox1 's keebs into /tominabox1 ([#16109](https://github.com/qmk/qmk_firmware/pull/16109)) -* move niu_mini to /kbdfans ([#16112](https://github.com/qmk/qmk_firmware/pull/16112)) -* move woodkeys.click keyboards to /woodkeys ([#16113](https://github.com/qmk/qmk_firmware/pull/16113)) -* move @omkbd 's boards to /omkbd ([#16116](https://github.com/qmk/qmk_firmware/pull/16116)) -* Overhaul Tractyl Manuform ([#16134](https://github.com/qmk/qmk_firmware/pull/16134)) -* Reduce firmware size for dztech/dz60rgb_wkl/v2_1:via ([#16254](https://github.com/qmk/qmk_firmware/pull/16254)) - -Keyboard fixes: -* Fix build failure for UT47 ([#15483](https://github.com/qmk/qmk_firmware/pull/15483)) -* Update grs_70ec to use newer custom matrix ([#15609](https://github.com/qmk/qmk_firmware/pull/15609)) -* fix compiler issue with Tractyl Manuform 4x6 ([#15646](https://github.com/qmk/qmk_firmware/pull/15646)) -* Fix CI. ([#15828](https://github.com/qmk/qmk_firmware/pull/15828)) -* Yet another bad `DEFAULT_FOLDER` fix. ([#15904](https://github.com/qmk/qmk_firmware/pull/15904)) -* Fix build failures for `mschwingen/modelm` ([#15987](https://github.com/qmk/qmk_firmware/pull/15987)) -* `rocketboard_16`: Fix mismatched LUT sizes ([#15997](https://github.com/qmk/qmk_firmware/pull/15997)) -* Fix erroneous SRC for Clueboard 66 hotswap ([#16007](https://github.com/qmk/qmk_firmware/pull/16007)) -* Fix handwired/ms_sculpt_mobile default keymap ([#16032](https://github.com/qmk/qmk_firmware/pull/16032)) -* Re-org Hillside folders as new model prep. Fix default keymap. ([#16128](https://github.com/qmk/qmk_firmware/pull/16128)) -* Fix up default folder locations. Again. ([#16135](https://github.com/qmk/qmk_firmware/pull/16135)) -* Sol3 rgb fix ([#16157](https://github.com/qmk/qmk_firmware/pull/16157)) -* Add missing `BOOTLOADER` for a handful of boards ([#16225](https://github.com/qmk/qmk_firmware/pull/16225)) -* Remove half implemented micronucleus bootloader support ([#16252](https://github.com/qmk/qmk_firmware/pull/16252)) -* Fixup bootloaders. ([#16256](https://github.com/qmk/qmk_firmware/pull/16256)) -* Fix idobao/id80/v3 compilation errors ([#16280](https://github.com/qmk/qmk_firmware/pull/16280)) -* Remove parent-relative paths from keyboards. ([#16282](https://github.com/qmk/qmk_firmware/pull/16282)) -* Bodge for helix build failures ([#16376](https://github.com/qmk/qmk_firmware/pull/16376)) - -Others: -* Add a clarification to an error message ([#15207](https://github.com/qmk/qmk_firmware/pull/15207)) -* Clang-format tweaks ([#15906](https://github.com/qmk/qmk_firmware/pull/15906)) -* Add example implementations for compatible MCUs list ([#15935](https://github.com/qmk/qmk_firmware/pull/15935)) -* Add version.h to gitignore ([#16222](https://github.com/qmk/qmk_firmware/pull/16222)) -* Update keyboard mapping for all moved boards this cycle ([#16312](https://github.com/qmk/qmk_firmware/pull/16312)) -* Align docs to new-keyboard behaviour ([#16357](https://github.com/qmk/qmk_firmware/pull/16357)) -* Align new-keyboard with recent schema updates ([#16378](https://github.com/qmk/qmk_firmware/pull/16378)) - -Bugs: -* Fixes potential wpm sampling overflow, along with code comment fixes ([#15277](https://github.com/qmk/qmk_firmware/pull/15277)) -* Add missing define for unicode common ([#15416](https://github.com/qmk/qmk_firmware/pull/15416)) -* Fix for SPI write timing in PMW3360 driver ([#15519](https://github.com/qmk/qmk_firmware/pull/15519)) -* Documentation Typo fix ([#15538](https://github.com/qmk/qmk_firmware/pull/15538)) -* fix a typo ([#15557](https://github.com/qmk/qmk_firmware/pull/15557)) -* Fix avr serial compile ([#15589](https://github.com/qmk/qmk_firmware/pull/15589)) -* More AVR GPIO compilation fixes. ([#15592](https://github.com/qmk/qmk_firmware/pull/15592)) -* Fix bug and code regression for Split Common ([#15603](https://github.com/qmk/qmk_firmware/pull/15603)) -* Include missing string.h include in split ([#15606](https://github.com/qmk/qmk_firmware/pull/15606)) -* Fixes for bootloader refactor build failures ([#15638](https://github.com/qmk/qmk_firmware/pull/15638)) -* Update pmw3360 driver after reading the datasheet top to bottom. Fix some outdated refs. ([#15682](https://github.com/qmk/qmk_firmware/pull/15682)) -* Fix split pointing for analog joystick ([#15691](https://github.com/qmk/qmk_firmware/pull/15691)) -* Fix broken bootloader builds in develop. ([#15880](https://github.com/qmk/qmk_firmware/pull/15880)) -* Fix optical sensor firmware upload ([#15919](https://github.com/qmk/qmk_firmware/pull/15919)) -* Pass in the keyrecord_t of the dual-role/tapping key when calling per-key tap hold functions ([#15938](https://github.com/qmk/qmk_firmware/pull/15938)) -* fixed typo in orange HSV colors decalartion ([#15976](https://github.com/qmk/qmk_firmware/pull/15976)) -* Fix hack for chibiOS reset name ([#15984](https://github.com/qmk/qmk_firmware/pull/15984)) -* Fix right side ws2812 leds having two indices ([#15985](https://github.com/qmk/qmk_firmware/pull/15985)) -* Workaround in Makefile for recursive rule matching ([#15988](https://github.com/qmk/qmk_firmware/pull/15988)) -* Fix BACKLIGHT_CAPS_LOCK warning ([#15999](https://github.com/qmk/qmk_firmware/pull/15999)) -* Fix compilation issues for led indicators ([#16001](https://github.com/qmk/qmk_firmware/pull/16001)) -* ChibiOS timer fixes ([#16017](https://github.com/qmk/qmk_firmware/pull/16017)) -* Fix bootloader_jump for certain CTRL boards ([#16026](https://github.com/qmk/qmk_firmware/pull/16026)) -* Fix up issue with PROGMEM and hand_swap_config ([#16027](https://github.com/qmk/qmk_firmware/pull/16027)) -* Don't make EEPROM size assumptions with dynamic keymaps. ([#16054](https://github.com/qmk/qmk_firmware/pull/16054)) -* fix missed .noci in reviung move ([#16107](https://github.com/qmk/qmk_firmware/pull/16107)) -* Fix issues with Python Tests ([#16162](https://github.com/qmk/qmk_firmware/pull/16162)) -* Fixup multibuild filegen ([#16166](https://github.com/qmk/qmk_firmware/pull/16166)) -* Remove old .gitignore entry. Add more macOS junk exclusions. ([#16167](https://github.com/qmk/qmk_firmware/pull/16167)) -* Fixup builds so that teensy EEPROM knows which MCU it's targeting. ([#16168](https://github.com/qmk/qmk_firmware/pull/16168)) -* Create a build error if no bootloader is specified. ([#16181](https://github.com/qmk/qmk_firmware/pull/16181)) -* Ensure `version.h` is recreated each build. ([#16188](https://github.com/qmk/qmk_firmware/pull/16188)) -* Add `custom` to list of valid bootloader types in info.json ([#16228](https://github.com/qmk/qmk_firmware/pull/16228)) -* Fix `layer_state` restoration at end of dynamic macro feature #16208 ([#16230](https://github.com/qmk/qmk_firmware/pull/16230)) -* Minor additions #12795 ([#16276](https://github.com/qmk/qmk_firmware/pull/16276)) -* Various fixes for matrix _RIGHT handling ([#16292](https://github.com/qmk/qmk_firmware/pull/16292)) -* Fix slashes in build_full_test.mk ([#16300](https://github.com/qmk/qmk_firmware/pull/16300)) -* ps2/avr: use the correct file name ([#16316](https://github.com/qmk/qmk_firmware/pull/16316)) -* Fix compilation of ChibiOS UART driver ([#16348](https://github.com/qmk/qmk_firmware/pull/16348)) -* Various fixes for new-keyboard ([#16358](https://github.com/qmk/qmk_firmware/pull/16358)) -* Allow NO_PIN within data driven configuration ([#16359](https://github.com/qmk/qmk_firmware/pull/16359)) diff --git a/docs/ChangeLog/20220528.md b/docs/ChangeLog/20220528.md deleted file mode 100644 index 1265c81206df..000000000000 --- a/docs/ChangeLog/20220528.md +++ /dev/null @@ -1,216 +0,0 @@ -# QMK Breaking Changes - 2022 May 28 Changelog - -## Notable Features :id=notable-features - -### Caps Word ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) :id=caps-word - -This is a new feature that allows for capslock-like functionality that turns itself off at the end of the word. - -For instance, if you wish to type "QMK" without holding shift the entire time, you can either tap both left and right shift, or double-tap shift, to turn on _Caps Word_ -- then type `qmk` (lowercase) without holding shift. Once you hit any key other than `a`--`z`, `0`--`9`, `-`, `_`, delete, or backspace, this will go back to normal typing! - -There are other activation mechanisms as well as configurable options like timeout and the like -- see the [Caps Word documentation](feature_caps_word.md) for more information. - -### Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) :id=quantum-painter - -QMK has had support for small OLED displays for some time now, but hasn't really gained too much ability to draw to panels other than the SSD1306 or SH1106 panels. - -Quantum Painter is a new drawing subsystem available to suitable ARM and RISC-V boards that is capable of drawing to large panel RGB LCDs and RGB OLEDs. It also allows for a lot more flexibility with a larger set of drawing APIs -- lines, rectangles, circles, ellipses, text, images, and even animations. - -The QMK CLI has new commands added to be able to generate images and fonts for Quantum Painter to digest -- it's even capable of converting animated gifs for display on screen. - -See the [Quantum Painter documentation](quantum_painter.md) for more information on how to set up the displays as well as how to convert images and fonts. - -!> Quantum Painter is not supported on AVR due to complexity and size constraints. Boards based on AVR such as ProMicro or Elite-C builds will not be able to leverage Quantum Painter. - -### Encoder Mapping ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) :id=encoder-mapping - -One of the long-standing complaints with Encoders is that there has been no easy way to configure them in user keymaps. [#13286](https://github.com/qmk/qmk_firmware/pull/13286) added support for [Encoder Mapping](feature_encoders.md#encoder-map), which allows users to define encoder functionality in a similar way to their normal keymap. - -!> This is not yet supported by QMK Configurator. It is also unlikely to ever be supported by VIA. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### `RESET` => `QK_BOOT` ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) :id=reset-2-qk_boot - -QMK is always in the process of picking up support for new hardware platforms. One of the side-effects for future integrations has shown that QMK's usage of `RESET` as a keycode is causing naming collisions. As a result, [#17037](https://github.com/qmk/qmk_firmware/pull/17037) changed usages of `RESET` to the new keycode `QK_BOOT` in the majority of default-like keymaps. At this stage the old keycode is still usable but will likely be removed in the next breaking changes cycle. Users with keymaps containing `RESET` should also move to `QK_BOOT`. - -### Sendstring keycode overhaul ([#16941](https://github.com/qmk/qmk_firmware/pull/16941)) :id=sendstring-keycodes - -Some keycodes used with `SEND_STRING` and its relatives have been deprecated and may have their old keycode usages removed at a later date. The list of [deprecated keycodes](https://github.com/qmk/qmk_firmware/blob/ebd402788346aa6e88bde1486b2a835684d40d39/quantum/send_string_keycodes.h#L456-L505) should be consulted to determine if you're using one of the older names (the first identifier after `#define`) -- you should swap to the newer variant (the second identifier on the same line). - -### Pillow Installation ([#17133](https://github.com/qmk/qmk_firmware/pull/17133)) :id=pillow-install - -The merge of Quantum Painter added some new dependencies in the QMK CLI, most notably _Pillow_, which requires some installation in order for the CLI to function. If you've got an existing installation, you'll need to run some commands in order to get things working: - -On Windows, if using _QMK MSYS_ or _msys2_, you'll need to run the following command: - -```sh -pacman --needed --noconfirm --disable-download-timeout -S mingw-w64-x86_64-python-pillow -python3 -m pip install --upgrade qmk -``` - -On macOS: - -```sh -brew update -brew upgrade qmk/qmk/qmk -``` - -On Linux or WSL: - -```sh -python3 -m pip install --user --upgrade qmk -``` - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|----------------------|--------------------| -| absinthe | keyhive/absinthe | -| amj40 | amjkeyboard/amj40 | -| amj60 | amjkeyboard/amj60 | -| amj96 | amjkeyboard/amj96 | -| amjpad | amjkeyboard/amjpad | -| at101_bh | viktus/at101_bh | -| ergosaurus | keyhive/ergosaurus | -| gmmk/pro/ansi | gmmk/pro/rev1/ansi | -| gmmk/pro/iso | gmmk/pro/rev1/iso | -| honeycomb | keyhive/honeycomb | -| lattice60 | keyhive/lattice60 | -| melody96 | ymdk/melody96 | -| mt40 | mt/mt40 | -| mt64rgb | mt/mt64rgb | -| mt84 | mt/mt84 | -| mt980 | mt/mt980 | -| navi10 | keyhive/navi10 | -| omnikey_bh | viktus/omnikey_bh | -| opus | keyhive/opus | -| smallice | keyhive/smallice | -| southpole | keyhive/southpole | -| uno | keyhive/uno | -| ut472 | keyhive/ut472 | -| wheatfield/blocked65 | mt/blocked65 | -| wheatfield/split75 | mt/split75 | -| z150_bh | viktus/z150_bh | - ---- - -## Full changelist :id=full-changelist - -Core: -* Quantum Painter ([#10174](https://github.com/qmk/qmk_firmware/pull/10174)) -* Add support for encoder mapping. ([#13286](https://github.com/qmk/qmk_firmware/pull/13286)) -* Add support for multiple switchs/solenoids to Haptic Feedback engine ([#15657](https://github.com/qmk/qmk_firmware/pull/15657)) -* Add compile/make macro to core ([#15959](https://github.com/qmk/qmk_firmware/pull/15959)) -* Add Reboot keycode to core ([#15990](https://github.com/qmk/qmk_firmware/pull/15990)) -* Add support for multiple sensors to pmw3360 ([#15996](https://github.com/qmk/qmk_firmware/pull/15996)) -* Asymmetric encoders, encoder tests. ([#16068](https://github.com/qmk/qmk_firmware/pull/16068)) -* Add hacky via support for RGB Matrix ([#16086](https://github.com/qmk/qmk_firmware/pull/16086)) -* Allow usage of AVRs minimal printf library ([#16266](https://github.com/qmk/qmk_firmware/pull/16266)) -* Squeeze AVR some more with `-mrelax` and `-mcall-prologues` ([#16269](https://github.com/qmk/qmk_firmware/pull/16269)) -* Heatmap incorrect matrix effect workaround ([#16315](https://github.com/qmk/qmk_firmware/pull/16315)) -* Add SN74x154 driver and convert AL1 custom matrix ([#16331](https://github.com/qmk/qmk_firmware/pull/16331)) -* Add customizable snake and knight animation increments ([#16337](https://github.com/qmk/qmk_firmware/pull/16337)) -* Chibios USB protocol: allow overriding RAW Capacity ([#16339](https://github.com/qmk/qmk_firmware/pull/16339)) -* HD44780 driver rework ([#16370](https://github.com/qmk/qmk_firmware/pull/16370)) -* Update wb32-dfu ([#16438](https://github.com/qmk/qmk_firmware/pull/16438)) -* Remove `send_unicode_hex_string()` ([#16518](https://github.com/qmk/qmk_firmware/pull/16518)) -* Add :flash target for UF2 bootloaders ([#16525](https://github.com/qmk/qmk_firmware/pull/16525)) -* Move `has_mouse_report_changed` function to `report.c` ([#16543](https://github.com/qmk/qmk_firmware/pull/16543)) -* Move Doxygen docs to subdirectory ([#16561](https://github.com/qmk/qmk_firmware/pull/16561)) -* Add Caps Word feature to core ([#16588](https://github.com/qmk/qmk_firmware/pull/16588)) -* Add non blackpill F4x1 config files ([#16600](https://github.com/qmk/qmk_firmware/pull/16600)) -* Force platform pin defs to be included ([#16611](https://github.com/qmk/qmk_firmware/pull/16611)) -* Refactor CTPC logic to allow future converters ([#16621](https://github.com/qmk/qmk_firmware/pull/16621)) -* Use a mutex guard for split shared memory ([#16647](https://github.com/qmk/qmk_firmware/pull/16647)) -* Rename TICK to TICK_EVENT ([#16649](https://github.com/qmk/qmk_firmware/pull/16649)) -* Add GET_TAPPING_TERM macro to reduce duplicate code ([#16681](https://github.com/qmk/qmk_firmware/pull/16681)) -* add the ability to change the pwm frequency for the IS31FL3737B ([#16718](https://github.com/qmk/qmk_firmware/pull/16718)) -* Joystick feature updates ([#16732](https://github.com/qmk/qmk_firmware/pull/16732)) -* Add emulated eeprom support for STM32F303xE ([#16737](https://github.com/qmk/qmk_firmware/pull/16737)) -* Refactor writePin to work with statements ([#16738](https://github.com/qmk/qmk_firmware/pull/16738)) -* Add mechanism to limit available converters ([#16783](https://github.com/qmk/qmk_firmware/pull/16783)) -* Implement XAP 'secure' core requirements ([#16843](https://github.com/qmk/qmk_firmware/pull/16843)) -* rgblight: Add functions to stop blinking one or all but one layer ([#16859](https://github.com/qmk/qmk_firmware/pull/16859)) -* Expose API for hardware unique ID ([#16869](https://github.com/qmk/qmk_firmware/pull/16869)) -* Added support for Wb32fq95 ([#16871](https://github.com/qmk/qmk_firmware/pull/16871)) -* Provide better config defaults for bluepill boards ([#16909](https://github.com/qmk/qmk_firmware/pull/16909)) -* Joystick: Simplify report descriptor and clean up error messages ([#16926](https://github.com/qmk/qmk_firmware/pull/16926)) -* Rename keymap_extras headers for consistency ([#16939](https://github.com/qmk/qmk_firmware/pull/16939)) -* Sendstring keycode overhaul ([#16941](https://github.com/qmk/qmk_firmware/pull/16941)) -* Move disable_jtag to platforms ([#16960](https://github.com/qmk/qmk_firmware/pull/16960)) -* Remove ARM pgm_read_word workaround in rgblight ([#16961](https://github.com/qmk/qmk_firmware/pull/16961)) -* Warn about LTO with arm_atsam, not ChibiOS. ([#17106](https://github.com/qmk/qmk_firmware/pull/17106)) - -CLI: -* Rework generate-api CLI command to use .build directory ([#16441](https://github.com/qmk/qmk_firmware/pull/16441)) -* Change data driven "str" type to represent a quoted string literal ([#16516](https://github.com/qmk/qmk_firmware/pull/16516)) -* Bump the 'jsonschema' version ([#16635](https://github.com/qmk/qmk_firmware/pull/16635)) -* Add frameworking for development board presets ([#16637](https://github.com/qmk/qmk_firmware/pull/16637)) -* Extend 'qmk info' to handle keymap level overrides ([#16702](https://github.com/qmk/qmk_firmware/pull/16702)) -* Data driven `g_led_config` ([#16728](https://github.com/qmk/qmk_firmware/pull/16728)) -* Allow new-keyboard to use development_board presets ([#16785](https://github.com/qmk/qmk_firmware/pull/16785)) -* Also format *.hpp files. ([#16997](https://github.com/qmk/qmk_firmware/pull/16997)) - -Submodule updates: -* ChibiOS 21.11.1 update. ([#16251](https://github.com/qmk/qmk_firmware/pull/16251)) -* Update ChibiOS-Contrib ([#16915](https://github.com/qmk/qmk_firmware/pull/16915)) - -Keyboards: -* chore: Add personal GMMK Pro keymap ([#15320](https://github.com/qmk/qmk_firmware/pull/15320)) -* move melody96 to ymdk vendor folder ([#15680](https://github.com/qmk/qmk_firmware/pull/15680)) -* move amj keyboards into amjkeyboard vendor folder ([#15733](https://github.com/qmk/qmk_firmware/pull/15733)) -* move z150_bh at101_bh omnikey_bh to viktus/ ([#16004](https://github.com/qmk/qmk_firmware/pull/16004)) -* MS Sculpt Mobile refactor ([#16038](https://github.com/qmk/qmk_firmware/pull/16038)) -* move keyhive exclusive boards into /keyhive ([#16084](https://github.com/qmk/qmk_firmware/pull/16084)) -* move 麦田 boards into /mt ([#16095](https://github.com/qmk/qmk_firmware/pull/16095)) -* Convert Wasdat Code custom matrix to SN74x138 driver ([#16257](https://github.com/qmk/qmk_firmware/pull/16257)) -* Move GMMK Pro to allow for multiple revisions ([#16423](https://github.com/qmk/qmk_firmware/pull/16423)) -* Updated pin mapping and readme. ([#16505](https://github.com/qmk/qmk_firmware/pull/16505)) -* Map data driven `DESCRIPTION` as string literal ([#16523](https://github.com/qmk/qmk_firmware/pull/16523)) -* remove unecessary layers ([#16559](https://github.com/qmk/qmk_firmware/pull/16559)) -* Helix/rev2 move to split common ([#16723](https://github.com/qmk/qmk_firmware/pull/16723)) -* Remove some layout exceptions ([#16957](https://github.com/qmk/qmk_firmware/pull/16957)) -* Refactor legacy quantum keycodes in default-ish keymaps ([#17037](https://github.com/qmk/qmk_firmware/pull/17037)) -* Refactor legacy quantum keycodes in default-ish keymaps ([#17150](https://github.com/qmk/qmk_firmware/pull/17150)) - -Keyboard fixes: -* gboards/gergoplex: move `COMBO_ENABLE` to keymap level ([#16667](https://github.com/qmk/qmk_firmware/pull/16667)) -* usb-usb converter: community layout support ([#16773](https://github.com/qmk/qmk_firmware/pull/16773)) -* Fix build of `keyhive/uno`. ([#16891](https://github.com/qmk/qmk_firmware/pull/16891)) -* Fix uno ([#16892](https://github.com/qmk/qmk_firmware/pull/16892)) -* converter/usb_usb: remove surplus commas ([#17024](https://github.com/qmk/qmk_firmware/pull/17024)) -* Various fixes for g_led_config lint warnings ([#17104](https://github.com/qmk/qmk_firmware/pull/17104)) - -Others: -* Add warning for CTPC/CONVERT_TO_PROTON_C. ([#16782](https://github.com/qmk/qmk_firmware/pull/16782)) -* Add bluepill/blackpill development board presets ([#16806](https://github.com/qmk/qmk_firmware/pull/16806)) -* Recommend pillow as part of manual MSYS install ([#17133](https://github.com/qmk/qmk_firmware/pull/17133)) - -Bugs: -* Fix one-shot locked modifiers ([#16114](https://github.com/qmk/qmk_firmware/pull/16114)) -* Fix missing definition for non-encoder case. ([#16593](https://github.com/qmk/qmk_firmware/pull/16593)) -* Fixup builds. ([#16596](https://github.com/qmk/qmk_firmware/pull/16596)) -* Missed some erroneous prints. ([#16597](https://github.com/qmk/qmk_firmware/pull/16597)) -* Workaround for pin_def errors on KINETIS based builds ([#16614](https://github.com/qmk/qmk_firmware/pull/16614)) -* Fix flipped logic bug with One Shot `OS_ON` / `OS_OFF` keys ([#16617](https://github.com/qmk/qmk_firmware/pull/16617)) -* Redo workaround for pin_def errors on KINETIS ([#16620](https://github.com/qmk/qmk_firmware/pull/16620)) -* Fix oneshot toggle logic ([#16630](https://github.com/qmk/qmk_firmware/pull/16630)) -* Mousekeys fix ([#16640](https://github.com/qmk/qmk_firmware/pull/16640)) -* Ignore transport defaults if SPLIT_KEYBOARD is unset ([#16706](https://github.com/qmk/qmk_firmware/pull/16706)) -* Fixes #16705 : digital rain follows val ([#16716](https://github.com/qmk/qmk_firmware/pull/16716)) -* Fix AVR backlight breathing: low brightness limit & exceeding breathing table max index ([#16770](https://github.com/qmk/qmk_firmware/pull/16770)) -* Fixed usb read loops not reading until timeout ([#16827](https://github.com/qmk/qmk_firmware/pull/16827)) -* [QP] Check BPP capabilities before loading the palette ([#16863](https://github.com/qmk/qmk_firmware/pull/16863)) -* Fix #16859. ([#16865](https://github.com/qmk/qmk_firmware/pull/16865)) -* Preinstall python dependencies before executing `qmk`. ([#16874](https://github.com/qmk/qmk_firmware/pull/16874)) -* Fixup AVR builds. ([#16875](https://github.com/qmk/qmk_firmware/pull/16875)) -* Fix kinetic mouse mode ([#16951](https://github.com/qmk/qmk_firmware/pull/16951)) -* Enhancement and fixes of "Secure" feature ([#16958](https://github.com/qmk/qmk_firmware/pull/16958)) -* Check for ongoing transfers on the OUT endpoint ([#16974](https://github.com/qmk/qmk_firmware/pull/16974)) -* MSYS2 install: add some Python dependencies through Pacman ([#17025](https://github.com/qmk/qmk_firmware/pull/17025)) -* Revert "Fix kinetic mouse mode (#16951)" ([#17095](https://github.com/qmk/qmk_firmware/pull/17095)) -* Workaround for recent -Werror=array-bounds AVR issues ([#17136](https://github.com/qmk/qmk_firmware/pull/17136)) -* Bug fix: Continue Caps Word when AltGr (right Alt) is held. ([#17156](https://github.com/qmk/qmk_firmware/pull/17156)) diff --git a/docs/ChangeLog/20220827.md b/docs/ChangeLog/20220827.md deleted file mode 100644 index b672b57cb893..000000000000 --- a/docs/ChangeLog/20220827.md +++ /dev/null @@ -1,343 +0,0 @@ -# QMK Breaking Changes - 2022 August 27 Changelog - -## Notable Features :id=notable-features - -### Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877), [#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17516](https://github.com/qmk/qmk_firmware/pull/17516), [#17519](https://github.com/qmk/qmk_firmware/pull/17519), [#17612](https://github.com/qmk/qmk_firmware/pull/17612), [#17512](https://github.com/qmk/qmk_firmware/pull/17512), [#17557](https://github.com/qmk/qmk_firmware/pull/17557), [#17817](https://github.com/qmk/qmk_firmware/pull/17817), [#17839](https://github.com/qmk/qmk_firmware/pull/17839), [#18100](https://github.com/qmk/qmk_firmware/pull/18100)) :id=rp2040-support - -QMK _finally_ picked up support for RP2040-based boards, such as the Raspberry Pi Pico, the Sparkfun Pro Micro RP2040, and the Adafruit KB2040. One of QMK's newest collaborators, _@KarlK90_, effectively did `/micdrop` with RP2040, with a massive set of changes to both QMK and the repository QMK uses for the base platform support, ChibiOS[-Contrib]. There has been a flurry of development this breaking changes cycle related to RP2040 from a large number of contributors -- so much so that almost all standard QMK hardware subsystems are supported. - -Check the [RP2040 platform development page](platformdev_rp2040.md) for all supported peripherals and other hardware implementation details. - -### Allow `qmk flash` to use prebuilt firmware binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) :id=cli-flash-binaries - -A long-requested capability of the QMK CLI has been the ability to flash binaries directly, without needing to build a firmware. QMK provides prebuilt `develop`-based default firmwares on our [CI page](https://qmk.tzarc.io/) -- normally people would need [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases/latest) to flash them. This new functionality written by _@Erovia_ allows `qmk flash` to be provided the prebuilt file instead, simplifying the workflow for people who haven't got Toolbox available. - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Default layers dropped from 32 to 16 ([#15286](https://github.com/qmk/qmk_firmware/pull/15286)) - -QMK allows for controlling the maximum number of layers it supports through `LAYER_STATE_(8|16|32)BIT`. Each definition allows for the same number of maximum layers -- `LAYER_STATE_8BIT` => 8 layers. There is also a corresponding firmware size decrease that goes along with smaller numbers -- given the vast majority of users don't use more than 16 layers the default has been swapped to 16. AVR users who were not previously specifying their max layer count may see some space freed up as a result. - -### `RESET` => `QK_BOOT` ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) :id=reset-2-qk_boot - -Following the last breaking changes cycle, QMK has been migrating usages of `RESET` to `QK_BOOT` due to naming collisions with our upstream board support packages. [#17940](https://github.com/qmk/qmk_firmware/pull/17940) converts user keymaps across to use the new keycode name. `RESET` should also move to `QK_BOOT`. - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|------------------------|--------------------------| -| gentleman65 | jkeys_design/gentleman65 | -| handwired/hillside/0_1 | handwired/hillside/48 | -| idobao/id80/v1/ansi | idobao/id80/v2/ansi | -| idobao/id80/v1/iso | idobao/id80/v2/iso | - -### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring - -QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, eventually leaving data-driven as the only method to specify USB information. - -A significant number of keyboards have already been changed on `master` in a like-for-like fashion, and [#18152](https://github.com/qmk/qmk_firmware/pull/18152) performs the same transformations for keyboards already on `develop`. - -Previously in `config.h`: -```c -#define VENDOR_ID 0x1234 -#define PRODUCT_ID 0x5678 -#define DEVICE_VER 0x0001 -#define MANUFACTURER Me -#define PRODUCT MyKeyboard -``` - -Replaced by `info.json`: -```json -{ - "keyboard_name": "MyKeyboard", - "manufacturer": "Me", - "usb": { - "vid": "0x1234", - "pid": "0x5678", - "device_version": "0.0.1" - }, - // ... layouts, etc. ... -} -``` - -#### Deprecation Schedule - -- From 2022 Aug 27, specifying USB information in `config.h` will produce warnings during build but will still function as previously. -- From 2022 Nov 26, specifying USB information in `config.h` will cause compilation to fail. - -## Notable core changes :id=notable-core - -### Board converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514), [#17603](https://github.com/qmk/qmk_firmware/pull/17603), [#17711](https://github.com/qmk/qmk_firmware/pull/17711), [#17827](https://github.com/qmk/qmk_firmware/pull/17827), [#17593](https://github.com/qmk/qmk_firmware/pull/17593), [#17652](https://github.com/qmk/qmk_firmware/pull/17652), [#17595](https://github.com/qmk/qmk_firmware/pull/17595)) :id=board-converters - -Historically QMK had a `CONVERT_TO_PROTON_C` directive for `rules.mk` to allow people to replace an AVR-based Pro Micro with a QMK Proton C. Global parts shortages have prompted people to create their own pin-compatible boards -- QMK has made this conversion generic and now allows for drop-in replacements for a lot more boards. see the [Converters Feature](feature_converters.md) documentation for the full list of supported replacement boards -- in this breaking changes cycle we've gone from 1 to 7. - -### Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) :id=cli-import - -To help with importing keyboards and keymaps from other sources, _@zvecr_ added [#16668](https://github.com/qmk/qmk_firmware/pull/16668) which adds a new set of commands to the CLI to automatically import keyboards (`qmk import-keyboard -h`), keymaps (`qmk import-keymap -h`), and kbfirmware definitions (`qmk import-kbfirmware -h`) into QMK. - -The now-EOL kbfirmware allowed people who aren't set up with QMK the ability to create keyboard firmwares without requiring a full installation of QMK. Unfortunately, it targets a 7-year-old version of QMK -- adding frustration for users who want the newest features, as well as for QMK maintainers who have to spend time explaining why QMK can't just accept a drive-by code drop from kbfirmware. With any luck, this new command helps both camps! - -### Generic wear-leveling for EEPROM emulation ([#16996](https://github.com/qmk/qmk_firmware/pull/16996), [#17376](https://github.com/qmk/qmk_firmware/pull/17376), [#18102](https://github.com/qmk/qmk_firmware/pull/18102)) :id=wear-leveling - -QMK has had the ability to write to internal MCU flash in order to emulate EEPROM for some time now, but it was only limited to a small number of MCUs. The base HAL used by QMK for a large number of ARM devices provides a "proper" embedded MCU flash driver, so _@tzarc_ decoupled the wear-leveling algorithm from the old flash writing code, improved it, wrote some tests, and enabled its use for a much larger number of other devices... including RP2040's XIP flash, and external SPI NOR Flash. - -See the [EEPROM Driver](eeprom_driver.md) documentation for more information. - -### Pointing Device Improvements ([#16371](https://github.com/qmk/qmk_firmware/pull/16371), [#17111](https://github.com/qmk/qmk_firmware/pull/17111), [#17176](https://github.com/qmk/qmk_firmware/pull/17176), [#17482](https://github.com/qmk/qmk_firmware/pull/17482), [#17776](https://github.com/qmk/qmk_firmware/pull/17776), [#17613](https://github.com/qmk/qmk_firmware/pull/17613)) :id=pointing-device-improvements - -Ever since Pointing Device Driver support and Split Pointing Device support were added by _@drashna_ and _@daskygit_, there has been increased interest in the development of the pointing device subsystem and its associated code. - -Both the PMW33xx and the Cirque Pinnacle implementations have seen a lot of improvement to their code, as has the mouse code in general. Features like circular/edge scrolling for the Cirque, and Kinetic movement for any sensor with "lift detection" ([#17482](https://github.com/qmk/qmk_firmware/pull/17482)). Additionally, for those that make fast motions with their pointing devices, support for much larger mouse movement reports has been added ([#16371](https://github.com/qmk/qmk_firmware/pull/16371)). - -Other related changes: - -* Add support for large Mouse Reports ([#16371](https://github.com/qmk/qmk_firmware/pull/16371)) -* Improve PS/2 mouse performance ([#17111](https://github.com/qmk/qmk_firmware/pull/17111)) -* Mouse key kinetic mode fix ([#17176](https://github.com/qmk/qmk_firmware/pull/17176)) -* Circular scroll, inertial cursor ([#17482](https://github.com/qmk/qmk_firmware/pull/17482)) -* Create generic Pointing Device Pin defines ([#17776](https://github.com/qmk/qmk_firmware/pull/17776)) -* PMW33XX drivers overhaul ([#17613](https://github.com/qmk/qmk_firmware/pull/17613)) - ---- - -## Full changelist :id=full-changelist - -Core: -* Tentative Teensy 3.5 support ([#14420](https://github.com/qmk/qmk_firmware/pull/14420)) -* Make default layer size 16-bit ([#15286](https://github.com/qmk/qmk_firmware/pull/15286)) -* Process all changed keys in one scan loop, deprecate `QMK_KEYS_PER_SCAN` ([#15292](https://github.com/qmk/qmk_firmware/pull/15292)) -* Do not enable PERMISSIVE_HOLD when TAPPING_TERM exceeds 500ms ([#15674](https://github.com/qmk/qmk_firmware/pull/15674)) -* Allow usage of ChibiOS's SIO driver for split keyboards ([#15907](https://github.com/qmk/qmk_firmware/pull/15907)) -* [Controller] Added board config for custom controller STeMCell ([#16287](https://github.com/qmk/qmk_firmware/pull/16287)) -* PoC: Swap Escape and Caps ([#16336](https://github.com/qmk/qmk_firmware/pull/16336)) -* Add support for large Mouse Reports ([#16371](https://github.com/qmk/qmk_firmware/pull/16371)) -* tap-dance: Restructure code and document in more detail ([#16394](https://github.com/qmk/qmk_firmware/pull/16394)) -* Teaching the CLI to flash binaries ([#16584](https://github.com/qmk/qmk_firmware/pull/16584)) -* Split ChibiOS usart split driver in protocol and hardware driver part ([#16669](https://github.com/qmk/qmk_firmware/pull/16669)) -* Added Wait time to sending each Keys for Dynamic Macros function ([#16800](https://github.com/qmk/qmk_firmware/pull/16800)) -* Added Delay time to sending each Keys for VIA Macros function feature ([#16810](https://github.com/qmk/qmk_firmware/pull/16810)) -* Improve avr wait_us() ([#16879](https://github.com/qmk/qmk_firmware/pull/16879)) -* Improve ENCODER_DEFAULT_POS to recognize lost ticks ([#16932](https://github.com/qmk/qmk_firmware/pull/16932)) -* Added emacs as an "operating system" for input mode. ([#16949](https://github.com/qmk/qmk_firmware/pull/16949)) -* 24LC32A EEPROM addition ([#16990](https://github.com/qmk/qmk_firmware/pull/16990)) -* Refactor steno and add `STENO_PROTOCOL = [all|txbolt|geminipr]` ([#17065](https://github.com/qmk/qmk_firmware/pull/17065)) -* improvements for Cirque Pinnacle trackpads ([#17091](https://github.com/qmk/qmk_firmware/pull/17091)) -* Use TAP_HOLD_CAPS_DELAY for KC_LOCKING_CAPS_LOCK ([#17099](https://github.com/qmk/qmk_firmware/pull/17099)) -* Improve PS/2 mouse performance ([#17111](https://github.com/qmk/qmk_firmware/pull/17111)) -* Update C standard to GNU11, C++ to GNU++14 ([#17114](https://github.com/qmk/qmk_firmware/pull/17114)) -* Added ws2812_pwm support for WB32 MCU. ([#17142](https://github.com/qmk/qmk_firmware/pull/17142)) -* Added ws2812_spi support for WB32 MCU ([#17143](https://github.com/qmk/qmk_firmware/pull/17143)) -* Make bootloader_jump for dualbank STM32 respect STM32_BOOTLOADER_DUAL_BANK_DELAY ([#17178](https://github.com/qmk/qmk_firmware/pull/17178)) -* Expose the time of the last change to the LED state ([#17222](https://github.com/qmk/qmk_firmware/pull/17222)) -* [Code] Add solid reactive gradient mode ([#17228](https://github.com/qmk/qmk_firmware/pull/17228)) -* Add keymap wrappers for introspection into the keymap. ([#17229](https://github.com/qmk/qmk_firmware/pull/17229)) -* Ensure eeconfig initialised before reading EEPROM handedness. ([#17256](https://github.com/qmk/qmk_firmware/pull/17256)) -* Add uf2-split-* make targets. ([#17257](https://github.com/qmk/qmk_firmware/pull/17257)) -* Removes terminal from QMK. ([#17258](https://github.com/qmk/qmk_firmware/pull/17258)) -* Make SPI Mode configurable for AW20216 and change default mode to 3 ([#17263](https://github.com/qmk/qmk_firmware/pull/17263)) -* Move SPLIT_HAND_PIN setup to split_pre_init ([#17271](https://github.com/qmk/qmk_firmware/pull/17271)) -* Allow larger SPLIT_USB_TIMEOUT with default SPLIT_USB_TIMEOUT_POLL ([#17272](https://github.com/qmk/qmk_firmware/pull/17272)) -* Feature-ify Send String ([#17275](https://github.com/qmk/qmk_firmware/pull/17275)) -* Rework paths for eeprom locations. ([#17326](https://github.com/qmk/qmk_firmware/pull/17326)) -* Pca9505/6 driver ([#17333](https://github.com/qmk/qmk_firmware/pull/17333)) -* Cirque Attenuation Setting ([#17342](https://github.com/qmk/qmk_firmware/pull/17342)) -* Scale brigthness for VIA ([#17352](https://github.com/qmk/qmk_firmware/pull/17352)) -* Ensure that rgb+via compiles in all cases ([#17355](https://github.com/qmk/qmk_firmware/pull/17355)) -* Wear-leveling EEPROM drivers: `embedded_flash`, `spi_flash`, `legacy` ([#17376](https://github.com/qmk/qmk_firmware/pull/17376)) -* In honor of king terry ([#17387](https://github.com/qmk/qmk_firmware/pull/17387)) -* tap-dance: Rename tests so that tap_dance is used consistently ([#17396](https://github.com/qmk/qmk_firmware/pull/17396)) -* IS31FL3737 Global Current Setting ([#17420](https://github.com/qmk/qmk_firmware/pull/17420)) -* [QP] Add ILI9488 support. ([#17438](https://github.com/qmk/qmk_firmware/pull/17438)) -* Mark GD32VF103 as ChibiOS-Contrib ([#17444](https://github.com/qmk/qmk_firmware/pull/17444)) -* ISSI Drivers Global Current Option ([#17448](https://github.com/qmk/qmk_firmware/pull/17448)) -* [Split] pointing transport check ([#17481](https://github.com/qmk/qmk_firmware/pull/17481)) -* Cirque trackpad features: circular scroll, inertial cursor ([#17482](https://github.com/qmk/qmk_firmware/pull/17482)) -* RGB heatmap skip NO_LED ([#17488](https://github.com/qmk/qmk_firmware/pull/17488)) -* Add kb2040 and sparkfun rp2040 converters ([#17514](https://github.com/qmk/qmk_firmware/pull/17514)) -* [style] rp2040 stage2 formatting ([#17516](https://github.com/qmk/qmk_firmware/pull/17516)) -* Also check /run/media/ for uf2 drives ([#17517](https://github.com/qmk/qmk_firmware/pull/17517)) -* RP2040 emulated EEPROM. ([#17519](https://github.com/qmk/qmk_firmware/pull/17519)) -* Make debounce algorithms signal matrix changes ([#17554](https://github.com/qmk/qmk_firmware/pull/17554)) -* Update PM2040 I2C pins ([#17578](https://github.com/qmk/qmk_firmware/pull/17578)) -* Added implementation of WB32 MCU wear_leveling_efl. ([#17579](https://github.com/qmk/qmk_firmware/pull/17579)) -* Use Pro Micro SDA/SCL pinout for PM2040 ([#17595](https://github.com/qmk/qmk_firmware/pull/17595)) -* Refactor Pixel Fractal effect ([#17602](https://github.com/qmk/qmk_firmware/pull/17602)) -* Add Blok RP2040 converter ([#17603](https://github.com/qmk/qmk_firmware/pull/17603)) -* Use polled waiting on ChibiOS platforms that support it ([#17607](https://github.com/qmk/qmk_firmware/pull/17607)) -* Stabilize Half-duplex RP2040 PIO split comms ([#17612](https://github.com/qmk/qmk_firmware/pull/17612)) -* PMW33XX drivers overhaul ([#17613](https://github.com/qmk/qmk_firmware/pull/17613)) -* Include stdint.h in avr/i2c_master.h ([#17639](https://github.com/qmk/qmk_firmware/pull/17639)) -* Add led matrix support for CKLED2001 ([#17643](https://github.com/qmk/qmk_firmware/pull/17643)) -* `STM32_USB_USE_OTG1` => `USB_ENDPOINTS_ARE_REORDERABLE` ([#17647](https://github.com/qmk/qmk_firmware/pull/17647)) -* Allow MCU-specific overrides for SPI flags. ([#17650](https://github.com/qmk/qmk_firmware/pull/17650)) -* Update LED/RGB Matrix flag function behavior ([#17651](https://github.com/qmk/qmk_firmware/pull/17651)) -* Cirque circular scroll: Support POINTING_DEVICE_COMBINED ([#17654](https://github.com/qmk/qmk_firmware/pull/17654)) -* Add support for PAW3204 Optical Sensor ([#17669](https://github.com/qmk/qmk_firmware/pull/17669)) -* Add LED limits call ([#17679](https://github.com/qmk/qmk_firmware/pull/17679)) -* Move Pointing Device code to a subdirectory ([#17684](https://github.com/qmk/qmk_firmware/pull/17684)) -* Avoid OOB in dynamic_keymap_reset ([#17695](https://github.com/qmk/qmk_firmware/pull/17695)) -* Allow dynamic keymap to compile without `via.h` ([#17703](https://github.com/qmk/qmk_firmware/pull/17703)) -* Use correct angle tune range of +/-127 on PMW33XX ([#17708](https://github.com/qmk/qmk_firmware/pull/17708)) -* Add Bonsai C4 converter ([#17711](https://github.com/qmk/qmk_firmware/pull/17711)) -* VIA Encoder Map Support ([#17734](https://github.com/qmk/qmk_firmware/pull/17734)) -* Move Pointing Device Initialization to after Split Post Initialization ([#17740](https://github.com/qmk/qmk_firmware/pull/17740)) -* Add ability to enter bootloader mode from `QK_MAKE` ([#17745](https://github.com/qmk/qmk_firmware/pull/17745)) -* Add `tap_code16_delay` ([#17748](https://github.com/qmk/qmk_firmware/pull/17748)) -* Implement relative mode for Cirque trackpad ([#17760](https://github.com/qmk/qmk_firmware/pull/17760)) -* Create generic Pointing Device Pin defines ([#17776](https://github.com/qmk/qmk_firmware/pull/17776)) -* Constrain Cirque Pinnacle coordinates ([#17803](https://github.com/qmk/qmk_firmware/pull/17803)) -* Refactor/rename postprocess_steno_user → post_process_steno_user ([#17823](https://github.com/qmk/qmk_firmware/pull/17823)) -* Add Bit-C PRO converter ([#17827](https://github.com/qmk/qmk_firmware/pull/17827)) -* guard RPC invocation by checking RPC info against crc checksum ([#17840](https://github.com/qmk/qmk_firmware/pull/17840)) -* Add ST7735 driver to Quantum Painter ([#17848](https://github.com/qmk/qmk_firmware/pull/17848)) -* Add minimal STM32F103C6 support ([#17853](https://github.com/qmk/qmk_firmware/pull/17853)) -* Remove legacy AVR ssd1306 driver ([#17864](https://github.com/qmk/qmk_firmware/pull/17864)) -* Remove tmk_core 'serial' code ([#17866](https://github.com/qmk/qmk_firmware/pull/17866)) -* Use LT_ZCAR in place of LT_PLUS for modded kc definitions of keymap_lithuanian_qwerty.h ([#18000](https://github.com/qmk/qmk_firmware/pull/18000)) -* Remove invisible variation selector-15 from keymap_japanese.h ([#18007](https://github.com/qmk/qmk_firmware/pull/18007)) -* define CZ_PERC S(CZ_PLUS) → define CZ_PERC S(CZ_EQL) ([#18008](https://github.com/qmk/qmk_firmware/pull/18008)) -* KR_DQUO S(KR_COLN) → KR_DQUO S(KR_QUOT) in keymap_korean.h ([#18011](https://github.com/qmk/qmk_firmware/pull/18011)) -* Replace ; by : in the shifted symbols ASCII art of keymap_norman ([#18029](https://github.com/qmk/qmk_firmware/pull/18029)) -* Add eeprom defaults for tinyuf2 bootloader ([#18042](https://github.com/qmk/qmk_firmware/pull/18042)) -* Remove duplicate COMBINING HORN in keymap_us_extended.h ([#18045](https://github.com/qmk/qmk_firmware/pull/18045)) -* Nix shell updates for `develop` ([#18131](https://github.com/qmk/qmk_firmware/pull/18131)) - -CLI: -* Add cli command to import keyboard|keymap|kbfirmware ([#16668](https://github.com/qmk/qmk_firmware/pull/16668)) -* Publish data as part of API generation ([#17020](https://github.com/qmk/qmk_firmware/pull/17020)) -* Allow encoder config from info.json ([#17295](https://github.com/qmk/qmk_firmware/pull/17295)) -* `qmk doctor`: show arch for macOS ([#17356](https://github.com/qmk/qmk_firmware/pull/17356)) -* Use --exclude-from=.gitignore in place of --exclude-standard ([#17399](https://github.com/qmk/qmk_firmware/pull/17399)) -* Improve importer workflow ([#17707](https://github.com/qmk/qmk_firmware/pull/17707)) -* Remove legacy bootmagic cli parsing ([#18099](https://github.com/qmk/qmk_firmware/pull/18099)) -* Align CLI requirements ([#18117](https://github.com/qmk/qmk_firmware/pull/18117)) - -Submodule updates: -* Add Raspberry Pi RP2040 support ([#14877](https://github.com/qmk/qmk_firmware/pull/14877)) -* Update mpaland/printf to eyalroz/printf fork ([#16163](https://github.com/qmk/qmk_firmware/pull/16163)) -* Generic wear-leveling algorithm ([#16996](https://github.com/qmk/qmk_firmware/pull/16996)) -* Update LUFA submodule ([#17368](https://github.com/qmk/qmk_firmware/pull/17368)) -* Update V-USB submodule ([#17385](https://github.com/qmk/qmk_firmware/pull/17385)) -* Update ChibiOS-Contrib ([#17540](https://github.com/qmk/qmk_firmware/pull/17540)) -* Update to latest ChibiOS-Contrib. ([#18016](https://github.com/qmk/qmk_firmware/pull/18016)) -* Update LUFA submodule ([#18168](https://github.com/qmk/qmk_firmware/pull/18168)) - -Keyboards: -* GMMK 2 WBG7 MCU compatibility ([#16436](https://github.com/qmk/qmk_firmware/pull/16436)) -* bastardkb: restructure folder hierarchy ([#16778](https://github.com/qmk/qmk_firmware/pull/16778)) -* Add Gentleman 65 SE Solderd PCB support ([#16992](https://github.com/qmk/qmk_firmware/pull/16992)) -* Move/Rename to Hillside48, simplify default keymap ([#17210](https://github.com/qmk/qmk_firmware/pull/17210)) -* IDOBAO ID67 code touch-ups and include factory keymap ([#17231](https://github.com/qmk/qmk_firmware/pull/17231)) -* IDOBAO ID87v2 code rewrite and include factory keymap ([#17232](https://github.com/qmk/qmk_firmware/pull/17232)) -* IDOBAO ID80v3 code rewrite and include factory keymap ([#17234](https://github.com/qmk/qmk_firmware/pull/17234)) -* IDOBAO ID80v1 folder rename ([#17265](https://github.com/qmk/qmk_firmware/pull/17265)) -* Fine!40 PCB Support ([#17426](https://github.com/qmk/qmk_firmware/pull/17426)) -* Update Charybdis code for Extended Mouse reports ([#17435](https://github.com/qmk/qmk_firmware/pull/17435)) -* (develop)AP2: Enable support for WL EEPROM Driver ([#17506](https://github.com/qmk/qmk_firmware/pull/17506)) -* (develop)Keychron Q2: Enable support for WL EEPROM Driver ([#17507](https://github.com/qmk/qmk_firmware/pull/17507)) -* Add Adafruit Macropad RP2040 ([#17512](https://github.com/qmk/qmk_firmware/pull/17512)) -* Add RP2040 config defaults ([#17557](https://github.com/qmk/qmk_firmware/pull/17557)) -* Add support keyboard Feker IK75 ([#17611](https://github.com/qmk/qmk_firmware/pull/17611)) -* boardsource/holiday/spooky data driven ([#17632](https://github.com/qmk/qmk_firmware/pull/17632)) -* boardsource/lulu data driven ([#17638](https://github.com/qmk/qmk_firmware/pull/17638)) -* Added support for gmmk pro rev2 keyboard. ([#17655](https://github.com/qmk/qmk_firmware/pull/17655)) -* boardsource/microdox data driven ([#17675](https://github.com/qmk/qmk_firmware/pull/17675)) -* Remove full bootmagic config from user files ([#17702](https://github.com/qmk/qmk_firmware/pull/17702)) -* (develop) Update bootmagic for Adafruit Macropad ([#17755](https://github.com/qmk/qmk_firmware/pull/17755)) -* Add a kb2040 version of the onkey keyboard that works with the oled keymap ([#17786](https://github.com/qmk/qmk_firmware/pull/17786)) -* Enable mousekeys by default for RGBKB Sol3 ([#17842](https://github.com/qmk/qmk_firmware/pull/17842)) -* More glyph transformations for spidey3 userspace ([#17854](https://github.com/qmk/qmk_firmware/pull/17854)) -* Default rgblight ([#17855](https://github.com/qmk/qmk_firmware/pull/17855)) -* Refactor satt/comet46 to use core OLED driver ([#17856](https://github.com/qmk/qmk_firmware/pull/17856)) -* Convert yosino58 to use split common ([#17861](https://github.com/qmk/qmk_firmware/pull/17861)) -* Migrate crkbd keymaps to oled driver ([#17863](https://github.com/qmk/qmk_firmware/pull/17863)) -* Overhaul uzu42 ([#17868](https://github.com/qmk/qmk_firmware/pull/17868)) -* Update ginkgo65hot to allow use of community layouts ([#17911](https://github.com/qmk/qmk_firmware/pull/17911)) -* Remove `UNUSED_PINS` ([#17931](https://github.com/qmk/qmk_firmware/pull/17931)) -* RESET -> QK_BOOT user keymaps ([#17940](https://github.com/qmk/qmk_firmware/pull/17940)) -* Add cursor layer to DMQ Spin ([#17996](https://github.com/qmk/qmk_firmware/pull/17996)) -* add new keyboard 'soda/cherish' ([#18057](https://github.com/qmk/qmk_firmware/pull/18057)) -* Move keyboard USB IDs and strings to data driven: develop ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) - -Keyboard fixes: -* Fixup SPI mode 3 => 0 on tzarc/djinn, `develop`. ([#17440](https://github.com/qmk/qmk_firmware/pull/17440)) -* Fixup doio/kb16 ([#17545](https://github.com/qmk/qmk_firmware/pull/17545)) -* Adafruit Macropad: Add VIA keymap, fix default km ([#17735](https://github.com/qmk/qmk_firmware/pull/17735)) -* Fix compilation issues for Charybdis/Dilemma ([#17791](https://github.com/qmk/qmk_firmware/pull/17791)) -* bastardkb: fix info.json changes that got reverted during the last merge from `master` to `develop` ([#17800](https://github.com/qmk/qmk_firmware/pull/17800)) -* Fixup uzu42 ([#17867](https://github.com/qmk/qmk_firmware/pull/17867)) -* use correct function in Dilemma splinky ([#17923](https://github.com/qmk/qmk_firmware/pull/17923)) -* Fix compilation issues for Boardsource Microdox ([#18037](https://github.com/qmk/qmk_firmware/pull/18037)) -* Fixup gmmk/pro/rev2 USB Data ([#18056](https://github.com/qmk/qmk_firmware/pull/18056)) - -Others: -* backlight|led 'on state' for DD configuration ([#17383](https://github.com/qmk/qmk_firmware/pull/17383)) -* Dump out the largest symbols in flash and in RAM. ([#17397](https://github.com/qmk/qmk_firmware/pull/17397)) -* Re-order user space rules inclusion ([#17459](https://github.com/qmk/qmk_firmware/pull/17459)) -* Update feature_split_keyboard.md to add extra detail about left and right matrices. ([#17492](https://github.com/qmk/qmk_firmware/pull/17492)) -* Swap F4x1 default board files away from blackpill ([#17522](https://github.com/qmk/qmk_firmware/pull/17522)) -* Add converter docs ([#17593](https://github.com/qmk/qmk_firmware/pull/17593)) -* Updates to Pointing Device Docs ([#17777](https://github.com/qmk/qmk_firmware/pull/17777)) -* Add deprecated check for RGBLIGHT_ANIMATIONS ([#17832](https://github.com/qmk/qmk_firmware/pull/17832)) -* Remove OLED driver Split Common warning ([#17862](https://github.com/qmk/qmk_firmware/pull/17862)) -* Revert " Re-order user space rules inclusion (#17459)" ([#18032](https://github.com/qmk/qmk_firmware/pull/18032)) - -Bugs: -* Minor schema fixes ([#14200](https://github.com/qmk/qmk_firmware/pull/14200)) -* Fix buffer size for WS2812 PWM driver ([#17046](https://github.com/qmk/qmk_firmware/pull/17046)) -* Fix AVR I2C master 1ms timeout ([#17174](https://github.com/qmk/qmk_firmware/pull/17174)) -* Mouse key kinetic mode fix ([#17176](https://github.com/qmk/qmk_firmware/pull/17176)) -* Fix RGB heatmap to use XY positions and use correct led limits. ([#17184](https://github.com/qmk/qmk_firmware/pull/17184)) -* Fix keys being discarded after using the leader key ([#17287](https://github.com/qmk/qmk_firmware/pull/17287)) -* Fixup pimoroni trackball ([#17335](https://github.com/qmk/qmk_firmware/pull/17335)) -* Fix via builds broken by brightness scaling ([#17354](https://github.com/qmk/qmk_firmware/pull/17354)) -* SPI Bugfix for ChibiOS `21.11.1` => `21.11.2` ([#17371](https://github.com/qmk/qmk_firmware/pull/17371)) -* Additional schema fixes ([#17414](https://github.com/qmk/qmk_firmware/pull/17414)) -* Fix deadlocks on disconnected secondary half ([#17423](https://github.com/qmk/qmk_firmware/pull/17423)) -* [Fix] Fix compilation warning for non-split keebs after #17423 ([#17439](https://github.com/qmk/qmk_firmware/pull/17439)) -* Fix Caps Word to treat mod-taps more consistently. ([#17463](https://github.com/qmk/qmk_firmware/pull/17463)) -* Fix docs regarding `USB_SUSPEND_WAKEUP_DELAY` ([#17501](https://github.com/qmk/qmk_firmware/pull/17501)) -* Fixup SSD1351 build after #17438 ([#17533](https://github.com/qmk/qmk_firmware/pull/17533)) -* Fixup SPI init procedure, SPI EEPROM sequencing ([#17534](https://github.com/qmk/qmk_firmware/pull/17534)) -* Fix Caps Word capitalization when used with Combos + Auto Shift. ([#17549](https://github.com/qmk/qmk_firmware/pull/17549)) -* Allow for `keymaps` array to be implemented in a file other than `$(KEYMAP_C)` ([#17559](https://github.com/qmk/qmk_firmware/pull/17559)) -* [Fix] printf update aftermath ([#17584](https://github.com/qmk/qmk_firmware/pull/17584)) -* Fix rgbkb/sol/rev2 build issues ([#17601](https://github.com/qmk/qmk_firmware/pull/17601)) -* More DD encoder fixes ([#17615](https://github.com/qmk/qmk_firmware/pull/17615)) -* [Fix] Make ChibiOS `_wait.h` independent of `quantum.h` ([#17645](https://github.com/qmk/qmk_firmware/pull/17645)) -* Grammar fixes for docs/feature_converters.md ([#17652](https://github.com/qmk/qmk_firmware/pull/17652)) -* Fix compilation issue with Cirque Guestures file ([#17656](https://github.com/qmk/qmk_firmware/pull/17656)) -* Fix compile issue with LED Matrix ([#17658](https://github.com/qmk/qmk_firmware/pull/17658)) -* Post-bootloader EFL/SPI fixes. ([#17661](https://github.com/qmk/qmk_firmware/pull/17661)) -* Fix LED limit loop ([#17678](https://github.com/qmk/qmk_firmware/pull/17678)) -* [Fix] Use correct angle tune range of +/-30 on PMW33XX ([#17693](https://github.com/qmk/qmk_firmware/pull/17693)) -* Fix AVR compilation of FNV by using standard integer typenames. ([#17716](https://github.com/qmk/qmk_firmware/pull/17716)) -* fix syntax error in header file ([#17732](https://github.com/qmk/qmk_firmware/pull/17732)) -* Fix custom debug function and sample output ([#17790](https://github.com/qmk/qmk_firmware/pull/17790)) -* Fix QK_MAKE's reboot check ([#17795](https://github.com/qmk/qmk_firmware/pull/17795)) -* Chibios: Stop I2C peripheral on transaction error ([#17798](https://github.com/qmk/qmk_firmware/pull/17798)) -* Fix ChibiOS `i2c_master` error codes ([#17808](https://github.com/qmk/qmk_firmware/pull/17808)) -* Update ChibiOS Contrib for RP2040 fixes ([#17817](https://github.com/qmk/qmk_firmware/pull/17817)) -* RP2040 disable PIO IRQs on serial timeout ([#17839](https://github.com/qmk/qmk_firmware/pull/17839)) -* Fix POINTING_DEVICE_GESTURES_SCROLL_ENABLE typo ([#17850](https://github.com/qmk/qmk_firmware/pull/17850)) -* Fixup compilation of printf-like functions with uint32_t args. ([#17904](https://github.com/qmk/qmk_firmware/pull/17904)) -* Fix issue with #17904. ([#17905](https://github.com/qmk/qmk_firmware/pull/17905)) -* Always run pointing device init ([#17936](https://github.com/qmk/qmk_firmware/pull/17936)) -* Align TO() max layers with other keycodes ([#17989](https://github.com/qmk/qmk_firmware/pull/17989)) -* Fix Bépo's BP_NNBS (narrow non-breaking space) ([#17999](https://github.com/qmk/qmk_firmware/pull/17999)) -* Move Encoder+Encoder Map from generic features ([#18018](https://github.com/qmk/qmk_firmware/pull/18018)) -* Fix wrong varaible in encoder block ([#18020](https://github.com/qmk/qmk_firmware/pull/18020)) -* Fix LV_CCAR and LV_NCED in keymap_latvian.h ([#18025](https://github.com/qmk/qmk_firmware/pull/18025)) -* Use ANSI ASCII art and fix comments for LT_COLN and LT_UNDS in keymap_lithuanian_qwerty.h ([#18028](https://github.com/qmk/qmk_firmware/pull/18028)) -* Partially revert some WB32 specific changes ([#18038](https://github.com/qmk/qmk_firmware/pull/18038)) -* Fix Emulated EEPROM issue with F466 ([#18039](https://github.com/qmk/qmk_firmware/pull/18039)) -* Fix DV_SCLN and DV_COLN in keymap_spanish_dvorak.h ([#18043](https://github.com/qmk/qmk_firmware/pull/18043)) -* Fix missing development_board schema entry ([#18050](https://github.com/qmk/qmk_firmware/pull/18050)) -* Add key event check to `is_tap_record` and remove `is_tap_key` ([#18063](https://github.com/qmk/qmk_firmware/pull/18063)) -* Fix GD32VF103 WS2812 PWM driver ([#18067](https://github.com/qmk/qmk_firmware/pull/18067)) -* Fix new-keyboard default for RP2040 bootloader ([#18100](https://github.com/qmk/qmk_firmware/pull/18100)) -* Fixup F4xx wear-leveling bootloader check ([#18102](https://github.com/qmk/qmk_firmware/pull/18102)) -* Fix PID value for the Keyboardio Atreus 2 bootloader ([#18116](https://github.com/qmk/qmk_firmware/pull/18116)) -* Add missing SS_LOPT and SS_ROPT defines ([#18175](https://github.com/qmk/qmk_firmware/pull/18175)) diff --git a/docs/ChangeLog/20221126.md b/docs/ChangeLog/20221126.md deleted file mode 100644 index 82aa4a499e39..000000000000 --- a/docs/ChangeLog/20221126.md +++ /dev/null @@ -1,510 +0,0 @@ -# QMK Breaking Changes - 2022 November 26 Changelog - -## Notable Features :id=notable-features - -### Autocorrect ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) :id=autocorrect - -_@getreuer_ in their infinite wisdom decided that autocorrect was a feature needed by QMK. As is customary, _@drashna_ adapted it to core and got it into a state that everyone else can use it. See [Feature: Autocorrect](feature_autocorrect.md) for more ifnormation (grin). - -## Changes Requiring User Action :id=changes-requiring-user-action - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|--------------------------------------|--------------------------------------| -| converter/numeric_keypad_IIe | converter/numeric_keypad_iie | -| durgod/k3x0/k310 | durgod/k310 | -| durgod/k3x0/k320 | durgod/k320 | -| emptystring/NQG | emptystring/nqg | -| handwired/hillside/46 | hillside/46 | -| handwired/hillside/48 | hillside/48 | -| handwired/hillside/52 | hillside/52 | -| maple_computing/christmas_tree/V2017 | maple_computing/christmas_tree/v2017 | - -### Keycodes refactoring :id=keycodes-overhaul-user-action - -QMK's keycodes got a very significant overhaul this breaking changes cycle, with the bulk of the work done by _@zvecr_ and _@fauxpark_ -- renaming, reordering, removing has been their focus in this area. In an attempt to standardise interoperation with host applications, keycode values now have strong versioning so that any connected application has confidence that the keys it thinks exist on the board actually match up with what's compiled in. These strongly-versioned keycode definitions are now published online and will not change, so tools that remap keycodes have a reference to work with. In future versions of QMK, any new or changed keycodes will result in a new version specification. See [API docs](api_docs.md#qmk-constants) for more information on the published versions if you're writing a tool to manage keycodes. - -In most cases user keymaps in the repository have already been updated to reflect the new naming scheme. In some cases user keymaps outside the repository may strike a missing keycode with the old name -- it's highly likely that the name had already been deprecated for some time, and should have been updated previously. - -See below for the full list of changesets. - -!> Keycode aliases have been put in place in most cases to cater for "old names" being mapped to "new names" -- the documentation already reflects all the new naming of keys. - -### Configuration Item Refactoring :id=config-refactoring - -A number of configuration items have been renamed for consistency. - -RGB Matrix configuration: - -| Old Config | New Config | -|-------------------------|-------------------------| -| DRIVER_LED_COUNT | RGB_MATRIX_LED_COUNT | -| RGB_DISABLE_TIMEOUT | RGB_MATRIX_TIMEOUT | -| RGB_MATRIX_STARTUP_HUE | RGB_MATRIX_DEFAULT_HUE | -| RGB_MATRIX_STARTUP_MODE | RGB_MATRIX_DEFAULT_MODE | -| RGB_MATRIX_STARTUP_SAT | RGB_MATRIX_DEFAULT_SAT | -| RGB_MATRIX_STARTUP_SPD | RGB_MATRIX_DEFAULT_SPD | -| RGB_MATRIX_STARTUP_VAL | RGB_MATRIX_DEFAULT_VAL | - -LED Matrix configuration: - -| Old Config | New Config | -|-------------------------|-------------------------| -| DRIVER_LED_COUNT | LED_MATRIX_LED_COUNT | -| LED_DISABLE_TIMEOUT | LED_MATRIX_TIMEOUT | -| LED_MATRIX_STARTUP_MODE | LED_MATRIX_DEFAULT_MODE | -| LED_MATRIX_STARTUP_SPD | LED_MATRIX_DEFAULT_SPD | -| LED_MATRIX_STARTUP_VAL | LED_MATRIX_DEFAULT_VAL | - -Joystick configuration: - -| Old Config | New Config | -|--------------------------|--------------------------| -| JOYSTICK_AXES_COUNT | JOYSTICK_AXIS_COUNT | -| JOYSTICK_AXES_RESOLUTION | JOYSTICK_AXIS_RESOLUTION | - -### Data-driven USB IDs Refactoring ([#18152](https://github.com/qmk/qmk_firmware/pull/18152)) :id=usb-ids-Refactoring - -QMK has decided to deprecate the specification of USB IDs inside `config.h` in favour of `info.json`, leaving data-driven as the only method to specify USB information. As per the deprecation schedule put forward last breaking changes cycle, USB information must be specified in `info.json` instead. - -Previously in `config.h`: -```c -#define VENDOR_ID 0x1234 -#define PRODUCT_ID 0x5678 -#define DEVICE_VER 0x0001 -#define MANUFACTURER Me -#define PRODUCT MyKeyboard -``` - -Replaced by `info.json`: -```json -{ - "keyboard_name": "MyKeyboard", - "manufacturer": "Me", - "usb": { - "vid": "0x1234", - "pid": "0x5678", - "device_version": "0.0.1" - } -} -``` - -### LED Indicator callback refactoring ([#14864](https://github.com/qmk/qmk_firmware/pull/18450)) :id=led-callback-refactor - -_RGB Matrix_ and _LED Matrix_ Indicator display code was traditionally difficult to override in keymaps as they did not follow the standard pattern of `bool *_kb()` deferring to `bool *_user()` functions, allowing signalling to the higher level that processing had already been done. - -This changes the standard callback model to allow for a base implementation to be provided by a keyboard, but also still allow for keymap-level overrides without needing to modify the keyboard's code. - -The old RGB Matrix keymap code went something like this: - -```c -void rgb_matrix_indicators_user(void) { - // keymap LED code -} -``` - -...but the new RGB Matrix keymap code looks like this: -```c -bool rgb_matrix_indicators_user(void) { - // keymap LED code - return false; -} -``` - -Keyboard designers should now structure their keyboard-level routines like the following, in order to allow for keymap overrides: - -```c -bool rgb_matrix_indicators_kb(void) { - // Defer to the keymap if they want to override - if (!rgb_matrix_indicators_user()) { return false; } - - // keyboard LED code - return true; -} -``` - -The equivalent transformations should be done for LED Matrix boards. - -### Unicode mode refactoring :id=unicode-mode-renaming - -Unicode modes were renamed in order to prevent collision with equivalent keycodes. The available values for `UNICODE_SELECTED_MODES` changed -- see [Feature: Unicode](feature_unicode.md#setting-the-input-mode) for the new list of values and how to configure them. - -## Notable core changes :id=notable-core - -This breaking changes cycle, a lot of the core changes are related to cleanup and refactoring -- commonly called "tech debt". - -### Keycodes refactoring :id=keycodes-overhaul-core-changes - -We aren't going to list each and every change -- they're far too numerous -- instead, we'll just list the related PRs in order to convey just how wide-reaching these changes were: - -* Align audio keycode names ([#18962](https://github.com/qmk/qmk_firmware/pull/18962)) -* Align dynamic tapping term keycode names ([#18963](https://github.com/qmk/qmk_firmware/pull/18963)) -* Align haptic feedback keycode names ([#18964](https://github.com/qmk/qmk_firmware/pull/18964)) -* Deprecate `CAPS_WORD`/`CAPSWRD` for `CW_TOGG` ([#18834](https://github.com/qmk/qmk_firmware/pull/18834)) -* Deprecate `KC_LEAD` for `QK_LEAD` ([#18792](https://github.com/qmk/qmk_firmware/pull/18792)) -* Deprecate `KC_LOCK` for `QK_LOCK` ([#18796](https://github.com/qmk/qmk_firmware/pull/18796)) -* Deprecate `KEY_OVERRIDE_*` keycodes for `KO_*` ([#18843](https://github.com/qmk/qmk_firmware/pull/18843)) -* Deprecate `ONESHOT_*` keycodes for `QK_ONE_SHOT_*` ([#18844](https://github.com/qmk/qmk_firmware/pull/18844)) -* Deprecate `SECURE_*` keycodes for `QK_SECURE_*` ([#18847](https://github.com/qmk/qmk_firmware/pull/18847)) -* Deprecate `VLK_TOG` for `VK_TOGG` ([#18807](https://github.com/qmk/qmk_firmware/pull/18807)) -* Initial DD keycode migration ([#18643](https://github.com/qmk/qmk_firmware/pull/18643)) -* Macro keycode name refactoring ([#18958](https://github.com/qmk/qmk_firmware/pull/18958)) -* Move mousekey keycodes into newly freed up keycode block ([#16076](https://github.com/qmk/qmk_firmware/pull/16076)) -* Normalise Auto Shift keycodes ([#18892](https://github.com/qmk/qmk_firmware/pull/18892)) -* Normalise Autocorrect keycodes ([#18893](https://github.com/qmk/qmk_firmware/pull/18893)) -* Normalise Combo keycodes ([#18877](https://github.com/qmk/qmk_firmware/pull/18877)) -* Normalise Dynamic Macro keycodes ([#18939](https://github.com/qmk/qmk_firmware/pull/18939)) -* Normalise Joystick and Programmable Button keycodes ([#18832](https://github.com/qmk/qmk_firmware/pull/18832)) -* Normalise MIDI keycodes ([#18972](https://github.com/qmk/qmk_firmware/pull/18972)) -* Normalise output selection (Bluetooth) keycodes ([#19004](https://github.com/qmk/qmk_firmware/pull/19004)) -* Normalise Space Cadet keycodes ([#18864](https://github.com/qmk/qmk_firmware/pull/18864)) -* Normalise Unicode keycodes ([#18898](https://github.com/qmk/qmk_firmware/pull/18898)) -* Publish constants metadata to API ([#19143](https://github.com/qmk/qmk_firmware/pull/19143)) -* Relocate US ANSI shifted keycode aliases ([#18634](https://github.com/qmk/qmk_firmware/pull/18634)) -* Remove `KC_DELT` ([#18882](https://github.com/qmk/qmk_firmware/pull/18882)) -* Remove `UNICODE_KEY_OSX` and `UC_OSX` ([#18290](https://github.com/qmk/qmk_firmware/pull/18290)) -* Remove deprecated RESET keycode alias ([#18271](https://github.com/qmk/qmk_firmware/pull/18271)) -* Remove legacy Debug keycode ([#18769](https://github.com/qmk/qmk_firmware/pull/18769)) -* Remove legacy EEPROM clear keycodes ([#18782](https://github.com/qmk/qmk_firmware/pull/18782)) -* Remove legacy fauxclicky and unicode keycodes ([#18800](https://github.com/qmk/qmk_firmware/pull/18800)) -* Remove legacy Grave Escape keycodes ([#18787](https://github.com/qmk/qmk_firmware/pull/18787)) -* Remove legacy international keycodes ([#18588](https://github.com/qmk/qmk_firmware/pull/18588)) -* Remove legacy keycodes, part 2 ([#18660](https://github.com/qmk/qmk_firmware/pull/18660)) -* Remove legacy keycodes, part 3 ([#18669](https://github.com/qmk/qmk_firmware/pull/18669)) -* Remove legacy keycodes, part 4 ([#18683](https://github.com/qmk/qmk_firmware/pull/18683)) -* Remove legacy keycodes, part 5 ([#18710](https://github.com/qmk/qmk_firmware/pull/18710)) -* Remove legacy keycodes, part 6 ([#18740](https://github.com/qmk/qmk_firmware/pull/18740)) -* Remove legacy locking caps/num/scroll keycodes ([#18601](https://github.com/qmk/qmk_firmware/pull/18601)) -* Remove legacy sendstring keycodes ([#18749](https://github.com/qmk/qmk_firmware/pull/18749)) -* Reworked backlight keycodes. ([#18961](https://github.com/qmk/qmk_firmware/pull/18961)) - -### Board Converters :id=board-converters - -There was additional work in the space of board converters -- historically QMK allowed for "converting" a Pro Micro build to a QMK Proton-C build. The last few versions of QMK have added support for replacement boards much like the Proton-C, and this quarter was no exception: - -* Add Bonsai C4 as a platform board file ([#18901](https://github.com/qmk/qmk_firmware/pull/18901)) -* Add converter support to keymap.json ([#18776](https://github.com/qmk/qmk_firmware/pull/18776)) -* Add Elite-C to converters ([#18309](https://github.com/qmk/qmk_firmware/pull/18309)) -* Add Elite-Pi converter ([#18236](https://github.com/qmk/qmk_firmware/pull/18236)) -* Allow QK_MAKE to work with converters ([#18637](https://github.com/qmk/qmk_firmware/pull/18637)) - -See [Feature: Converters](feature_converters.md) for the full list of board conversions available. - -### Pointing and Digitizer device updates :id=pointing-and-digitizer - -Both pointing devices and digitizer got a host of updates this cycle. Inertia, automatic mouse layers, fixes for preventing sleep... you even get more buttons with digitizers! - -* add "inertia" mode for mouse keys ([#18774](https://github.com/qmk/qmk_firmware/pull/18774)) -* Digitizer feature improvements ([#19034](https://github.com/qmk/qmk_firmware/pull/19034)) -* Enabling Pointing Device support in register code functions ([#18363](https://github.com/qmk/qmk_firmware/pull/18363)) -* Feature: pointing device automatic mouse layer ([#17962](https://github.com/qmk/qmk_firmware/pull/17962)) -* Fix mouse report comparison failing on shared EP (fixes KB preventing sleep) ([#18060](https://github.com/qmk/qmk_firmware/pull/18060)) -* Fix mouse use within send_string ([#18659](https://github.com/qmk/qmk_firmware/pull/18659)) -* Handle mouse keys more consistently ([#18513](https://github.com/qmk/qmk_firmware/pull/18513)) -* Invert pointing device motion pin for cirque touchpads ([#18404](https://github.com/qmk/qmk_firmware/pull/18404)) -* Refactor more host code (programmable button & digitizer) ([#18565](https://github.com/qmk/qmk_firmware/pull/18565)) - -## Full changelist :id=full-changelist - -Core: -* quantum: led: split out led_update_ports() for customization of led behaviour ([#14452](https://github.com/qmk/qmk_firmware/pull/14452)) -* Add getreuer's Autocorrect feature to core ([#15699](https://github.com/qmk/qmk_firmware/pull/15699)) -* Move mousekey keycodes into newly freed up keycode block ([#16076](https://github.com/qmk/qmk_firmware/pull/16076)) -* Introduce pointing device specific debug messages ([#17663](https://github.com/qmk/qmk_firmware/pull/17663)) -* PWM Backlight for RP2040 ([#17706](https://github.com/qmk/qmk_firmware/pull/17706)) -* Adjust PWM hardware audio driver for RP2040 ([#17723](https://github.com/qmk/qmk_firmware/pull/17723)) -* Prevent tap dance from wiping dynamic macros ([#17880](https://github.com/qmk/qmk_firmware/pull/17880)) -* Feature: pointing device automatic mouse layer ([#17962](https://github.com/qmk/qmk_firmware/pull/17962)) -* Allow custom timings for WS2812 PIO driver ([#18006](https://github.com/qmk/qmk_firmware/pull/18006)) -* Use `TAP_CODE_DELAY` for encoder mapping by default. Add docs. ([#18098](https://github.com/qmk/qmk_firmware/pull/18098)) -* Move Oneshot mod callbacks to after mods are set ([#18101](https://github.com/qmk/qmk_firmware/pull/18101)) -* mcp23018: add return status to init ([#18178](https://github.com/qmk/qmk_firmware/pull/18178)) -* Switch over MANUFACTURER and PRODUCT to string literals ([#18183](https://github.com/qmk/qmk_firmware/pull/18183)) -* Remove deprecated USBasp and bootloadHID bootloader types ([#18195](https://github.com/qmk/qmk_firmware/pull/18195)) -* Chromeos keycodes ([#18212](https://github.com/qmk/qmk_firmware/pull/18212)) -* VIA V3 - The Custom UI Update ([#18222](https://github.com/qmk/qmk_firmware/pull/18222)) -* Move bootloader.mk to platforms ([#18228](https://github.com/qmk/qmk_firmware/pull/18228)) -* Simplify extrakeys sending at the host driver level ([#18230](https://github.com/qmk/qmk_firmware/pull/18230)) -* Add unicode mode change callbacks ([#18235](https://github.com/qmk/qmk_firmware/pull/18235)) -* Add Elite-Pi converter ([#18236](https://github.com/qmk/qmk_firmware/pull/18236)) -* Better handle EEPROM reset keycode ([#18244](https://github.com/qmk/qmk_firmware/pull/18244)) -* Work around WinCompose issue for U+Axxx or U+Exxx ([#18260](https://github.com/qmk/qmk_firmware/pull/18260)) -* Remove deprecated RESET keycode alias ([#18271](https://github.com/qmk/qmk_firmware/pull/18271)) -* Move Bluetooth-related function calls up to host/keyboard level ([#18274](https://github.com/qmk/qmk_firmware/pull/18274)) -* Added analog support for WB32 MCU. ([#18289](https://github.com/qmk/qmk_firmware/pull/18289)) -* Remove `UNICODE_KEY_OSX` and `UC_OSX` ([#18290](https://github.com/qmk/qmk_firmware/pull/18290)) -* Add Elite-C to converters ([#18309](https://github.com/qmk/qmk_firmware/pull/18309)) -* RN42 driver: small cleanups ([#18310](https://github.com/qmk/qmk_firmware/pull/18310)) -* Reboot wb32 devices after flashing ([#18323](https://github.com/qmk/qmk_firmware/pull/18323)) -* Refactor Unicode feature ([#18333](https://github.com/qmk/qmk_firmware/pull/18333)) -* Move fake EE_HANDS from EEPROM init. ([#18352](https://github.com/qmk/qmk_firmware/pull/18352)) -* Enabling Pointing Device support in register code functions ([#18363](https://github.com/qmk/qmk_firmware/pull/18363)) -* Start Bluetooth API ([#18366](https://github.com/qmk/qmk_firmware/pull/18366)) -* Add UART support for Kinetis boards ([#18370](https://github.com/qmk/qmk_firmware/pull/18370)) -* [QP] Add RGB565 surface. Docs clarification, cleanup, tabsification, and reordering. ([#18396](https://github.com/qmk/qmk_firmware/pull/18396)) -* Change `DRIVER_LED_COUNT` to `{LED,RGB}_MATRIX_LED_COUNT` ([#18399](https://github.com/qmk/qmk_firmware/pull/18399)) -* Invert pointing device motion pin for cirque touchpads ([#18404](https://github.com/qmk/qmk_firmware/pull/18404)) -* Change `{LED,RGB}_DISABLE_TIMEOUT` to `{LED,RGB}_MATRIX_TIMEOUT` ([#18415](https://github.com/qmk/qmk_firmware/pull/18415)) -* rewrite locking in split transaction handlers ([#18417](https://github.com/qmk/qmk_firmware/pull/18417)) -* remove busy waiting from rgblight functions ([#18418](https://github.com/qmk/qmk_firmware/pull/18418)) -* Serial-protocol: always clear receive queue on main half of split keyboard ([#18419](https://github.com/qmk/qmk_firmware/pull/18419)) -* Stabilize RP2040 Half-duplex PIO split comms take 2 ([#18421](https://github.com/qmk/qmk_firmware/pull/18421)) -* Copy RP2040 vector table to RAM on startup ([#18424](https://github.com/qmk/qmk_firmware/pull/18424)) -* Further refactoring of joystick feature ([#18437](https://github.com/qmk/qmk_firmware/pull/18437)) -* Start moving towards introspection-based data retrieval ([#18441](https://github.com/qmk/qmk_firmware/pull/18441)) -* RP2040: use built-in integer hardware divider and optimized i64 multiplication ([#18464](https://github.com/qmk/qmk_firmware/pull/18464)) -* Only trigger encoder callbacks on primary side ([#18467](https://github.com/qmk/qmk_firmware/pull/18467)) -* Handle mouse keys more consistently ([#18513](https://github.com/qmk/qmk_firmware/pull/18513)) -* Gentoo install script — build newlib with `nano` USE flag ([#18527](https://github.com/qmk/qmk_firmware/pull/18527)) -* Small un/register_code() cleanups ([#18544](https://github.com/qmk/qmk_firmware/pull/18544)) -* Refactor more host code (programmable button & digitizer) ([#18565](https://github.com/qmk/qmk_firmware/pull/18565)) -* Don't clear keys on layer change unless STRICT_LAYER_RELEASE is enabled ([#18577](https://github.com/qmk/qmk_firmware/pull/18577)) -* Remove legacy international keycodes ([#18588](https://github.com/qmk/qmk_firmware/pull/18588)) -* onekey: Enable ADC for STM32F072 Discovery ([#18592](https://github.com/qmk/qmk_firmware/pull/18592)) -* Implement split comms watchdog ([#18599](https://github.com/qmk/qmk_firmware/pull/18599)) -* Remove legacy locking caps/num/scroll keycodes ([#18601](https://github.com/qmk/qmk_firmware/pull/18601)) -* Use `get_u16_str` instead of `snprintf` in `autoshift_timer_report` ([#18606](https://github.com/qmk/qmk_firmware/pull/18606)) -* Refactor `send_extra` ([#18615](https://github.com/qmk/qmk_firmware/pull/18615)) -* LUFA: Consolidate report sending code ([#18629](https://github.com/qmk/qmk_firmware/pull/18629)) -* Relocate US ANSI shifted keycode aliases ([#18634](https://github.com/qmk/qmk_firmware/pull/18634)) -* Allow QK_MAKE to work with converters ([#18637](https://github.com/qmk/qmk_firmware/pull/18637)) -* Programmable Button API refactor and improve docs ([#18641](https://github.com/qmk/qmk_firmware/pull/18641)) -* Initial DD keycode migration ([#18643](https://github.com/qmk/qmk_firmware/pull/18643)) -* Remove legacy keycodes, part 2 ([#18660](https://github.com/qmk/qmk_firmware/pull/18660)) -* Remove legacy keycodes, part 3 ([#18669](https://github.com/qmk/qmk_firmware/pull/18669)) -* Remove legacy keycodes, part 4 ([#18683](https://github.com/qmk/qmk_firmware/pull/18683)) -* Revert "mcp23018: add return status to init" ([#18709](https://github.com/qmk/qmk_firmware/pull/18709)) -* Remove legacy keycodes, part 5 ([#18710](https://github.com/qmk/qmk_firmware/pull/18710)) -* Make QP driver init functions weak. ([#18717](https://github.com/qmk/qmk_firmware/pull/18717)) -* Add unit tests for HOLD_ON_OTHER_KEY_PRESS ([#18721](https://github.com/qmk/qmk_firmware/pull/18721)) -* Remove legacy keycodes, part 6 ([#18740](https://github.com/qmk/qmk_firmware/pull/18740)) -* Remove legacy sendstring keycodes ([#18749](https://github.com/qmk/qmk_firmware/pull/18749)) -* 4 Driver support for IS31FL3737 ([#18750](https://github.com/qmk/qmk_firmware/pull/18750)) -* Remove quantum/audio from global VPATH ([#18753](https://github.com/qmk/qmk_firmware/pull/18753)) -* Widen the ARM Cortex-M family support. Allow USB peripheral change. ([#18767](https://github.com/qmk/qmk_firmware/pull/18767)) -* Remove legacy Debug keycode ([#18769](https://github.com/qmk/qmk_firmware/pull/18769)) -* add "inertia" mode for mouse keys ([#18774](https://github.com/qmk/qmk_firmware/pull/18774)) -* Remove legacy EEPROM clear keycodes ([#18782](https://github.com/qmk/qmk_firmware/pull/18782)) -* Remove legacy Grave Escape keycodes ([#18787](https://github.com/qmk/qmk_firmware/pull/18787)) -* Deprecate `KC_LEAD` for `QK_LEAD` ([#18792](https://github.com/qmk/qmk_firmware/pull/18792)) -* Deprecate `KC_LOCK` for `QK_LOCK` ([#18796](https://github.com/qmk/qmk_firmware/pull/18796)) -* Remove legacy fauxclicky and unicode keycodes ([#18800](https://github.com/qmk/qmk_firmware/pull/18800)) -* Generalise CTPC logic from common_features ([#18803](https://github.com/qmk/qmk_firmware/pull/18803)) -* Deprecate `VLK_TOG` for `VK_TOGG` ([#18807](https://github.com/qmk/qmk_firmware/pull/18807)) -* ChibiOS USB: Add a dummy IN callback to work around LLD bugs ([#18811](https://github.com/qmk/qmk_firmware/pull/18811)) -* Normalise Joystick and Programmable Button keycodes ([#18832](https://github.com/qmk/qmk_firmware/pull/18832)) -* Deprecate `CAPS_WORD`/`CAPSWRD` for `CW_TOGG` ([#18834](https://github.com/qmk/qmk_firmware/pull/18834)) -* added BS_TOGG so BS_SWAP and BS_NORM can be on a single key ([#18837](https://github.com/qmk/qmk_firmware/pull/18837)) -* Remove some assumptions on sequential keycode ranges ([#18838](https://github.com/qmk/qmk_firmware/pull/18838)) -* Deprecate `KEY_OVERRIDE_*` keycodes for `KO_*` ([#18843](https://github.com/qmk/qmk_firmware/pull/18843)) -* Deprecate `ONESHOT_*` keycodes for `QK_ONE_SHOT_*` ([#18844](https://github.com/qmk/qmk_firmware/pull/18844)) -* Deprecate `SECURE_*` keycodes for `QK_SECURE_*` ([#18847](https://github.com/qmk/qmk_firmware/pull/18847)) -* Normalise Space Cadet keycodes ([#18864](https://github.com/qmk/qmk_firmware/pull/18864)) -* Allow overriding of dynamic keymap start address. ([#18867](https://github.com/qmk/qmk_firmware/pull/18867)) -* Formalise keyboard- and user-specific EEPROM blocks ([#18874](https://github.com/qmk/qmk_firmware/pull/18874)) -* Normalise Combo keycodes ([#18877](https://github.com/qmk/qmk_firmware/pull/18877)) -* Remove rgblight_list.h ([#18878](https://github.com/qmk/qmk_firmware/pull/18878)) -* Remove `KC_DELT` ([#18882](https://github.com/qmk/qmk_firmware/pull/18882)) -* Simplify Keymap Config EEPROM ([#18886](https://github.com/qmk/qmk_firmware/pull/18886)) -* Normalise Auto Shift keycodes ([#18892](https://github.com/qmk/qmk_firmware/pull/18892)) -* Normalise Autocorrect keycodes ([#18893](https://github.com/qmk/qmk_firmware/pull/18893)) -* Normalise Unicode keycodes ([#18898](https://github.com/qmk/qmk_firmware/pull/18898)) -* Add Bonsai C4 as a platform board file ([#18901](https://github.com/qmk/qmk_firmware/pull/18901)) -* Normalise Dynamic Macro keycodes ([#18939](https://github.com/qmk/qmk_firmware/pull/18939)) -* Reduce includes for sequencer header ([#18946](https://github.com/qmk/qmk_firmware/pull/18946)) -* Reduce includes for crc header ([#18947](https://github.com/qmk/qmk_firmware/pull/18947)) -* Reduce includes for caps_word header ([#18948](https://github.com/qmk/qmk_firmware/pull/18948)) -* Reduce includes for wpm header ([#18949](https://github.com/qmk/qmk_firmware/pull/18949)) -* Reduce includes for dip_switch header ([#18951](https://github.com/qmk/qmk_firmware/pull/18951)) -* Reduce includes for send_string header ([#18952](https://github.com/qmk/qmk_firmware/pull/18952)) -* Macro keycode name refactoring ([#18958](https://github.com/qmk/qmk_firmware/pull/18958)) -* Remove thermal printer. ([#18959](https://github.com/qmk/qmk_firmware/pull/18959)) -* Reworked backlight keycodes. ([#18961](https://github.com/qmk/qmk_firmware/pull/18961)) -* Align audio keycode names ([#18962](https://github.com/qmk/qmk_firmware/pull/18962)) -* Align dynamic tapping term keycode names ([#18963](https://github.com/qmk/qmk_firmware/pull/18963)) -* Align haptic feedback keycode names ([#18964](https://github.com/qmk/qmk_firmware/pull/18964)) -* NVRAM refactor, phase 1. ([#18969](https://github.com/qmk/qmk_firmware/pull/18969)) -* Normalise MIDI keycodes ([#18972](https://github.com/qmk/qmk_firmware/pull/18972)) -* Normalise output selection (Bluetooth) keycodes ([#19004](https://github.com/qmk/qmk_firmware/pull/19004)) -* Move EFL wear-leveling driver to be default for F1, F3, F4, L4, G4, WB32, GD32V. ([#19020](https://github.com/qmk/qmk_firmware/pull/19020)) -* Digitizer feature improvements ([#19034](https://github.com/qmk/qmk_firmware/pull/19034)) -* Joystick feature improvements ([#19052](https://github.com/qmk/qmk_firmware/pull/19052)) -* Add default limit to OLED dirty processing ([#19068](https://github.com/qmk/qmk_firmware/pull/19068)) -* Change `RGB_MATRIX_STARTUP_*` defines to `RGB_MATRIX_DEFAULT_*` ([#19079](https://github.com/qmk/qmk_firmware/pull/19079)) -* Change `LED_MATRIX_STARTUP_*` defines to `LED_MATRIX_DEFAULT_*` ([#19080](https://github.com/qmk/qmk_firmware/pull/19080)) -* Extend eeconfig kb/user datablock API ([#19094](https://github.com/qmk/qmk_firmware/pull/19094)) -* Remove .noci functionality ([#19122](https://github.com/qmk/qmk_firmware/pull/19122)) - -CLI: -* Reject json with duplicate keys ([#18108](https://github.com/qmk/qmk_firmware/pull/18108)) -* Add pointing device support to data driven config ([#18215](https://github.com/qmk/qmk_firmware/pull/18215)) -* Disconnect `usb.device_ver` ([#18259](https://github.com/qmk/qmk_firmware/pull/18259)) -* Normalise info_config.h define generation ([#18439](https://github.com/qmk/qmk_firmware/pull/18439)) -* Generate DD RGBLight/LED/RGB Matrix animation defines ([#18459](https://github.com/qmk/qmk_firmware/pull/18459)) -* Add converter support to keymap.json ([#18776](https://github.com/qmk/qmk_firmware/pull/18776)) -* Ensure consistent clean behaviour ([#18781](https://github.com/qmk/qmk_firmware/pull/18781)) -* Format DD mappings and schemas ([#18924](https://github.com/qmk/qmk_firmware/pull/18924)) -* Publish hjson files as json ([#18996](https://github.com/qmk/qmk_firmware/pull/18996)) -* Add raw output option for QGF/QFF files. ([#18998](https://github.com/qmk/qmk_firmware/pull/18998)) -* Improve LED config parsing error messages ([#19007](https://github.com/qmk/qmk_firmware/pull/19007)) -* Revert "Add pointing device support to data driven config (#18215)" ([#19063](https://github.com/qmk/qmk_firmware/pull/19063)) -* Additional DD backlight config ([#19124](https://github.com/qmk/qmk_firmware/pull/19124)) -* Publish constants metadata to API ([#19143](https://github.com/qmk/qmk_firmware/pull/19143)) - -Submodule updates: -* Use a macro to compute the size of arrays at compile time ([#18044](https://github.com/qmk/qmk_firmware/pull/18044)) -* Update pico-sdk to version 1.4.0 ([#18423](https://github.com/qmk/qmk_firmware/pull/18423)) - -Keyboards: -* Rework PS/2 driver selection ([#17892](https://github.com/qmk/qmk_firmware/pull/17892)) -* Durgod K310/K320 Refactor ([#18224](https://github.com/qmk/qmk_firmware/pull/18224)) -* Optimise LAYOUT macro generation ([#18262](https://github.com/qmk/qmk_firmware/pull/18262)) -* Rename keyboards with uppercase letters ([#18268](https://github.com/qmk/qmk_firmware/pull/18268)) -* Remove legacy USE_SERIAL define ([#18292](https://github.com/qmk/qmk_firmware/pull/18292)) -* Resolve conflict merging master to develop ([#18297](https://github.com/qmk/qmk_firmware/pull/18297)) -* Remove legacy define USE_SERIAL_PD2 ([#18298](https://github.com/qmk/qmk_firmware/pull/18298)) -* Remove legacy define SERIAL_USE_MULTI_TRANSACTION ([#18299](https://github.com/qmk/qmk_firmware/pull/18299)) -* Adapt spidey3 userspace to recent unicode refactoring ([#18345](https://github.com/qmk/qmk_firmware/pull/18345)) -* Remove remaining use of terminal keys and related comment labels ([#18402](https://github.com/qmk/qmk_firmware/pull/18402)) -* Add DD mapping for LED/RGB Matrix center ([#18432](https://github.com/qmk/qmk_firmware/pull/18432)) -* develop updates for Drashna Keymaps ([#18472](https://github.com/qmk/qmk_firmware/pull/18472)) -* Remove lingering `DRIVER_LED_TOTAL` references ([#18475](https://github.com/qmk/qmk_firmware/pull/18475)) -* Remove lingering `DRIVER_LED_TOTAL` references ([#18594](https://github.com/qmk/qmk_firmware/pull/18594)) -* update andrebrait GMMK Pro keymap ([#18608](https://github.com/qmk/qmk_firmware/pull/18608)) -* AnnePro2: Adjust RGB flushing ([#18640](https://github.com/qmk/qmk_firmware/pull/18640)) -* Remove lingering `DRIVER_LED_TOTAL` references ([#18662](https://github.com/qmk/qmk_firmware/pull/18662)) -* Update snowe's KC_RESET to use QK_BOOT ([#18667](https://github.com/qmk/qmk_firmware/pull/18667)) -* Remove some .gitignore files ([#18689](https://github.com/qmk/qmk_firmware/pull/18689)) -* Remove keymaps that still reference legacy macros ([#18690](https://github.com/qmk/qmk_firmware/pull/18690)) -* Remove keymaps that still reference legacy macros ([#18693](https://github.com/qmk/qmk_firmware/pull/18693)) -* Remove stale userspace/keymaps ([#18700](https://github.com/qmk/qmk_firmware/pull/18700)) -* Update keyboards readme ([#18714](https://github.com/qmk/qmk_firmware/pull/18714)) -* Allow changes to the moonlander default music map ([#18715](https://github.com/qmk/qmk_firmware/pull/18715)) -* led_update_kb -> led_update_ports where appropriate ([#18716](https://github.com/qmk/qmk_firmware/pull/18716)) -* Update converter/usb_usb user keymaps to use LAYOUT_fullsize ([#18720](https://github.com/qmk/qmk_firmware/pull/18720)) -* Remove RGBLIGHT_ANIMATION and clean up effect defines for G-K ([#18726](https://github.com/qmk/qmk_firmware/pull/18726)) -* Remove RGBLIGHT_ANIMATION and clean up effect defines for L-Q ([#18727](https://github.com/qmk/qmk_firmware/pull/18727)) -* Remove RGBLIGHT_ANIMATION and clean up effect defines for R-Z ([#18728](https://github.com/qmk/qmk_firmware/pull/18728)) -* Remove RGBLIGHT_ANIMATION and clean up effect defines for layouts+users ([#18729](https://github.com/qmk/qmk_firmware/pull/18729)) -* Update info.json configs to explicitly list RGBLIGHT animations ([#18730](https://github.com/qmk/qmk_firmware/pull/18730)) -* A little personal cleanup after #18726 and #18729 ([#18734](https://github.com/qmk/qmk_firmware/pull/18734)) -* Move Hillside out of handwired ([#18751](https://github.com/qmk/qmk_firmware/pull/18751)) -* wilba_tech: allow keymaps to override backlight_effect_indicators() ([#18791](https://github.com/qmk/qmk_firmware/pull/18791)) -* Remove broken userspace and keymaps ([#18806](https://github.com/qmk/qmk_firmware/pull/18806)) -* Add support for KBDfans Odin V2 ([#18910](https://github.com/qmk/qmk_firmware/pull/18910)) -* Remove more `UNUSED_PINS` defines ([#18940](https://github.com/qmk/qmk_firmware/pull/18940)) -* Remove hardcoded VIA keycode range ([#18956](https://github.com/qmk/qmk_firmware/pull/18956)) -* KC_GESC -> QK_GESC, better alignment for OCD ([#19018](https://github.com/qmk/qmk_firmware/pull/19018)) -* Add missing `manufacturer` fields ([#19065](https://github.com/qmk/qmk_firmware/pull/19065)) -* Update use of legacy keycodes ([#19120](https://github.com/qmk/qmk_firmware/pull/19120)) - -Keyboard fixes: -* [GMMK Pro] Fix unintentional taps to the volume keys when using the encoder ([#17129](https://github.com/qmk/qmk_firmware/pull/17129)) -* Luna keyboard pet OLED timeout fix ([#17189](https://github.com/qmk/qmk_firmware/pull/17189)) -* Handle escaping of manufacturer/product strings ([#18194](https://github.com/qmk/qmk_firmware/pull/18194)) -* kegen/gboy: add manufacturer string ([#18196](https://github.com/qmk/qmk_firmware/pull/18196)) -* Ensure all keyboards have a bootloader set ([#18234](https://github.com/qmk/qmk_firmware/pull/18234)) -* Reverse keymap search order ([#18449](https://github.com/qmk/qmk_firmware/pull/18449)) -* Fixup cradio bootloader/processor ([#18477](https://github.com/qmk/qmk_firmware/pull/18477)) -* onekey: enable ADC for Bluepill and Blackpill ([#18545](https://github.com/qmk/qmk_firmware/pull/18545)) -* Fixup controllerworks/mini42 ([#18553](https://github.com/qmk/qmk_firmware/pull/18553)) -* RESET -> QK_BOOT user keymaps ([#18560](https://github.com/qmk/qmk_firmware/pull/18560)) -* Fixup linworks/fave84h ([#18593](https://github.com/qmk/qmk_firmware/pull/18593)) -* Fix compilation of 1upkeyboards on develop ([#18618](https://github.com/qmk/qmk_firmware/pull/18618)) -* Various keyboard fixes ([#18649](https://github.com/qmk/qmk_firmware/pull/18649)) -* Fixup twig50 ([#18651](https://github.com/qmk/qmk_firmware/pull/18651)) -* Fixup handwired/jopr — remove deprecated keycode ([#18668](https://github.com/qmk/qmk_firmware/pull/18668)) -* Fixup keychron/q3 ([#18687](https://github.com/qmk/qmk_firmware/pull/18687)) -* Fixup dumbpad/v3x ([#18692](https://github.com/qmk/qmk_firmware/pull/18692)) -* Fix aurora/sweep ([#18701](https://github.com/qmk/qmk_firmware/pull/18701)) -* Fix build failures uncovered by #18753 ([#18789](https://github.com/qmk/qmk_firmware/pull/18789)) -* Fixup emptystring/nqg ([#18804](https://github.com/qmk/qmk_firmware/pull/18804)) -* Fixup controllerwords/mini36 ([#18840](https://github.com/qmk/qmk_firmware/pull/18840)) -* Fixup 1upkeyboards/pi60_rgb ([#18858](https://github.com/qmk/qmk_firmware/pull/18858)) -* Fixup doio/kb16 ([#18859](https://github.com/qmk/qmk_firmware/pull/18859)) -* Fixup keebio/sinc/rev3 ([#18866](https://github.com/qmk/qmk_firmware/pull/18866)) -* elephant42: fix default keymap ([#18884](https://github.com/qmk/qmk_firmware/pull/18884)) -* Properly fix elephant42 ([#18908](https://github.com/qmk/qmk_firmware/pull/18908)) -* Fix syntax error introduced in #18800 ([#18933](https://github.com/qmk/qmk_firmware/pull/18933)) -* Resolve info.json/rules.mk feature conflicts in three boards ([#18942](https://github.com/qmk/qmk_firmware/pull/18942)) -* Fix DD warnings for RGBKB boards ([#18944](https://github.com/qmk/qmk_firmware/pull/18944)) -* Fix "no matrix definition" errors for some boards ([#18954](https://github.com/qmk/qmk_firmware/pull/18954)) -* LED config fixes ([#18973](https://github.com/qmk/qmk_firmware/pull/18973)) -* `handwired/swiftrax/walter`: fix layout mismatch ([#18974](https://github.com/qmk/qmk_firmware/pull/18974)) -* Fix use of shifted custom keycode ([#18978](https://github.com/qmk/qmk_firmware/pull/18978)) -* `pizzakeyboards/pizza65`: fix layouts ([#18979](https://github.com/qmk/qmk_firmware/pull/18979)) -* `cannonkeys/db60/hotswap`: fix layouts ([#18982](https://github.com/qmk/qmk_firmware/pull/18982)) -* `handwired/swiftrax/cowfish`: fix layouts ([#18984](https://github.com/qmk/qmk_firmware/pull/18984)) -* Fixup hotdox76v2 on develop ([#18991](https://github.com/qmk/qmk_firmware/pull/18991)) -* `mechlovin/adelais/standard_led/avr/rev1`: fix layout ([#18997](https://github.com/qmk/qmk_firmware/pull/18997)) -* `gboards/gergoplex`: fix matrix pins ([#18999](https://github.com/qmk/qmk_firmware/pull/18999)) -* Fixup keychron/q1/iso_encoder ([#19006](https://github.com/qmk/qmk_firmware/pull/19006)) -* Rollback unrelated changes from previous PR. ([#19015](https://github.com/qmk/qmk_firmware/pull/19015)) -* Fixup bn006 on develop ([#19029](https://github.com/qmk/qmk_firmware/pull/19029)) -* onekey: disable NKRO and mousekeys by default ([#19038](https://github.com/qmk/qmk_firmware/pull/19038)) -* Fix up laser_ninja/pumpkin_pad ([#19060](https://github.com/qmk/qmk_firmware/pull/19060)) -* Fixup keychron/q6 ([#19066](https://github.com/qmk/qmk_firmware/pull/19066)) -* Fixup handwired/alcor_dactyl ([#19072](https://github.com/qmk/qmk_firmware/pull/19072)) -* Fix some old keycodes ([#19086](https://github.com/qmk/qmk_firmware/pull/19086)) -* Update more `DRIVER_LED_TOTAL` defines to `RGB_MATRIX_LED_COUNT` ([#19089](https://github.com/qmk/qmk_firmware/pull/19089)) -* Fix references to `mouse_report_t` (which doesnt exist) ([#19107](https://github.com/qmk/qmk_firmware/pull/19107)) -* Fixup keychron/q5 ([#19119](https://github.com/qmk/qmk_firmware/pull/19119)) -* Fixup aeboards/satellite ([#19137](https://github.com/qmk/qmk_firmware/pull/19137)) -* Fixup aurora/corne on develop ([#19144](https://github.com/qmk/qmk_firmware/pull/19144)) -* Minor lint fixes for various info.json ([#19146](https://github.com/qmk/qmk_firmware/pull/19146)) - -Others: -* Add DD mapping for LED/RGB Matrix max brightness ([#18403](https://github.com/qmk/qmk_firmware/pull/18403)) -* Add DD mapping for LED/RGB Matrix split count ([#18408](https://github.com/qmk/qmk_firmware/pull/18408)) -* Add DD mapping for LED/RGB Matrix HSVS steps ([#18414](https://github.com/qmk/qmk_firmware/pull/18414)) -* Remove RGBLIGHT_ANIMTION and clean up effect defines for 0-F ([#18725](https://github.com/qmk/qmk_firmware/pull/18725)) -* Merge API update workflow ([#19121](https://github.com/qmk/qmk_firmware/pull/19121)) - -Bugs: -* Fix layer switching from tap dances by redoing the keymap lookup ([#17935](https://github.com/qmk/qmk_firmware/pull/17935)) -* ws2812: replace RGBLED_NUM with driver-owned constant to decouple driver from RGBLEDs/RGBMATRIX defines ([#18036](https://github.com/qmk/qmk_firmware/pull/18036)) -* Prevent USB peripheral fault when restarting USB on WB32 MCUs ([#18058](https://github.com/qmk/qmk_firmware/pull/18058)) -* Fix mouse report comparison failing on shared EP (fixes KB preventing sleep) ([#18060](https://github.com/qmk/qmk_firmware/pull/18060)) -* Fix incorrect `bluetooth.driver` rules.mk mapping ([#18205](https://github.com/qmk/qmk_firmware/pull/18205)) -* Adjust `EXTRAKEY_ENABLE` ifdefs for `send_extra()` ([#18249](https://github.com/qmk/qmk_firmware/pull/18249)) -* Fix docs regarding cirque pinnacle attenuation ([#18279](https://github.com/qmk/qmk_firmware/pull/18279)) -* Avoid repeated calls to rgblight_set() in tight succession when setting lighting layers ([#18338](https://github.com/qmk/qmk_firmware/pull/18338)) -* Fix cirque tap from secondary side of split keyboard ([#18351](https://github.com/qmk/qmk_firmware/pull/18351)) -* Fix EECONFIG_KEYMAP_UPPER_BYTE init ([#18394](https://github.com/qmk/qmk_firmware/pull/18394)) -* Fix retain brightness when val is changed while a layer is active ([#18426](https://github.com/qmk/qmk_firmware/pull/18426)) -* Update Chibios to latest 21.11.2 changes for RP2040 XIP deadlock mitigation ([#18428](https://github.com/qmk/qmk_firmware/pull/18428)) -* Fix incorrect g_led_config generation ([#18431](https://github.com/qmk/qmk_firmware/pull/18431)) -* Fix Per Key LED Indicator Callbacks ([#18450](https://github.com/qmk/qmk_firmware/pull/18450)) -* Update chibios-contrib for RP2040 i2c fixes take 2 ([#18455](https://github.com/qmk/qmk_firmware/pull/18455)) -* Fix comment of CM_QUES (Colemak question mark) ([#18557](https://github.com/qmk/qmk_firmware/pull/18557)) -* ChibiOS: Fix USB bus disconnect handling ([#18566](https://github.com/qmk/qmk_firmware/pull/18566)) -* Update ChibiOS-Contrib for USB IRQ and bus handling fixes ([#18574](https://github.com/qmk/qmk_firmware/pull/18574)) -* RP2040: only clear RX FIFO for serial pio driver clear ([#18581](https://github.com/qmk/qmk_firmware/pull/18581)) -* Fix ST7565 handler deadlock ([#18609](https://github.com/qmk/qmk_firmware/pull/18609)) -* Fix/Update ChibiOS hardware ID ([#18613](https://github.com/qmk/qmk_firmware/pull/18613)) -* Fix some rp2040 hardware ID errors ([#18617](https://github.com/qmk/qmk_firmware/pull/18617)) -* Fix joystick functionality for ChibiOS and OTG (Blackpill) ([#18631](https://github.com/qmk/qmk_firmware/pull/18631)) -* fix typo in solenoid.h ([#18635](https://github.com/qmk/qmk_firmware/pull/18635)) -* Fix boundary in `RGB_MATRIX_INDICATOR_SET_COLOR` ([#18650](https://github.com/qmk/qmk_firmware/pull/18650)) -* Fix MIDI output endpoint to use the out direction ([#18654](https://github.com/qmk/qmk_firmware/pull/18654)) -* Fix mouse use within send_string ([#18659](https://github.com/qmk/qmk_firmware/pull/18659)) -* Correctly build keymap.json containing additional config ([#18766](https://github.com/qmk/qmk_firmware/pull/18766)) -* Correctly build out of tree keymap.json containing additional config ([#18775](https://github.com/qmk/qmk_firmware/pull/18775)) -* Fix garbled test output ([#18822](https://github.com/qmk/qmk_firmware/pull/18822)) -* Fix rgb_matrix_set_flags_noeeprom declaration ([#18860](https://github.com/qmk/qmk_firmware/pull/18860)) -* Add missing Space Cadet alias ([#18876](https://github.com/qmk/qmk_firmware/pull/18876)) -* Fix oled_render to render all dirty blocks. ([#18887](https://github.com/qmk/qmk_firmware/pull/18887)) -* compiler.txt: ensure file exists before comparison ([#18921](https://github.com/qmk/qmk_firmware/pull/18921)) -* Fix compilation issue with WPM ([#18965](https://github.com/qmk/qmk_firmware/pull/18965)) -* Fix keycode parameter extraction to match the new DD keycodes ([#18977](https://github.com/qmk/qmk_firmware/pull/18977)) -* Fix jump in mouse_report value when scale changes during cirque get report ([#18992](https://github.com/qmk/qmk_firmware/pull/18992)) -* Fixup WS2812 vendor driver ([#19028](https://github.com/qmk/qmk_firmware/pull/19028)) -* Add missing prototype for get_hold_on_other_key_press to resolve #18855 ([#19056](https://github.com/qmk/qmk_firmware/pull/19056)) -* Fix duplicate key in keyboard.jsonschema ([#19058](https://github.com/qmk/qmk_firmware/pull/19058)) -* Fixup `keyboard.jsonschema`. ([#19059](https://github.com/qmk/qmk_firmware/pull/19059)) -* fixed MOUSEKEY_INERTIA on AVR ([#19096](https://github.com/qmk/qmk_firmware/pull/19096)) -* Fix encoder_init call order in keyboard_init ([#19140](https://github.com/qmk/qmk_firmware/pull/19140)) -* Fixup installation procedure for different Fedora versions. ([#19159](https://github.com/qmk/qmk_firmware/pull/19159)) diff --git a/docs/ChangeLog/20230226.md b/docs/ChangeLog/20230226.md deleted file mode 100644 index df5095ac7b5b..000000000000 --- a/docs/ChangeLog/20230226.md +++ /dev/null @@ -1,367 +0,0 @@ -# QMK Breaking Changes - 2023 February 26 Changelog - -## Changes Requiring User Action :id=changes-requiring-user-action - -### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#15741](https://github.com/qmk/qmk_firmware/pull/15741)) :id=i-m-t-i - -`IGNORE_MOD_TAP_INTERRUPT_PER_KEY` has been removed and `IGNORE_MOD_TAP_INTERRUPT` deprecated as a stepping stone towards making `IGNORE_MOD_TAP_INTERRUPT` the new default behavior for mod-taps in the future. - -In place of the now removed `IGNORE_MOD_TAP_INTERRUPT_PER_KEY`, one must use the pre-existing `HOLD_ON_OTHER_KEY_PRESS` option. - -In most cases, updating `get_ignore_mod_tap_interrupt` to `get_hold_on_other_key_press` is simply a matter of renaming the function and swapping every `true` by `false` and vice versa. The one subtlety you may need to look out for is that the `get_ignore_mod_tap_interrupt` was only ever called with mod-taps passed in as the `keycode` argument, while the `keycode` argument of `get_hold_on_other_key_press` can be any dual-role key. This includes not only mod-taps, but also layer-taps, one shot keys, `TT(layer)` and more. This has an impact on the effect of the `default` case in a typical per-key configuration making use of a `switch(keycode)` statement. - -To illustrate, let's take the example of a configuration where we'd want all mod-taps to activate the modifier if another key is pressed while held with the exception of `LCTL_T(KC_A)`, which should ignore keys pressed while it is held and activate the modifier only if it has been held for longer than the tapping term. In addition, we would like to keep the default "ignore-interrupt" behavior of layer taps. - -An old way to do this would be via the following code: - -```c -bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case LCTL_T(KC_A): - return true; - default: - return false; - } -} -``` - -The correct way to update this code without accidentally changing how the layer-taps work would be the following: - -```c -bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - // Capture all mod-tap keycodes. - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - if (keycode == LCTL_T(KC_A)) { - // Disable HOLD_ON_OTHER_KEY_PRESS for LCTL_T(KC_A) - // aka enable IGNORE_MOD_TAP_INTERRUPT for LCTL_T(KC_A). - return false; - } else { - // Enable HOLD_ON_OTHER_KEY_PRESS for every other mod-tap keycode. - return true; - } - default: - return false; - } -} -``` - -For more information, you are invited to read the sections on [IGNORE_MOD_TAP_INTERRUPT](tap_hold.md#ignore-mod-tap-interrupt) and [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md). - -### `TAPPING_FORCE_HOLD` => `QUICK_TAP_TERM` ([#17007](https://github.com/qmk/qmk_firmware/pull/17007)) :id=quick-tap-term - -`TAPPING_FORCE_HOLD` feature is now replaced by `QUICK_TAP_TERM`. Instead of turning off auto-repeat completely, user will have the option to configure a `QUICK_TAP_TERM` in milliseconds. When the user holds a tap-hold key after tapping it within `QUICK_TAP_TERM`, QMK will send the tap keycode to the host, enabling auto-repeat. - -Its value is set to `TAPPING_TERM` by default and it can be reduced to match typing habits to avoid false triggers. To disable auto-repeat completely, set `QUICK_TAP_TERM` to zero. - -`TAPPING_FORCE_HOLD_PER_KEY` is also deprecated and replaced by `QUICK_TAP_TERM_PER_KEY`. The old granular control function for tapping force hold is: - -```c -bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(1, KC_BSPC): - return true; - default: - return false; - } -} -``` - -That function can be replaced with: - -```c -uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return 0; - default: - return QUICK_TAP_TERM; - } -} -``` - -For more details, please read the updated documentation section on [Quick Tap Term](tap_hold.md#quick-tap-term). - -### Leader Key Rework :id=leader-key-rework ([#19632](https://github.com/qmk/qmk_firmware/pull/19632)) - -The Leader Key feature API has been significantly improved, along with some bugfixes and added tests. - -Instead of defining your leader sequences in `matrix_scan_user()`, they are now handled in the `leader_end_user()` callback, and the `LEADER_EXTERNS()`/`LEADER_DICTIONARY()` macros are no longer needed: - -```c -void leader_end_user(void) { - if (leader_sequence_one_key(KC_F)) { - // Leader, f => Types the below string - SEND_STRING("QMK is awesome."); - } else if (leader_sequence_two_keys(KC_D, KC_D)) { - // Leader, d, d => Ctrl+A, Ctrl+C - SEND_STRING(SS_LCTL("a") SS_LCTL("c")); - } else if (leader_sequence_three_keys(KC_D, KC_D, KC_S)) { - // Leader, d, d, s => Types the below string - SEND_STRING("https://start.duckduckgo.com\n"); - } else if (leader_sequence_two_keys(KC_A, KC_S)) { - // Leader, a, s => GUI+S - tap_code16(LGUI(KC_S)); - } -} -``` - -For more information please see the [Leader Key documentation](feature_leader_key.md). - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -The following keyboards have had their source moved within QMK: - -| Old Keyboard Name | New Keyboard Name | -|-----------------------------|--------------------------| -| ramonimbao/aelith | rmi_kb/aelith | -| ramonimbao/herringbone/pro | rmi_kb/herringbone/pro | -| ramonimbao/herringbone/v1 | rmi_kb/herringbone/v1 | -| ramonimbao/mona/v1_1 | rmi_kb/mona/v1_1 | -| ramonimbao/mona/v1 | rmi_kb/mona/v1 | -| ramonimbao/mona/v32a | rmi_kb/mona/v32a | -| ramonimbao/squishy65 | rmi_kb/squishy65 | -| ramonimbao/squishytkl | rmi_kb/squishytkl | -| ramonimbao/tkl_ff | rmi_kb/tkl_ff | -| ramonimbao/tkl_ff/v1 | rmi_kb/tkl_ff/v1 | -| ramonimbao/tkl_ff/v2 | rmi_kb/tkl_ff/v2 | -| ramonimbao/wete/v1 | rmi_kb/wete/v1 | -| ramonimbao/wete/v2 | rmi_kb/wete/v2 | -| the_uni | stenothe_uni | -| xelus/xs60 | xelus/xs60/soldered | - -## Notable core changes :id=notable-core - -As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around consolidation of core subsystems and constant values, as well as addressing tech debt. Whilst not outwardly visible, this cleanup and refactoring should start paying dividends as it simplifies future development and maintenance. - -A handful of examples: - -* Standardised the lower/raise/adjust layer change pattern with explicit keycodes and configurable target layers -* Cleaned up a lot of Makefile logic to simplify and speed up builds -* Automated tooling to regenerate keycode values has been hooked into the PR pipeline and will trigger failures if they're incorrect -* Many more configuration options have moved into `info.json`, such as backlight, encoders -* Additional unit tests to ensure keycode behaviours don't accidentally change - -## Full changelist :id=full-changelist - -Core: -* Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY in favour of HOLD_ON_OTHER_KEY_PRESS_PER_KEY ([#15741](https://github.com/qmk/qmk_firmware/pull/15741)) -* Add combo hook to allow per layer combo reference layers. ([#16699](https://github.com/qmk/qmk_firmware/pull/16699)) -* Replace Tapping Force Hold feature with Quick Tap Term ([#17007](https://github.com/qmk/qmk_firmware/pull/17007)) -* [Test] Reset timer for every unit test and provide timestamps for log messages ([#17028](https://github.com/qmk/qmk_firmware/pull/17028)) -* Bug17281 - Retain momentary layers until the end of tapping ([#17282](https://github.com/qmk/qmk_firmware/pull/17282)) -* Detect host OS based on USB fingerprint ([#18463](https://github.com/qmk/qmk_firmware/pull/18463)) -* allow locking the matrix state ([#18852](https://github.com/qmk/qmk_firmware/pull/18852)) -* Initial DD keymap_extras migration ([#19031](https://github.com/qmk/qmk_firmware/pull/19031)) -* Support inverted scan logic for optical switches ([#19053](https://github.com/qmk/qmk_firmware/pull/19053)) -* Corrections to uart driver for Chibios platform ([#19075](https://github.com/qmk/qmk_firmware/pull/19075)) -* Remaining DD keymap_extras migration ([#19110](https://github.com/qmk/qmk_firmware/pull/19110)) -* Add udev rule for the WB32 DFU bootloader ([#19135](https://github.com/qmk/qmk_firmware/pull/19135)) -* Add Michi MCU Converter support ([#19163](https://github.com/qmk/qmk_firmware/pull/19163)) -* Add Split support for Haptic feedback ([#19203](https://github.com/qmk/qmk_firmware/pull/19203)) -* Allow mod-tap hold action on one shot layer ([#19214](https://github.com/qmk/qmk_firmware/pull/19214)) -* Remove RGBLIGHT_ANIMATIONS from core (+cleanup) ([#19216](https://github.com/qmk/qmk_firmware/pull/19216)) -* Revert WB32 ISO workaround ([#19224](https://github.com/qmk/qmk_firmware/pull/19224)) -* Prevent dynamic keymaps from processing layers that don't exist ([#19225](https://github.com/qmk/qmk_firmware/pull/19225)) -* Add `*_RIGHT` configuration for PMW33XX driver ([#19243](https://github.com/qmk/qmk_firmware/pull/19243)) -* Remove deprecated led_set_kb ([#19273](https://github.com/qmk/qmk_firmware/pull/19273)) -* Tests that caps word stays active after use of OSL ([#19303](https://github.com/qmk/qmk_firmware/pull/19303)) -* Allow overriding of keymap/encodermap layer count. ([#19325](https://github.com/qmk/qmk_firmware/pull/19325)) -* guard action related debug messages ([#19348](https://github.com/qmk/qmk_firmware/pull/19348)) -* use `IS_EVENT` macro instead of `!IS_NOEVENT` ([#19366](https://github.com/qmk/qmk_firmware/pull/19366)) -* [Test] Introduce VERIFY_AND_CLEAR shorthand ([#19370](https://github.com/qmk/qmk_firmware/pull/19370)) -* Add RGB565 and RGB888 color support to Quantum Painter ([#19382](https://github.com/qmk/qmk_firmware/pull/19382)) -* Initial DD keycode regen workflow ([#19400](https://github.com/qmk/qmk_firmware/pull/19400)) -* Update RGB matrix reactive gradient timer scale ([#19415](https://github.com/qmk/qmk_firmware/pull/19415)) -* De-obfuscate random8 functions ([#19416](https://github.com/qmk/qmk_firmware/pull/19416)) -* Use random8 for jellybean effect ([#19418](https://github.com/qmk/qmk_firmware/pull/19418)) -* Align definition of unicode_map ([#19452](https://github.com/qmk/qmk_firmware/pull/19452)) -* Add analog support for RP2040 ([#19453](https://github.com/qmk/qmk_firmware/pull/19453)) -* [CI] Regenerate Files ([#19463](https://github.com/qmk/qmk_firmware/pull/19463)) -* Build warning when not valid work-tree ([#19475](https://github.com/qmk/qmk_firmware/pull/19475)) -* Migrate 'make git-submodule' to CLI command ([#19479](https://github.com/qmk/qmk_firmware/pull/19479)) -* Remove cmp checks from Makefile ([#19480](https://github.com/qmk/qmk_firmware/pull/19480)) -* Replace list_keyboards.sh with CLI calls ([#19485](https://github.com/qmk/qmk_firmware/pull/19485)) -* Remove unused Makefile paths ([#19487](https://github.com/qmk/qmk_firmware/pull/19487)) -* Migrate submodule dirty check to CLI ([#19488](https://github.com/qmk/qmk_firmware/pull/19488)) -* Remove `make all-` build targets ([#19496](https://github.com/qmk/qmk_firmware/pull/19496)) -* Relax converter validation within keymap schema ([#19544](https://github.com/qmk/qmk_firmware/pull/19544)) -* De-duplicate platform detection ([#19545](https://github.com/qmk/qmk_firmware/pull/19545)) -* Add alias support for converters ([#19563](https://github.com/qmk/qmk_firmware/pull/19563)) -* Revert "De-duplicate platform detection" ([#19564](https://github.com/qmk/qmk_firmware/pull/19564)) -* Add mmoskal/uf2-stm32f103 bootloader support ([#19594](https://github.com/qmk/qmk_firmware/pull/19594)) -* usb_main.c: remove `CH_KERNEL_MAJOR` check ([#19597](https://github.com/qmk/qmk_firmware/pull/19597)) -* Use the correct keycode when updating WPM ([#19599](https://github.com/qmk/qmk_firmware/pull/19599)) -* De-duplicate platform detection ([#19603](https://github.com/qmk/qmk_firmware/pull/19603)) -* Refactor rain pixel function ([#19606](https://github.com/qmk/qmk_firmware/pull/19606)) -* ChibiOS: Consolidate report sending code ([#19607](https://github.com/qmk/qmk_firmware/pull/19607)) -* Add f303 to tinyuf2 bootloader support ([#19620](https://github.com/qmk/qmk_firmware/pull/19620)) -* Refactor Leader key feature ([#19632](https://github.com/qmk/qmk_firmware/pull/19632)) -* Split out mcu_selection to platform ([#19701](https://github.com/qmk/qmk_firmware/pull/19701)) -* Move MIDI code out of tmk_core ([#19704](https://github.com/qmk/qmk_firmware/pull/19704)) -* Remove deprecated Quantum keycodes ([#19712](https://github.com/qmk/qmk_firmware/pull/19712)) -* QP: Correct rotation and offset when using LVGL ([#19713](https://github.com/qmk/qmk_firmware/pull/19713)) -* Remove usages of config_common.h from config.h files. ([#19714](https://github.com/qmk/qmk_firmware/pull/19714)) -* Relocate diode direction definitions ([#19715](https://github.com/qmk/qmk_firmware/pull/19715)) -* Normalise Swap Hands keycodes ([#19720](https://github.com/qmk/qmk_firmware/pull/19720)) -* Strip out more of config_common ([#19722](https://github.com/qmk/qmk_firmware/pull/19722)) -* Remove `IS_HOST_LED_ON` and migrate usages ([#19753](https://github.com/qmk/qmk_firmware/pull/19753)) -* Move more unicode ranges to DD ([#19755](https://github.com/qmk/qmk_firmware/pull/19755)) -* Tidy up use of keycode range helpers ([#19756](https://github.com/qmk/qmk_firmware/pull/19756)) -* Tri Layer Keys ([#19795](https://github.com/qmk/qmk_firmware/pull/19795)) -* Remove matrix_init_quantum/matrix_scan_quantum ([#19806](https://github.com/qmk/qmk_firmware/pull/19806)) -* Tidy up use of keycode range helpers ([#19813](https://github.com/qmk/qmk_firmware/pull/19813)) -* Remove `config.h` include from quantum files ([#19817](https://github.com/qmk/qmk_firmware/pull/19817)) -* Add rp2040_ce and add elite-pi and helios as alias ([#19830](https://github.com/qmk/qmk_firmware/pull/19830)) -* Add swap hands status function ([#19831](https://github.com/qmk/qmk_firmware/pull/19831)) -* Align sequencer keycodes ([#19875](https://github.com/qmk/qmk_firmware/pull/19875)) -* Align magic keycodes ([#19877](https://github.com/qmk/qmk_firmware/pull/19877)) -* Move `KC_MISSION_CONTROL`/`KC_LAUNCHPAD` keycodes to core ([#19884](https://github.com/qmk/qmk_firmware/pull/19884)) -* Reallocate user/kb keycode ranges ([#19907](https://github.com/qmk/qmk_firmware/pull/19907)) -* Reallocate SAFE_RANGE ([#19909](https://github.com/qmk/qmk_firmware/pull/19909)) -* Hide hex output when building uf2 ([#19940](https://github.com/qmk/qmk_firmware/pull/19940)) - -CLI: -* Automate "Data Driven" migrations? ([#17820](https://github.com/qmk/qmk_firmware/pull/17820)) -* Generate encodermap output from keymap.json. ([#18915](https://github.com/qmk/qmk_firmware/pull/18915)) -* Publish keymap.json to API ([#19167](https://github.com/qmk/qmk_firmware/pull/19167)) -* Apply suggested workaround for #18371 ([#19226](https://github.com/qmk/qmk_firmware/pull/19226)) -* Align new-keymap with new-keyboard ([#19229](https://github.com/qmk/qmk_firmware/pull/19229)) -* Validate keyboard name before accepting further input ([#19394](https://github.com/qmk/qmk_firmware/pull/19394)) -* Implement XAP style merge semantics for DD keycodes ([#19397](https://github.com/qmk/qmk_firmware/pull/19397)) -* Allow CLI to flash .uf2 files ([#19462](https://github.com/qmk/qmk_firmware/pull/19462)) -* Report submodule status when not valid work-tree ([#19474](https://github.com/qmk/qmk_firmware/pull/19474)) -* `qmk compile`/`qmk flash` - Validate keymap argument ([#19530](https://github.com/qmk/qmk_firmware/pull/19530)) -* Add commit info to `version.h` ([#19542](https://github.com/qmk/qmk_firmware/pull/19542)) -* Remove CLI commands: `multibuild`, `cformat`, `fileformat`, `pyformat`. ([#19629](https://github.com/qmk/qmk_firmware/pull/19629)) -* Print distro in doctor output ([#19633](https://github.com/qmk/qmk_firmware/pull/19633)) -* Reduce false positives in layout name validation ([#19646](https://github.com/qmk/qmk_firmware/pull/19646)) -* Add `mass-compile` ability to filter by key existence. ([#19885](https://github.com/qmk/qmk_firmware/pull/19885)) - -Submodule updates: -* Update ChibiOS[-Contrib], SIO driver, configs ([#17915](https://github.com/qmk/qmk_firmware/pull/17915)) -* Quantum Painter - LVGL Integration ([#18499](https://github.com/qmk/qmk_firmware/pull/18499)) -* [RP2040] update i2c drivers to reflect peripheral number ([#19277](https://github.com/qmk/qmk_firmware/pull/19277)) -* Update pico-sdk to 1.5.0 ([#19829](https://github.com/qmk/qmk_firmware/pull/19829)) - -Keyboards: -* Refactor entire Handwired K552 keyboard ([#18066](https://github.com/qmk/qmk_firmware/pull/18066)) -* Moonlander: Add RGB LED layout map macro ([#18745](https://github.com/qmk/qmk_firmware/pull/18745)) -* Add the Ortho60 v2 Keyboard to QMK ([#18890](https://github.com/qmk/qmk_firmware/pull/18890)) -* Refactor xs60 with soldered and hotswap version ([#19049](https://github.com/qmk/qmk_firmware/pull/19049)) -* [GMMK Pro] Change DEBOUNCE_TYPE to sym_eager_pk to reduce latency ([#19153](https://github.com/qmk/qmk_firmware/pull/19153)) -* Add KPrepublic BM16A v2 ([#19194](https://github.com/qmk/qmk_firmware/pull/19194)) -* Add Rama Works M60-B ([#19248](https://github.com/qmk/qmk_firmware/pull/19248)) -* Revert RESET-> QK_BOOT in Read Me files where applicable ([#19262](https://github.com/qmk/qmk_firmware/pull/19262)) -* Remove broken keymap/userspace ([#19271](https://github.com/qmk/qmk_firmware/pull/19271)) -* The Uni change folder location ([#19326](https://github.com/qmk/qmk_firmware/pull/19326)) -* New keymap for ID75 - paryz ([#19350](https://github.com/qmk/qmk_firmware/pull/19350)) -* Remove useless line continuations ([#19399](https://github.com/qmk/qmk_firmware/pull/19399)) -* Add The Uni Utility Belt Keymap ([#19411](https://github.com/qmk/qmk_firmware/pull/19411)) -* Migrate `MCU` and `BOOTLOADER` to data-driven ([#19529](https://github.com/qmk/qmk_firmware/pull/19529)) -* Migrate `LAYOUTS` to data driven ([#19541](https://github.com/qmk/qmk_firmware/pull/19541)) -* Tidy up use of CTPC ([#19570](https://github.com/qmk/qmk_firmware/pull/19570)) -* Remove matrix size defines ([#19581](https://github.com/qmk/qmk_firmware/pull/19581)) -* keebio/iris document LED matrix ([#19588](https://github.com/qmk/qmk_firmware/pull/19588)) -* Add support for current/voltage measurement on Ghoul. ([#19630](https://github.com/qmk/qmk_firmware/pull/19630)) -* Rename ramonimbao folder to rmi_kb ([#19699](https://github.com/qmk/qmk_firmware/pull/19699)) -* Remove commented out backlight config & stray "backlight levels" ([#19703](https://github.com/qmk/qmk_firmware/pull/19703)) -* Clean up Force NKRO in config.h ([#19718](https://github.com/qmk/qmk_firmware/pull/19718)) -* Remove unused `MATRIX_HAS_GHOST` from config.h ([#19726](https://github.com/qmk/qmk_firmware/pull/19726)) -* Debounce defines cleanup ([#19742](https://github.com/qmk/qmk_firmware/pull/19742)) -* Remove unused `LOCKING_SUPPORT_ENABLE` from config.h ([#19748](https://github.com/qmk/qmk_firmware/pull/19748)) -* Remove `DEBOUNCE` macro usage ([#19750](https://github.com/qmk/qmk_firmware/pull/19750)) -* Remove unused `GRAVE_ESC_CTRL_OVERRIDE` from config.h ([#19752](https://github.com/qmk/qmk_firmware/pull/19752)) -* Remove unused Bootmagic row/col defines from config.h ([#19761](https://github.com/qmk/qmk_firmware/pull/19761)) -* Remove unused `SOFT_SERIAL_PIN` from config.h ([#19768](https://github.com/qmk/qmk_firmware/pull/19768)) -* Remove `SOFT_SERIAL_PIN` for non-split boards ([#19774](https://github.com/qmk/qmk_firmware/pull/19774)) -* implement missing layouts + DD migration for wilba_tech/wt60_d ([#19777](https://github.com/qmk/qmk_firmware/pull/19777)) -* Move LED indicator config to data driven ([#19800](https://github.com/qmk/qmk_firmware/pull/19800)) -* Migrate `DIRECT_PINS` to data driven ([#19826](https://github.com/qmk/qmk_firmware/pull/19826)) -* Remove lingering `I2CD2` usages w/ RP2040 ([#19833](https://github.com/qmk/qmk_firmware/pull/19833)) -* Brick ([#19851](https://github.com/qmk/qmk_firmware/pull/19851)) -* Remove unused RGBLight defines from config.h ([#19859](https://github.com/qmk/qmk_firmware/pull/19859)) -* Move Bootmagic config to data driven ([#19860](https://github.com/qmk/qmk_firmware/pull/19860)) -* Move `SOFT_SERIAL_PIN` to data driven ([#19863](https://github.com/qmk/qmk_firmware/pull/19863)) -* Move layouts for direct_pins boards to data driven ([#19872](https://github.com/qmk/qmk_firmware/pull/19872)) -* Move QMK LUFA bootloader config to data driven ([#19879](https://github.com/qmk/qmk_firmware/pull/19879)) -* Move backlight config to data driven, part 1 ([#19887](https://github.com/qmk/qmk_firmware/pull/19887)) -* Add license headers to all default layout keymaps ([#19888](https://github.com/qmk/qmk_firmware/pull/19888)) -* Migrate some more layouts to data driven ([#19889](https://github.com/qmk/qmk_firmware/pull/19889)) -* Remove magic bodges from via keymaps ([#19890](https://github.com/qmk/qmk_firmware/pull/19890)) -* Refactor more `KC_MISSION_CONTROL`/`KC_LAUNCHPAD` usages ([#19891](https://github.com/qmk/qmk_firmware/pull/19891)) -* Remove default and unused `BACKLIGHT_LEVELS` ([#19898](https://github.com/qmk/qmk_firmware/pull/19898)) -* Move backlight config to data driven ([#19910](https://github.com/qmk/qmk_firmware/pull/19910)) -* Remove VIA specific use of `MACRO0*` ([#19918](https://github.com/qmk/qmk_firmware/pull/19918)) -* Use standard magic keycodes in `yandrstudio` keymaps ([#19919](https://github.com/qmk/qmk_firmware/pull/19919)) -* Move encoder config to data driven ([#19923](https://github.com/qmk/qmk_firmware/pull/19923)) - -Keyboard fixes: -* Partially revert #18940 for Ploopy Thumb Trackball ([#18943](https://github.com/qmk/qmk_firmware/pull/18943)) -* Fix up Info.Json files that weren't parsing correctly ([#19275](https://github.com/qmk/qmk_firmware/pull/19275)) -* Fix DZTECH Tofu II v1 i2c config ([#19306](https://github.com/qmk/qmk_firmware/pull/19306)) -* Fixup build failures. ([#19332](https://github.com/qmk/qmk_firmware/pull/19332)) -* Fixup horrortroll/handwired_k552 ([#19447](https://github.com/qmk/qmk_firmware/pull/19447)) -* Ignore defaults.hjson values if already set ([#19511](https://github.com/qmk/qmk_firmware/pull/19511)) -* Fix mk0_avr_extra PIN_COMPATIBLE lint warning ([#19640](https://github.com/qmk/qmk_firmware/pull/19640)) -* fix pegasushoof caps light, add via keymap ([#19649](https://github.com/qmk/qmk_firmware/pull/19649)) -* Fixup handwired/jscotto/scotto40 ([#19675](https://github.com/qmk/qmk_firmware/pull/19675)) -* Clean up remaining rules.mk `MCU`/`BOOTLOADER`s ([#19778](https://github.com/qmk/qmk_firmware/pull/19778)) -* Fix errors flagged by generate-api ([#19784](https://github.com/qmk/qmk_firmware/pull/19784)) -* Fix merge error with fave84 board ([#19808](https://github.com/qmk/qmk_firmware/pull/19808)) -* Fixup ek65 -- add processor & bootloader in `info.json` ([#19815](https://github.com/qmk/qmk_firmware/pull/19815)) -* Fixup durgod/dgk6x (scroll lock mis-defined as num lock) ([#19864](https://github.com/qmk/qmk_firmware/pull/19864)) -* Fix API generation ([#19866](https://github.com/qmk/qmk_firmware/pull/19866)) -* Fixup for_science ([#19867](https://github.com/qmk/qmk_firmware/pull/19867)) -* Fix more build failures ([#19869](https://github.com/qmk/qmk_firmware/pull/19869)) -* Fixup pegasushoof VIA keymap ([#19874](https://github.com/qmk/qmk_firmware/pull/19874)) -* Fixup cannonkeys/satisfaction75 (readd `backlight.breathing_period`) ([#19901](https://github.com/qmk/qmk_firmware/pull/19901)) -* Add some missing `#pragma once`s ([#19902](https://github.com/qmk/qmk_firmware/pull/19902)) -* `keebio/kbo5000`: fix encoder config ([#19941](https://github.com/qmk/qmk_firmware/pull/19941)) - -Others: -* KC_GESC -> QK_GESC for cn and ja Docs ([#19024](https://github.com/qmk/qmk_firmware/pull/19024)) -* Update files changed action ([#19172](https://github.com/qmk/qmk_firmware/pull/19172)) -* DD bootmagic config ([#19201](https://github.com/qmk/qmk_firmware/pull/19201)) -* Rework input_pressed_state docs ([#19267](https://github.com/qmk/qmk_firmware/pull/19267)) -* Change log for Quick Tap Term ([#19341](https://github.com/qmk/qmk_firmware/pull/19341)) -* Promote CTPC warning to error ([#19565](https://github.com/qmk/qmk_firmware/pull/19565)) -* Run format-text on keyboard PRs ([#19656](https://github.com/qmk/qmk_firmware/pull/19656)) -* Change defines by enums ([#19793](https://github.com/qmk/qmk_firmware/pull/19793)) -* [Doc]Remove depracted extension links in vscode guide ([#19842](https://github.com/qmk/qmk_firmware/pull/19842)) - -Bugs: -* Make Magic handling more consistent in Action Keycode handling ([#9126](https://github.com/qmk/qmk_firmware/pull/9126)) -* Fix functions when `NO_ACTION_TAPPING` is defined ([#11528](https://github.com/qmk/qmk_firmware/pull/11528)) -* Return USB HID GET_REPORT requests ([#14814](https://github.com/qmk/qmk_firmware/pull/14814)) -* Fixed NKRO issue caused by HID_SET_PROTOCOL on Chibios platform ([#17588](https://github.com/qmk/qmk_firmware/pull/17588)) -* kint36: do not restart USB stack after wakeup ([#19077](https://github.com/qmk/qmk_firmware/pull/19077)) -* Fixes to source generation [mostly typographic] ([#19160](https://github.com/qmk/qmk_firmware/pull/19160)) -* Teensy 3.5: do not restart USB stack after wakeup ([#19269](https://github.com/qmk/qmk_firmware/pull/19269)) -* Fixing PMW3389.c so it can compile ([#19301](https://github.com/qmk/qmk_firmware/pull/19301)) -* UCIS: remove `qk_` prefix ([#19302](https://github.com/qmk/qmk_firmware/pull/19302)) -* Leader: remove `qk_` prefix ([#19304](https://github.com/qmk/qmk_firmware/pull/19304)) -* Tap Dance: remove `qk_` prefix ([#19313](https://github.com/qmk/qmk_firmware/pull/19313)) -* Revert changes to keymap_steno.h ([#19412](https://github.com/qmk/qmk_firmware/pull/19412)) -* Use unique name for regen PR branches ([#19464](https://github.com/qmk/qmk_firmware/pull/19464)) -* Restore packing of midi note keycodes ([#19468](https://github.com/qmk/qmk_firmware/pull/19468)) -* Fix 'Need at least one layout defined in info.json' check ([#19537](https://github.com/qmk/qmk_firmware/pull/19537)) -* `qmk doctor` - Handle permission issues while checking udev ([#19548](https://github.com/qmk/qmk_firmware/pull/19548)) -* `qmk doctor` - Handle timeouts while checking binaries ([#19549](https://github.com/qmk/qmk_firmware/pull/19549)) -* Fix CLI community detection ([#19562](https://github.com/qmk/qmk_firmware/pull/19562)) -* Fix joystick build for ChibiOS ([#19602](https://github.com/qmk/qmk_firmware/pull/19602)) -* Fix converter alias after 19603 ([#19644](https://github.com/qmk/qmk_firmware/pull/19644)) -* Fix functions with empty params ([#19647](https://github.com/qmk/qmk_firmware/pull/19647)) -* rp2040: fix timer wrap deadlock in ws2812 vendor driver ([#19652](https://github.com/qmk/qmk_firmware/pull/19652)) -* analog.c: Fix `pinToMux()` for STM32F0xx ([#19658](https://github.com/qmk/qmk_firmware/pull/19658)) -* Fix quantum ring_buffer for ChibiOS ([#19683](https://github.com/qmk/qmk_firmware/pull/19683)) -* Regen keycode_table for unit tests ([#19721](https://github.com/qmk/qmk_firmware/pull/19721)) -* Fix midi after recent refactoring ([#19723](https://github.com/qmk/qmk_firmware/pull/19723)) -* Fix build failures with `OPT = 0` due to inline functions ([#19767](https://github.com/qmk/qmk_firmware/pull/19767)) -* Fix tri layer compiler issue if NO_ACTION_LAYER is defined ([#19821](https://github.com/qmk/qmk_firmware/pull/19821)) -* Fixup `develop` compiles. ([#19828](https://github.com/qmk/qmk_firmware/pull/19828)) -* Fix Layer Mod mishandling of right-handed mods, a mixup of 5-bit vs. 8-bit mods representation. ([#19845](https://github.com/qmk/qmk_firmware/pull/19845)) -* Fix compilation issue for Key Overrides ([#19856](https://github.com/qmk/qmk_firmware/pull/19856)) -* Fix regen script for macOS ([#19857](https://github.com/qmk/qmk_firmware/pull/19857)) -* Fix compilation error when defining QUICK_TAP_TERM_PER_KEY ([#19893](https://github.com/qmk/qmk_firmware/pull/19893)) -* VIA Protocol 12 + fixes ([#19916](https://github.com/qmk/qmk_firmware/pull/19916)) diff --git a/docs/ChangeLog/20230528.md b/docs/ChangeLog/20230528.md deleted file mode 100644 index b4044d3109b6..000000000000 --- a/docs/ChangeLog/20230528.md +++ /dev/null @@ -1,551 +0,0 @@ -# QMK Breaking Changes - 2023 May 28 Changelog - -## Notable Changes :id=notable-changes - -As per last breaking changes cycle, there has been _a lot_ of emphasis on behind-the-scenes changes, mainly around migration of configurables into `info.json` files, cleanup of `info.json` files, additional layout definitions for keyboards, adding support for general community layouts to keyboards, as well as addressing technical debt. - -Of note for keyboard designers: - -* Layout and matrix definitions in `info.json` are now _mandatory_ for merge into QMK. - * Layout macros in `.h` are no longer accepted into QMK Firmware. - * Existing keyboards have been meticulously converted by the QMK collaborators - * Layouts missing from keyboard definitions have been added in the process - * Keys within layouts should not specify `"w":1` or `"h":1` if the key size is 1 -- `w`/`h` should only be present for sizes other than 1 -* `config_common.h` has been removed and should not be present anywhere in your keyboard code. -* `RGB_DI_PIN` will now cause an error during build: - * For WS2812-like LEDs, this should be moved to `info.json`: `"ws2812": { "pin": "xxx" }` - * For APA102 LEDs, this should be moved to `info.json`: `"apa102": { "data_pin": "xxx" }` -* Other mandatory data-driven changes should be automatically flagged during build -* Keymaps with `encoder_map` should now have the following change made: - * `encoder_map[][NUM_ENCODERS][2]` => `encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]` - * Users assumed the `2` referred to the number of encoders, rather than the number of directions (which is always 2) - -### Repeat last key ([#19700](https://github.com/qmk/qmk_firmware/pull/19700)) :id=repeat-last-key - -A new pair of keys has been added to QMK -- namely `QK_REPEAT_KEY` and `QK_ALT_REPEAT_KEY` (shortened: `QK_REP`/`QK_AREP`). These allow you to repeat the last key pressed, or in the case of the alternate key, press the "opposite" of the last key. For example, if you press `KC_LEFT`, pressing `QK_REPEAT_KEY` afterwards repeats `KC_LEFT`, but pressing `QK_ALT_REPEAT_KEY` instead sends `KC_RIGHT`. - -The full list of default alternate keys is available on the [Repeat Key](feature_repeat_key.md) documentation. - -To enable these keys, in your keymap's `rules.mk`, add: - -```make -REPEAT_KEY_ENABLE = yes -``` - -...and add them to your keymap. - -### User callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584)) :id=user-callback-for-pre-process-record - -Two new boolean callback functions, `pre_process_record_kb` and `pre_process_record_user`, have been added. They are called at the beginning of `process_record`, right before `process_combo`. - -Similar to existing `*_kb` and `*_user` callback functions, returning `false` will halt further processing of key events. The `pre_process_record_user` function will allow user space opportunity to handle or capture an input before it undergoes quantum processing. For example, while action tapping is still resolving the tap or hold output of a mod-tap key, `pre_process_record_user` can capture the next key record of an input event that follows. That key record can be used to influence the [decision of the mod-tap](https://docs.qmk.fm/#/tap_hold) key that is currently undergoing quantum processing. - -### Consolidate modelm ([#14996](https://github.com/qmk/qmk_firmware/pull/14996) :id=consolidate-modelm - -Several build targets for the IBM Model M were cluttered in different folders. The maintainers of several Model M replacement controller projects agreed to consolidate them under one common folder. - -The list of all moved keyboard locations is listed [below](20230528.md#updated-keyboard-codebases). - -## Changes Requiring User Action :id=changes-requiring-user-action - -### `IGNORE_MOD_TAP_INTERRUPT` behaviour changes ([#20211](https://github.com/qmk/qmk_firmware/pull/20211)) :id=i-m-t-i - -Following up from the last breaking changes cycle, `IGNORE_MOD_TAP_INTERRUPT` has been removed and if present in keymap code, will now fail to build. The previous functionality for `IGNORE_MOD_TAP_INTERRUPT` is now default, and should you wish to revert to the old behaviour, you can use `HOLD_ON_OTHER_KEY_PRESS` instead. - -For more information, you are invited to read the section on [HOLD_ON_OTHER_KEY_PRESS](tap_hold.md#hold-on-other-key-press) in the page on [Tap-Hold configuration options](tap_hold.md). - -### Updated Keyboard Codebases :id=updated-keyboard-codebases - -| Old Keyboard Name | New Keyboard Name | -|---------------------------------|-------------------------------------| -| ashpil/modelm_usbc | ibm/model_m/ashpil_usbc | -| binepad/bn009r2 | binepad/bn009/r2 | -| converter/modelm101 | ibm/model_m/teensypp | -| converter/modelm101_teensy2 | ibm/model_m/teensy2 | -| converter/modelm_ssk | ibm/model_m_ssk/teensypp_ssk | -| durgod/dgk6x/hades | durgod/dgk6x/hades_ansi | -| handwired/ibm122m | ibm/model_m_122/ibm122m | -| jacky_studio/piggy60/hotswap | jacky_studio/piggy60/rev1/hotswap | -| jacky_studio/piggy60/solder | jacky_studio/piggy60/rev1/solder | -| kamigakushi | jaykeeb/kamigakushi | -| massdrop/thekey | drop/thekey/v1 | -| massdrop/thekey_v2 | drop/thekey/v2 | -| mschwingen/modelm | ibm/model_m/mschwingen | -| tronguylabs/m122_3270 | ibm/model_m_122/m122_3270 | -| tronguylabs/m122_3270/blackpill | ibm/model_m_122/m122_3270/blackpill | -| tronguylabs/m122_3270/bluepill | ibm/model_m_122/m122_3270/bluepill | -| tronguylabs/m122_3270/teensy | ibm/model_m_122/m122_3270/teensy | -| yugo_m/model_m_101 | ibm/model_m/yugo_m | - -## Notable core changes :id=notable-core - -### Encoder functionality fallback ([#20320](https://github.com/qmk/qmk_firmware/pull/20320)) :id=encoder-functionality-fallback - -For keyboards who have not yet been migrated to encoder map, a default set of encoder functionality is now enabled, gracefully degrading functionality depending on which flags are enabled by the keyboard: - -* If `EXTRAKEY_ENABLE` is enabled by the keyboard, the encoder will be mapped to `KC_VOLU`/`KC_VOLD` -* If `MOUSEKEY_ENABLE` is enabled by the keyboard, the encoder will be mapped to `KC_MS_WH_UP`/`KC_MS_WH_DOWN` -* Otherwise, `KC_PGDN`/`KC_PGUP` will be used - -Additionally, this ensures that builds on QMK Configurator produce some sort of usable encoder mapping. - -### OLED Driver Improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331)) :id=oled-driver-improvements - -The "classic" OLED driver picked up support for additional sizes of OLED displays, support for the SH1107 controller, and SPI-based OLED support. - -Other configurable items are available and can be found on the [OLED Driver page](https://docs.qmk.fm/#/feature_oled_driver). - -## Full changelist :id=full-changelist - -Core: -* Refactor `keyevent_t` for 1ms timing resolution ([#15847](https://github.com/qmk/qmk_firmware/pull/15847)) -* PS/2 PIO Driver for RP2040 ([#17893](https://github.com/qmk/qmk_firmware/pull/17893)) -* Relocate various modifier defines ([#18638](https://github.com/qmk/qmk_firmware/pull/18638)) -* Added PMW3320 driver ([#19543](https://github.com/qmk/qmk_firmware/pull/19543)) -* Keymap introspection for combos. ([#19670](https://github.com/qmk/qmk_firmware/pull/19670)) -* Add direction to dynamic_macro_record_start_user ([#19689](https://github.com/qmk/qmk_firmware/pull/19689)) -* Add Repeat Key ("repeat last key") as a core feature. ([#19700](https://github.com/qmk/qmk_firmware/pull/19700)) -* [Cleanup] Quantum Painter ([#19825](https://github.com/qmk/qmk_firmware/pull/19825)) -* Improve robustness of AW20216 driver ([#19849](https://github.com/qmk/qmk_firmware/pull/19849)) -* Make "detected_host_os()" available on the SLAVE side of the split keyboard ([#19854](https://github.com/qmk/qmk_firmware/pull/19854)) -* Add RP2040 Community Edition alias for splitkb.com's Liatris controller ([#19966](https://github.com/qmk/qmk_firmware/pull/19966)) -* Remove some use of keymap.h ([#19980](https://github.com/qmk/qmk_firmware/pull/19980)) -* Merge upstream changes to uf2conv ([#19993](https://github.com/qmk/qmk_firmware/pull/19993)) -* Remove keymap.h ([#20004](https://github.com/qmk/qmk_firmware/pull/20004)) -* Remove some use of keymap.h ([#20006](https://github.com/qmk/qmk_firmware/pull/20006)) -* Quantum Painter QoL enhancements -- auto-poweroff, auto-flush, buffer sizing ([#20013](https://github.com/qmk/qmk_firmware/pull/20013)) -* Make Pointing Device Auto Layer more configurable ([#20061](https://github.com/qmk/qmk_firmware/pull/20061)) -* Add last activity functions for pointing device ([#20079](https://github.com/qmk/qmk_firmware/pull/20079)) -* Caps Word "Invert on shift" option: pressing Shift inverts the shift state. ([#20092](https://github.com/qmk/qmk_firmware/pull/20092)) -* Remove bootloader logic from `mcu_selection.mk` ([#20150](https://github.com/qmk/qmk_firmware/pull/20150)) -* Update qmk_cli container references ([#20154](https://github.com/qmk/qmk_firmware/pull/20154)) -* Clean up APA102 config and add DD mapping ([#20159](https://github.com/qmk/qmk_firmware/pull/20159)) -* Sync activity timestamps between sides. ([#20192](https://github.com/qmk/qmk_firmware/pull/20192)) -* Update Doxygen comments for some headers ([#20194](https://github.com/qmk/qmk_firmware/pull/20194)) -* Make IGNORE_MOD_TAP_INTERRUPT the default behaviour for mod-taps ([#20211](https://github.com/qmk/qmk_firmware/pull/20211)) -* Add some helpers to tidy up XAP ([#20235](https://github.com/qmk/qmk_firmware/pull/20235)) -* Tidy up duplication of MIN/MAX fallback implementations ([#20236](https://github.com/qmk/qmk_firmware/pull/20236)) -* Optionally keep intermediate file listings in order to do comparisons between builds. ([#20237](https://github.com/qmk/qmk_firmware/pull/20237)) -* Add basic profiler. ([#20238](https://github.com/qmk/qmk_firmware/pull/20238)) -* WS2812 driver improvements ([#20262](https://github.com/qmk/qmk_firmware/pull/20262)) -* typing_heatmap: Add macro to configure increase steps ([#20300](https://github.com/qmk/qmk_firmware/pull/20300)) -* Migrate `rgblight.pin` and `RGB_DI_PIN` to `ws2812.pin` ([#20303](https://github.com/qmk/qmk_firmware/pull/20303)) -* Delete config_common.h ([#20312](https://github.com/qmk/qmk_firmware/pull/20312)) -* Allow EEPROM_DRIVER from info.json ([#20313](https://github.com/qmk/qmk_firmware/pull/20313)) -* rp2040: *_PAL_MODE overridable for this platform too ([#20314](https://github.com/qmk/qmk_firmware/pull/20314)) -* Add core/fallback encoder behaviour ([#20320](https://github.com/qmk/qmk_firmware/pull/20320)) -* OLED Driver improvements ([#20331](https://github.com/qmk/qmk_firmware/pull/20331)) -* [Chore] Remove stray mod tap interrupt defines and per key functions ([#20347](https://github.com/qmk/qmk_firmware/pull/20347)) -* Add swap hands toggle functions ([#20381](https://github.com/qmk/qmk_firmware/pull/20381)) -* Prevent Tri-Layer keys from stopping caps word ([#20398](https://github.com/qmk/qmk_firmware/pull/20398)) -* quantum/action_util.c: Use uint8_t for oneshot_layer_data ([#20423](https://github.com/qmk/qmk_firmware/pull/20423)) -* Encoder map direction define. ([#20454](https://github.com/qmk/qmk_firmware/pull/20454)) -* Realign and size check EECONFIG structures ([#20541](https://github.com/qmk/qmk_firmware/pull/20541)) -* Clean up ISSI drivers, Add IS31FL3736 support ([#20572](https://github.com/qmk/qmk_firmware/pull/20572)) -* Add a user callback for pre process record ([#20584](https://github.com/qmk/qmk_firmware/pull/20584)) -* Disable debug on QP's internal task ([#20623](https://github.com/qmk/qmk_firmware/pull/20623)) -* Add required string header file ([#20638](https://github.com/qmk/qmk_firmware/pull/20638)) -* Add Develop is31fl3736 multi drivers ([#20642](https://github.com/qmk/qmk_firmware/pull/20642)) -* Support PS/2 mouse 9-bit output with MOUSE_EXTENDED_REPORT ([#20734](https://github.com/qmk/qmk_firmware/pull/20734)) -* BIOI G60/Morgan65: use custom Bluetooth driver ([#20897](https://github.com/qmk/qmk_firmware/pull/20897)) -* Move `pre_process_record_kb()` before `process_combo()` ([#20969](https://github.com/qmk/qmk_firmware/pull/20969)) -* Implement UF2 device type id extension tag ([#21029](https://github.com/qmk/qmk_firmware/pull/21029)) - -CLI: -* Add force support to 'qmk git-submodule' ([#19705](https://github.com/qmk/qmk_firmware/pull/19705)) -* JSON encoder: improve sorting of layout dict keys ([#19974](https://github.com/qmk/qmk_firmware/pull/19974)) -* Increase verbosity of make command ([#20172](https://github.com/qmk/qmk_firmware/pull/20172)) -* Append user variables to the end of make command ([#20177](https://github.com/qmk/qmk_firmware/pull/20177)) -* Strip API specific output from `qmk info` ([#20234](https://github.com/qmk/qmk_firmware/pull/20234)) -* `qmk find`: usability improvements ([#20440](https://github.com/qmk/qmk_firmware/pull/20440)) -* `qmk format-json`: Expose full key path and respect `sort_keys` ([#20836](https://github.com/qmk/qmk_firmware/pull/20836)) -* Update json2c to use dump_lines ([#21013](https://github.com/qmk/qmk_firmware/pull/21013)) - -Submodule updates: -* Update ChibiOS to latest stable 21.11.x ([#20470](https://github.com/qmk/qmk_firmware/pull/20470)) - -Keyboards: -* Allow a larger int for the idle timeout for urbanvanilla keymap ([#19738](https://github.com/qmk/qmk_firmware/pull/19738)) -* Change aidansmithdotdev/fine40 to use Encoder Map ([#19912](https://github.com/qmk/qmk_firmware/pull/19912)) -* Custom keycodes in JSON ([#19925](https://github.com/qmk/qmk_firmware/pull/19925)) -* Remove `"w":1` and `"h":1` from info.json ([#19961](https://github.com/qmk/qmk_firmware/pull/19961)) -* Move matrix config to info.json, part 1 ([#19985](https://github.com/qmk/qmk_firmware/pull/19985)) -* Move matrix config to info.json, part 2 ([#19987](https://github.com/qmk/qmk_firmware/pull/19987)) -* Move matrix config to info.json, part 3 ([#19991](https://github.com/qmk/qmk_firmware/pull/19991)) -* Move matrix config to info.json, part 4 ([#20001](https://github.com/qmk/qmk_firmware/pull/20001)) -* Move matrix config to info.json, part 5 ([#20003](https://github.com/qmk/qmk_firmware/pull/20003)) -* Move matrix config to info.json, part 6 ([#20019](https://github.com/qmk/qmk_firmware/pull/20019)) -* Move matrix config to info.json, part 7 ([#20020](https://github.com/qmk/qmk_firmware/pull/20020)) -* Move matrix config to info.json, part 8 ([#20030](https://github.com/qmk/qmk_firmware/pull/20030)) -* Remove empty rules.mk from keymaps ([#20056](https://github.com/qmk/qmk_firmware/pull/20056)) -* Adjust offset for some layouts ([#20075](https://github.com/qmk/qmk_firmware/pull/20075)) -* Remove useless "ifdef KEYBOARD_*" ([#20078](https://github.com/qmk/qmk_firmware/pull/20078)) -* Remove pointless `USE_I2C` blocks in keyboard headers ([#20084](https://github.com/qmk/qmk_firmware/pull/20084)) -* Add support for ISO version of Durgod Hades ([#20110](https://github.com/qmk/qmk_firmware/pull/20110)) -* Consolidate Binepad BN009 R1 and R2 into common folder ([#20113](https://github.com/qmk/qmk_firmware/pull/20113)) -* Remove more empty headers ([#20155](https://github.com/qmk/qmk_firmware/pull/20155)) -* Remove trailing zeroes in info.json layouts ([#20156](https://github.com/qmk/qmk_firmware/pull/20156)) -* Clean up usage of `QMK_KEYBOARD_H` ([#20167](https://github.com/qmk/qmk_firmware/pull/20167)) -* Move Keychron Q0 and Q0 Plus data-driven configuration; `keychron` keymap `rules.mk` cleanup ([#20168](https://github.com/qmk/qmk_firmware/pull/20168)) -* Move ortho & numpad layouts to data driven ([#20183](https://github.com/qmk/qmk_firmware/pull/20183)) -* Remove `RGB_DI_PIN` ifdefs ([#20218](https://github.com/qmk/qmk_firmware/pull/20218)) -* Add the KJ-Modify RS40 PCB keyboard ([#20243](https://github.com/qmk/qmk_firmware/pull/20243)) -* Move `WS2812_DRIVER` to data driven ([#20248](https://github.com/qmk/qmk_firmware/pull/20248)) -* [jacky_studio/piggy60] move AVR PCB under rev1 ([#20253](https://github.com/qmk/qmk_firmware/pull/20253)) -* Move 75% and 96% layouts to data driven ([#20289](https://github.com/qmk/qmk_firmware/pull/20289)) -* Move split layouts to data driven ([#20290](https://github.com/qmk/qmk_firmware/pull/20290)) -* Move 66% and 68% layouts to data driven ([#20293](https://github.com/qmk/qmk_firmware/pull/20293)) -* add jacky_studio/piggy60/rev2 ([#20297](https://github.com/qmk/qmk_firmware/pull/20297)) -* Move 65% layouts to data driven ([#20308](https://github.com/qmk/qmk_firmware/pull/20308)) -* Move TKL F13 and FRL layouts to data driven ([#20310](https://github.com/qmk/qmk_firmware/pull/20310)) -* Remove some use of keymap.h ([#20316](https://github.com/qmk/qmk_firmware/pull/20316)) -* Move fullsize layouts to data driven ([#20317](https://github.com/qmk/qmk_firmware/pull/20317)) -* Add 36-key layout for Beekeeb Piantor ([#20328](https://github.com/qmk/qmk_firmware/pull/20328)) -* Add sriwedari70 and move kamigakushi to new folder ([#20334](https://github.com/qmk/qmk_firmware/pull/20334)) -* Move TKL layouts to data driven ([#20337](https://github.com/qmk/qmk_firmware/pull/20337)) -* Move Alice and Ergodox layouts to data driven ([#20340](https://github.com/qmk/qmk_firmware/pull/20340)) -* Move small macropad-ish layouts to data driven ([#20341](https://github.com/qmk/qmk_firmware/pull/20341)) -* Move `default` layouts to data driven ([#20349](https://github.com/qmk/qmk_firmware/pull/20349)) -* Move `RGB_MATRIX_DRIVER` to data driven ([#20350](https://github.com/qmk/qmk_firmware/pull/20350)) -* Move split space/backspace layouts to data driven ([#20356](https://github.com/qmk/qmk_firmware/pull/20356)) -* Move single `LAYOUT`s to data driven ([#20365](https://github.com/qmk/qmk_firmware/pull/20365)) -* Add encoder map for Iris Rev. 5 VIA ([#20412](https://github.com/qmk/qmk_firmware/pull/20412)) -* Move remaining `LAYOUT`s to data driven ([#20422](https://github.com/qmk/qmk_firmware/pull/20422)) -* Move single `LAYOUT_all`s to data driven ([#20430](https://github.com/qmk/qmk_firmware/pull/20430)) -* 4pplet/yakiimo Layout Macro Conversion and Additions ([#20436](https://github.com/qmk/qmk_firmware/pull/20436)) -* Move single `60_ansi`, `60_hhkb` and `60_iso` layouts to data driven ([#20438](https://github.com/qmk/qmk_firmware/pull/20438)) -* Update brauner preonic layout ([#20439](https://github.com/qmk/qmk_firmware/pull/20439)) -* AEBoards Satellite Rev1 Layout Macro Conversion ([#20442](https://github.com/qmk/qmk_firmware/pull/20442)) -* Acheron Austin Layout Macro Conversion and Additions ([#20443](https://github.com/qmk/qmk_firmware/pull/20443)) -* Move remaining `LAYOUT_all`s to data driven ([#20463](https://github.com/qmk/qmk_firmware/pull/20463)) -* Update lotus58 RGB config ([#20468](https://github.com/qmk/qmk_firmware/pull/20468)) -* Cleanup `ekow/akira` ([#20474](https://github.com/qmk/qmk_firmware/pull/20474)) -* Move 60% layouts to data driven ([#20477](https://github.com/qmk/qmk_firmware/pull/20477)) -* Move DZ60 and MJ6XY layouts to data driven ([#20478](https://github.com/qmk/qmk_firmware/pull/20478)) -* AEBoards Constellation Layout Macro Updates ([#20487](https://github.com/qmk/qmk_firmware/pull/20487)) -* AI03 Equinox Layout Macro Additions ([#20488](https://github.com/qmk/qmk_firmware/pull/20488)) -* AI03 Vega Layout Macro Additions ([#20489](https://github.com/qmk/qmk_firmware/pull/20489)) -* AKB OGR Layout Macro Additions ([#20490](https://github.com/qmk/qmk_firmware/pull/20490)) -* AKB Vero Layout Macro Additions ([#20491](https://github.com/qmk/qmk_firmware/pull/20491)) -* Alf DC60 Layout Macro Additions ([#20494](https://github.com/qmk/qmk_firmware/pull/20494)) -* Alf X2 Layout Macro Additions ([#20495](https://github.com/qmk/qmk_firmware/pull/20495)) -* Koolertron AMAG23 Touch-Up ([#20496](https://github.com/qmk/qmk_firmware/pull/20496)) -* BIOI G60 Layout Macro Additions ([#20498](https://github.com/qmk/qmk_firmware/pull/20498)) -* BIOI Morgan65 Layout Macro Additions ([#20499](https://github.com/qmk/qmk_firmware/pull/20499)) -* BIOI S65 Layout Macro Additions ([#20500](https://github.com/qmk/qmk_firmware/pull/20500)) -* Boston Layout Macro Additions ([#20504](https://github.com/qmk/qmk_firmware/pull/20504)) -* Potato65S Layout Macro Additions ([#20508](https://github.com/qmk/qmk_firmware/pull/20508)) -* Move miscellaneous layouts to data driven ([#20516](https://github.com/qmk/qmk_firmware/pull/20516)) -* Cable Car Designs Cypher rev6 Layout Additions and Touch-Up ([#20518](https://github.com/qmk/qmk_firmware/pull/20518)) -* Caffeinated Studios Serpent65 Layout Macro Additions ([#20519](https://github.com/qmk/qmk_firmware/pull/20519)) -* CannonKeys Adelie Layout Macro Additions ([#20546](https://github.com/qmk/qmk_firmware/pull/20546)) -* CannonKeys Aella Layout Macro Additions ([#20547](https://github.com/qmk/qmk_firmware/pull/20547)) -* CannonKeys Balance Layout Macro Additions and Touch-Up ([#20548](https://github.com/qmk/qmk_firmware/pull/20548)) -* CannonKeys Brutal v2 1800 Layout Macro Additions ([#20549](https://github.com/qmk/qmk_firmware/pull/20549)) -* CannonKeys Brutal v2 65 Layout Macro Additions ([#20552](https://github.com/qmk/qmk_firmware/pull/20552)) -* CannonKeys Cloudline Layout Macro Additions ([#20553](https://github.com/qmk/qmk_firmware/pull/20553)) -* CannonKeys Crin Layout Macro Additions ([#20554](https://github.com/qmk/qmk_firmware/pull/20554)) -* CannonKeys DevastatingTKL Layout Macro Additions ([#20555](https://github.com/qmk/qmk_firmware/pull/20555)) -* CannonKeys Ellipse Layout Macro Additions ([#20558](https://github.com/qmk/qmk_firmware/pull/20558)) -* CannonKeys Ellipse Hotswap Layout Macro Addition & Touch-Up ([#20560](https://github.com/qmk/qmk_firmware/pull/20560)) -* CannonKeys Gentoo Layout Macro Additions ([#20561](https://github.com/qmk/qmk_firmware/pull/20561)) -* CannonKeys Gentoo Hotswap Touch-Up ([#20562](https://github.com/qmk/qmk_firmware/pull/20562)) -* CannonKeys HoodrowG Layout Macro Additions ([#20563](https://github.com/qmk/qmk_firmware/pull/20563)) -* CannonKeys Moment Layout Macro Additions ([#20564](https://github.com/qmk/qmk_firmware/pull/20564)) -* CannonKeys Moment Hotswap Touch-Up ([#20565](https://github.com/qmk/qmk_firmware/pull/20565)) -* CannonKeys Nearfield Layout Macro Addition ([#20566](https://github.com/qmk/qmk_firmware/pull/20566)) -* CannonKeys Obliterated75 Layout Macro Additions ([#20567](https://github.com/qmk/qmk_firmware/pull/20567)) -* CannonKeys Onyx Layout Macro Additions ([#20568](https://github.com/qmk/qmk_firmware/pull/20568)) -* CannonKeys Rekt1800 Layout Macro Additions ([#20569](https://github.com/qmk/qmk_firmware/pull/20569)) -* CannonKeys Serenity Layout Macro Additions ([#20570](https://github.com/qmk/qmk_firmware/pull/20570)) -* CannonKeys Vector Layout Macro Additions ([#20571](https://github.com/qmk/qmk_firmware/pull/20571)) -* Carbo65 Community Layout support ([#20580](https://github.com/qmk/qmk_firmware/pull/20580)) -* cest73 TKM Layout Macro Additions ([#20583](https://github.com/qmk/qmk_firmware/pull/20583)) -* Charue Charon Layout Macro Additions ([#20585](https://github.com/qmk/qmk_firmware/pull/20585)) -* Charue Sunsetter R2 Layout Macro Additions ([#20586](https://github.com/qmk/qmk_firmware/pull/20586)) -* Remove `FLIP_HALF` layouts and move to data driven ([#20588](https://github.com/qmk/qmk_firmware/pull/20588)) -* update ymdk/id75/rules.mk for develop ([#20592](https://github.com/qmk/qmk_firmware/pull/20592)) -* CherryB Studio CB1800 Layout Macro Additions ([#20593](https://github.com/qmk/qmk_firmware/pull/20593)) -* CherryB Studio CB65 Layout Macro Additions ([#20594](https://github.com/qmk/qmk_firmware/pull/20594)) -* CherryB Studio CB87RGB Layout Macro Additions ([#20595](https://github.com/qmk/qmk_firmware/pull/20595)) -* CheckerBoards G_IDB60 Layout Macro Edits ([#20596](https://github.com/qmk/qmk_firmware/pull/20596)) -* CherryB Studio CB87v2 Layout Macro Additions ([#20597](https://github.com/qmk/qmk_firmware/pull/20597)) -* CX60 Community Layout Support ([#20598](https://github.com/qmk/qmk_firmware/pull/20598)) -* Demiurge Layout Macro Touch-Up ([#20599](https://github.com/qmk/qmk_firmware/pull/20599)) -* Ducky One 2 SF 1967ST Layout Macro Additions ([#20600](https://github.com/qmk/qmk_firmware/pull/20600)) -* Move `FORCE_NKRO` to data driven ([#20604](https://github.com/qmk/qmk_firmware/pull/20604)) -* dyz Synthesis60 Layout Macro Addition ([#20610](https://github.com/qmk/qmk_firmware/pull/20610)) -* DZTech Bocc Layout Macro Additions ([#20611](https://github.com/qmk/qmk_firmware/pull/20611)) -* E88 Layout Macro Additions ([#20612](https://github.com/qmk/qmk_firmware/pull/20612)) -* Emery65 Layout Macro Additions ([#20613](https://github.com/qmk/qmk_firmware/pull/20613)) -* EvyD13 MX5160 Layout Macro Additions ([#20614](https://github.com/qmk/qmk_firmware/pull/20614)) -* FJLabs AD65 Layout Macro Additions ([#20619](https://github.com/qmk/qmk_firmware/pull/20619)) -* FJLabs Avalon Layout Additions and Touch-Up ([#20620](https://github.com/qmk/qmk_firmware/pull/20620)) -* FJLabs Midway60 Layout Macro Additions ([#20621](https://github.com/qmk/qmk_firmware/pull/20621)) -* FJLabs Polaris Layout Additions and Touch-Up ([#20622](https://github.com/qmk/qmk_firmware/pull/20622)) -* FJLabs Sinanju WK Layout Additions and Touch-Up ([#20628](https://github.com/qmk/qmk_firmware/pull/20628)) -* LFK87 refactor ([#20635](https://github.com/qmk/qmk_firmware/pull/20635)) -* Fox Lab Time80 Layout Macro Additions ([#20636](https://github.com/qmk/qmk_firmware/pull/20636)) -* FJLabs Solanis Layout Macro Additions ([#20639](https://github.com/qmk/qmk_firmware/pull/20639)) -* GrayStudio Aero 75 Refactor and Touch-Up ([#20640](https://github.com/qmk/qmk_firmware/pull/20640)) -* Move `USB_MAX_POWER_CONSUMPTION` to data driven ([#20648](https://github.com/qmk/qmk_firmware/pull/20648)) -* `info.json` whitespace cleanups ([#20651](https://github.com/qmk/qmk_firmware/pull/20651)) -* Hand88 Layout Macro Additions ([#20657](https://github.com/qmk/qmk_firmware/pull/20657)) -* Cyberstar Handwired Layout Macro Additions ([#20658](https://github.com/qmk/qmk_firmware/pull/20658)) -* split_65 Handwired Layout Macro Addition and Touch-Up ([#20659](https://github.com/qmk/qmk_firmware/pull/20659)) -* Bebol Handwired Layout Macro Additions ([#20660](https://github.com/qmk/qmk_firmware/pull/20660)) -* Glacier Handwired Layout Macro Addition and Touch-Up ([#20661](https://github.com/qmk/qmk_firmware/pull/20661)) -* Koalafications Handwired Layout Macro Additions ([#20662](https://github.com/qmk/qmk_firmware/pull/20662)) -* The Galleon Handwired Layout Macro Additions ([#20663](https://github.com/qmk/qmk_firmware/pull/20663)) -* More `info.json` whitespace cleanups ([#20665](https://github.com/qmk/qmk_firmware/pull/20665)) -* Remove use of layout macros for LFKeyboards LED config ([#20666](https://github.com/qmk/qmk_firmware/pull/20666)) -* Helix rev2: remove 4 rows option ([#20667](https://github.com/qmk/qmk_firmware/pull/20667)) -* Wakizashi40 Handwired Touch-Up ([#20671](https://github.com/qmk/qmk_firmware/pull/20671)) -* yttyx: convert readme to utf-8 encoding ([#20672](https://github.com/qmk/qmk_firmware/pull/20672)) -* Alicia Cook Layout Macro Additions ([#20675](https://github.com/qmk/qmk_firmware/pull/20675)) -* Primus75 Layout Macro Additions ([#20676](https://github.com/qmk/qmk_firmware/pull/20676)) -* Volcano660 Layout Macro Additions ([#20677](https://github.com/qmk/qmk_firmware/pull/20677)) -* Iris Keyboards Iris60 Layout Macro Additions ([#20678](https://github.com/qmk/qmk_firmware/pull/20678)) -* Irene Layout Macro Additions ([#20679](https://github.com/qmk/qmk_firmware/pull/20679)) -* Iron180 Layout Macro Additions ([#20680](https://github.com/qmk/qmk_firmware/pull/20680)) -* kinesis/alvicstep: remove kicad project files ([#20681](https://github.com/qmk/qmk_firmware/pull/20681)) -* Remove more junk files and scripts ([#20682](https://github.com/qmk/qmk_firmware/pull/20682)) -* JKeys Design Gentleman65 Layout Macro Addition and Touch-Up ([#20684](https://github.com/qmk/qmk_firmware/pull/20684)) -* JKeys Design Gentleman65 Suited Edition Layout Macro Addition ([#20685](https://github.com/qmk/qmk_firmware/pull/20685)) -* add additional layouts to `dactyl_manuform` variants ([#20688](https://github.com/qmk/qmk_firmware/pull/20688)) -* TheDogKeyboard Layout Macro Addition ([#20689](https://github.com/qmk/qmk_firmware/pull/20689)) -* KBDfans Bella Soldered Layout Macro Additions ([#20691](https://github.com/qmk/qmk_firmware/pull/20691)) -* KBDfans Bounce75 Hotswap Touch-Up ([#20692](https://github.com/qmk/qmk_firmware/pull/20692)) -* KBDfans KBD66 Layout Additions and Refactor ([#20693](https://github.com/qmk/qmk_firmware/pull/20693)) -* KBDfans Odin RGB Touch-Up ([#20694](https://github.com/qmk/qmk_firmware/pull/20694)) -* KBDfans Odin Soldered Layout Additions and Touch-Up ([#20695](https://github.com/qmk/qmk_firmware/pull/20695)) -* keebzdotnet FMe Layout Additions ([#20696](https://github.com/qmk/qmk_firmware/pull/20696)) -* Kegen G-Boy Layout Additions ([#20697](https://github.com/qmk/qmk_firmware/pull/20697)) -* Escape Unicode characters in info.json ([#20698](https://github.com/qmk/qmk_firmware/pull/20698)) -* Kiko's Lab Ellora65 Layout Additions ([#20699](https://github.com/qmk/qmk_firmware/pull/20699)) -* Even more `info.json` whitespace cleanups ([#20703](https://github.com/qmk/qmk_firmware/pull/20703)) -* kkatano Bakeneko 65 V3 Layout Additions ([#20706](https://github.com/qmk/qmk_firmware/pull/20706)) -* kopibeng MNK65 Layout Additions ([#20708](https://github.com/qmk/qmk_firmware/pull/20708)) -* kopibeng Typ65+ Layout Additions ([#20710](https://github.com/qmk/qmk_firmware/pull/20710)) -* kopibeng XT60 Layout Additions ([#20711](https://github.com/qmk/qmk_firmware/pull/20711)) -* kopibeng XT60_SINGA Layout Additions ([#20712](https://github.com/qmk/qmk_firmware/pull/20712)) -* kopibeng XT8x Layout Additions ([#20713](https://github.com/qmk/qmk_firmware/pull/20713)) -* Lefty Touch-Up ([#20714](https://github.com/qmk/qmk_firmware/pull/20714)) -* Loki65 Layout Additions ([#20715](https://github.com/qmk/qmk_firmware/pull/20715)) -* Lucid Alexa Solder Layout Additions ([#20716](https://github.com/qmk/qmk_firmware/pull/20716)) -* Lucid Phantom Soldered Layout Additions ([#20717](https://github.com/qmk/qmk_firmware/pull/20717)) -* Leftover30 Layout Addition ([#20718](https://github.com/qmk/qmk_firmware/pull/20718)) -* Matrix Cain RE Touch-Up ([#20719](https://github.com/qmk/qmk_firmware/pull/20719)) -* Matrix Lab 8XV1.2 OG Layout Updates ([#20720](https://github.com/qmk/qmk_firmware/pull/20720)) -* Mechlovin Studio Hex6C Layout Additions ([#20722](https://github.com/qmk/qmk_firmware/pull/20722)) -* Mechlovin.Studio Rogue87 Rev.1 Layout Additions ([#20724](https://github.com/qmk/qmk_firmware/pull/20724)) -* Mechlovin.Studio Rouge87 Rev.1 Layout Additions ([#20725](https://github.com/qmk/qmk_firmware/pull/20725)) -* Mechlovin.Studio infinity87 Rev.1 Layout Additions ([#20726](https://github.com/qmk/qmk_firmware/pull/20726)) -* Mechlovin.Studio Infinity87 RGB Rev1 Layout Additions ([#20727](https://github.com/qmk/qmk_firmware/pull/20727)) -* Mechlovin9 Layout Addition ([#20728](https://github.com/qmk/qmk_firmware/pull/20728)) -* 1upkeyboards/pi50 WS2812_DI_PIN patch for develop ([#20731](https://github.com/qmk/qmk_firmware/pull/20731)) -* Mechlovin.Studio Infinity87 Rev.2 Layout Additions ([#20735](https://github.com/qmk/qmk_firmware/pull/20735)) -* Mechlovin.Studio Olly JF Layout Additions ([#20736](https://github.com/qmk/qmk_firmware/pull/20736)) -* Mechlovin Studio Serratus Layout Additions ([#20737](https://github.com/qmk/qmk_firmware/pull/20737)) -* MechWild Mercutio Layout Addition ([#20738](https://github.com/qmk/qmk_firmware/pull/20738)) -* MisterKnife Knife66 ISO Layout Addition ([#20739](https://github.com/qmk/qmk_firmware/pull/20739)) -* MNK1800s Layout Addition ([#20740](https://github.com/qmk/qmk_firmware/pull/20740)) -* MNK75 Layout Additions ([#20741](https://github.com/qmk/qmk_firmware/pull/20741)) -* Mode SixtyFive S Layout Additions ([#20742](https://github.com/qmk/qmk_firmware/pull/20742)) -* Mode SeventyFive H Layout Addition ([#20743](https://github.com/qmk/qmk_firmware/pull/20743)) -* Monstargear XO87 Soldered Layout Additions ([#20744](https://github.com/qmk/qmk_firmware/pull/20744)) -* MTBKeys MTB60 Solder Layout Additions ([#20745](https://github.com/qmk/qmk_firmware/pull/20745)) -* Nix Keyboards Day Off 60 Touch-Up and Layout Additions ([#20746](https://github.com/qmk/qmk_firmware/pull/20746)) -* Kastenwagen 1840 Layout Addition ([#20747](https://github.com/qmk/qmk_firmware/pull/20747)) -* Kastenwagen 48 Layout Addition ([#20748](https://github.com/qmk/qmk_firmware/pull/20748)) -* NovelKeys NK87 Touch-Up ([#20749](https://github.com/qmk/qmk_firmware/pull/20749)) -* NovelKeys NK87B Touch-Up ([#20750](https://github.com/qmk/qmk_firmware/pull/20750)) -* Noxary 378 Layout Addition ([#20751](https://github.com/qmk/qmk_firmware/pull/20751)) -* Noxary Valhalla Layout Addition ([#20752](https://github.com/qmk/qmk_firmware/pull/20752)) -* Nightly Boards/DeskDaily Daily60 Layout Additions ([#20753](https://github.com/qmk/qmk_firmware/pull/20753)) -* Odelia Touch-Up ([#20754](https://github.com/qmk/qmk_firmware/pull/20754)) -* One Key Co Dango40 Touch-Up and Layout Addition ([#20755](https://github.com/qmk/qmk_firmware/pull/20755)) -* P3D Glitch Layout Addition ([#20763](https://github.com/qmk/qmk_firmware/pull/20763)) -* Pearl Boards Pandora Layout Additions ([#20764](https://github.com/qmk/qmk_firmware/pull/20764)) -* Pearl Boards Pearl Layout Addition ([#20765](https://github.com/qmk/qmk_firmware/pull/20765)) -* support boards with APM32 instead of the STM32 ([#20770](https://github.com/qmk/qmk_firmware/pull/20770)) -* Pearl Boards Zeus Layout Additions ([#20773](https://github.com/qmk/qmk_firmware/pull/20773)) -* Peej Rosaline Staggered Layout Additions ([#20774](https://github.com/qmk/qmk_firmware/pull/20774)) -* plywrks Lune Layout Touch-Up ([#20775](https://github.com/qmk/qmk_firmware/pull/20775)) -* Project Keyboard Signature65 Layout Additions ([#20776](https://github.com/qmk/qmk_firmware/pull/20776)) -* protoTypist Allison Layout Additions ([#20777](https://github.com/qmk/qmk_firmware/pull/20777)) -* Prototypist J-01 Rev1 Layout Additions ([#20778](https://github.com/qmk/qmk_firmware/pull/20778)) -* Protozoa Cassini Layout Additions ([#20779](https://github.com/qmk/qmk_firmware/pull/20779)) -* Protozoa P.01 Layout Additions ([#20781](https://github.com/qmk/qmk_firmware/pull/20781)) -* QwertleKeys Calice Layout Addition ([#20782](https://github.com/qmk/qmk_firmware/pull/20782)) -* Ramlord WITF Layout Touch-Up and Addition ([#20783](https://github.com/qmk/qmk_firmware/pull/20783)) -* Rart45: rename LAYOUT_all to LAYOUT ([#20784](https://github.com/qmk/qmk_firmware/pull/20784)) -* Rart60 Layout Additions ([#20785](https://github.com/qmk/qmk_firmware/pull/20785)) -* Rart67 Layout Additions ([#20786](https://github.com/qmk/qmk_firmware/pull/20786)) -* Rart67M: rename LAYOUT_all to LAYOUT ([#20787](https://github.com/qmk/qmk_firmware/pull/20787)) -* RART75 Layout Additions ([#20788](https://github.com/qmk/qmk_firmware/pull/20788)) -* RART75 Hotswap Layout Additions ([#20789](https://github.com/qmk/qmk_firmware/pull/20789)) -* RART75M: rename LAYOUT_all to LAYOUT ([#20790](https://github.com/qmk/qmk_firmware/pull/20790)) -* RART80 Hotswap Layout Additions ([#20791](https://github.com/qmk/qmk_firmware/pull/20791)) -* Rartand Layout Additions ([#20799](https://github.com/qmk/qmk_firmware/pull/20799)) -* Rartlice: rename LAYOUT_all to LAYOUT ([#20800](https://github.com/qmk/qmk_firmware/pull/20800)) -* Ratio65 Hotswap: rename LAYOUT_all to LAYOUT_65_ansi_blocker ([#20801](https://github.com/qmk/qmk_firmware/pull/20801)) -* Ratio65 Solder Layout Additions ([#20802](https://github.com/qmk/qmk_firmware/pull/20802)) -* Specifying the default board file is redundant ([#20807](https://github.com/qmk/qmk_firmware/pull/20807)) -* RGBKB Pan Layout Additions ([#20809](https://github.com/qmk/qmk_firmware/pull/20809)) -* saevus cor Layout Additions ([#20810](https://github.com/qmk/qmk_firmware/pull/20810)) -* Clean up trailing commas from info.json ([#20812](https://github.com/qmk/qmk_firmware/pull/20812)) -* Enable LTO on salicylic acid 7skb to reduce size ([#20813](https://github.com/qmk/qmk_firmware/pull/20813)) -* Reduce compiled size for mt64rgb's via keymap ([#20814](https://github.com/qmk/qmk_firmware/pull/20814)) -* Reduce compiled size for prototypist oceanographer's via keymap ([#20816](https://github.com/qmk/qmk_firmware/pull/20816)) -* Sauce Mild Layout Additions ([#20818](https://github.com/qmk/qmk_firmware/pull/20818)) -* VCL x SawnsProjects VCL65 Layout Additions ([#20819](https://github.com/qmk/qmk_firmware/pull/20819)) -* senselessclay had60 Layout Additions ([#20820](https://github.com/qmk/qmk_firmware/pull/20820)) -* Space Holdings Nebula12B ([#20821](https://github.com/qmk/qmk_firmware/pull/20821)) -* SmithRune Iron180 Layout Additions ([#20822](https://github.com/qmk/qmk_firmware/pull/20822)) -* Stello65 Beta Layout Additions and Clean-Up ([#20824](https://github.com/qmk/qmk_firmware/pull/20824)) -* Studio Kestra Nue Layout Additions ([#20825](https://github.com/qmk/qmk_firmware/pull/20825)) -* Switchplate Peripherals 910 Layout Additions ([#20827](https://github.com/qmk/qmk_firmware/pull/20827)) -* TKC California Layout Addition and Touch-Up ([#20829](https://github.com/qmk/qmk_firmware/pull/20829)) -* TKC M0lly Layout Additions ([#20830](https://github.com/qmk/qmk_firmware/pull/20830)) -* TKC TKL A/B87 Layout Additions ([#20831](https://github.com/qmk/qmk_firmware/pull/20831)) -* Viendi 8L Layout Additions ([#20832](https://github.com/qmk/qmk_firmware/pull/20832)) -* Viktus Smolka Layout Additions ([#20833](https://github.com/qmk/qmk_firmware/pull/20833)) -* Viktus SP111 Layout Additions ([#20834](https://github.com/qmk/qmk_firmware/pull/20834)) -* Viktus SP_Mini Layout Additions ([#20835](https://github.com/qmk/qmk_firmware/pull/20835)) -* W1-AT Layout Additions ([#20842](https://github.com/qmk/qmk_firmware/pull/20842)) -* Weirdo Geminate60 Layout Additions ([#20843](https://github.com/qmk/qmk_firmware/pull/20843)) -* Cypher rev5 Layout Additions ([#20844](https://github.com/qmk/qmk_firmware/pull/20844)) -* Prophet Layout Additions ([#20845](https://github.com/qmk/qmk_firmware/pull/20845)) -* Tidy up encoder_map directions ([#20847](https://github.com/qmk/qmk_firmware/pull/20847)) -* Rama Works Koyu Community Layout Support ([#20848](https://github.com/qmk/qmk_firmware/pull/20848)) -* Rama Works M65-B Community Layout Support ([#20850](https://github.com/qmk/qmk_firmware/pull/20850)) -* Rama Works M65-BX Community Layout Support ([#20851](https://github.com/qmk/qmk_firmware/pull/20851)) -* Rama Works U80-A Community Layout Support ([#20853](https://github.com/qmk/qmk_firmware/pull/20853)) -* Wilba Tech WT60-B Community Layout Support ([#20854](https://github.com/qmk/qmk_firmware/pull/20854)) -* Wilba Tech WT60-BX Layout Additions and Touch-Up ([#20855](https://github.com/qmk/qmk_firmware/pull/20855)) -* Wilba Tech WT60-C Community Layout Support ([#20858](https://github.com/qmk/qmk_firmware/pull/20858)) -* Wilba Tech WT60-D Layout Addition and Touch-Up ([#20859](https://github.com/qmk/qmk_firmware/pull/20859)) -* Wilba Tech WT60-G Community Layout Support ([#20860](https://github.com/qmk/qmk_firmware/pull/20860)) -* Wilba Tech WT60-G2 Community Layout Support ([#20861](https://github.com/qmk/qmk_firmware/pull/20861)) -* Wilba Tech WT60-H2: rename LAYOUT_all to LAYOUT_60_ansi_tsangan_split_rshift ([#20864](https://github.com/qmk/qmk_firmware/pull/20864)) -* Wilba Tech WT60-XT Layout Additions and Touch-Up ([#20865](https://github.com/qmk/qmk_firmware/pull/20865)) -* Wilba Tech WT65-A Community Layout Support and Touch-Up ([#20866](https://github.com/qmk/qmk_firmware/pull/20866)) -* Wilba Tech WT65-B Layout Addition and Touch-Up ([#20867](https://github.com/qmk/qmk_firmware/pull/20867)) -* Wilba Tech WT65-F Community Layout Support and Touch-Up ([#20869](https://github.com/qmk/qmk_firmware/pull/20869)) -* Wilba Tech WT65-FX Community Layout Support ([#20870](https://github.com/qmk/qmk_firmware/pull/20870)) -* Wilba Tech WT65-G Layout Additions and Touch-Up ([#20871](https://github.com/qmk/qmk_firmware/pull/20871)) -* Wilba Tech WT65-G2 Layout Additions and Touch-Up ([#20872](https://github.com/qmk/qmk_firmware/pull/20872)) -* Wilba Tech WT65-XT: rename LAYOUT_all to LAYOUT_65_xt_ansi_blocker_tsangan ([#20873](https://github.com/qmk/qmk_firmware/pull/20873)) -* Wilba Tech WT65-XTX Layout Additions and Touch-Up ([#20874](https://github.com/qmk/qmk_firmware/pull/20874)) -* Wilba Tech WT69-A Layout Addition and Touch-Up ([#20875](https://github.com/qmk/qmk_firmware/pull/20875)) -* Wilba Tech WT70-JB Layout Addition and Touch-Up ([#20876](https://github.com/qmk/qmk_firmware/pull/20876)) -* Wilba Tech WT75-A Layout Additions and Touch-Up ([#20877](https://github.com/qmk/qmk_firmware/pull/20877)) -* Wilba Tech WT75-B Layout Additions and Touch-Up ([#20878](https://github.com/qmk/qmk_firmware/pull/20878)) -* Wilba Tech WT75-C Layout Additions and Touch-Up ([#20879](https://github.com/qmk/qmk_firmware/pull/20879)) -* Wilba Tech WT80-G Layout Additions and Touch-Up ([#20880](https://github.com/qmk/qmk_firmware/pull/20880)) -* WinKeys Mini Winni: rename LAYOUT_all to LAYOUT_ortho_2x4 ([#20881](https://github.com/qmk/qmk_firmware/pull/20881)) -* Scarlet Bandana Layout Additions ([#20882](https://github.com/qmk/qmk_firmware/pull/20882)) -* Winkeyless B87 Community Layout Support ([#20884](https://github.com/qmk/qmk_firmware/pull/20884)) -* Xelus AkiS Layout Additions ([#20885](https://github.com/qmk/qmk_firmware/pull/20885)) -* Xelus Dharma Layout Additions ([#20886](https://github.com/qmk/qmk_firmware/pull/20886)) -* Xelus Kangaroo Layout Additions ([#20887](https://github.com/qmk/qmk_firmware/pull/20887)) -* Xelus La+ Layout Addition ([#20888](https://github.com/qmk/qmk_firmware/pull/20888)) -* Xelus Pachi Mini 32U4 Community Layout Support ([#20889](https://github.com/qmk/qmk_firmware/pull/20889)) -* Xelus Pachi rev1 Community Layout Support ([#20891](https://github.com/qmk/qmk_firmware/pull/20891)) -* Xelus Trinity XT TKL Layout Additions ([#20892](https://github.com/qmk/qmk_firmware/pull/20892)) -* Xelus Valor FRL TKL Layout Additions ([#20893](https://github.com/qmk/qmk_firmware/pull/20893)) -* YDKB Chili Community Layout Support ([#20895](https://github.com/qmk/qmk_firmware/pull/20895)) -* YDKB Grape Layout Additions ([#20899](https://github.com/qmk/qmk_firmware/pull/20899)) -* YMDK Wings Layout Addition ([#20900](https://github.com/qmk/qmk_firmware/pull/20900)) -* YMDK Wings Hotswap: rename LAYOUT_all to LAYOUT ([#20901](https://github.com/qmk/qmk_firmware/pull/20901)) -* YMDK YM68 Community Layout Support ([#20906](https://github.com/qmk/qmk_firmware/pull/20906)) -* Yugo-M Controller Layout Additions ([#20907](https://github.com/qmk/qmk_firmware/pull/20907)) -* Zicodia TKLFRLNRLMLAO Layout Addition ([#20908](https://github.com/qmk/qmk_firmware/pull/20908)) -* ZTBoards After Layout Addition ([#20912](https://github.com/qmk/qmk_firmware/pull/20912)) -* ZTBoards Noon Layout Addition ([#20913](https://github.com/qmk/qmk_firmware/pull/20913)) -* SawnsProjects Amber80 Solder Community Layout Support ([#20917](https://github.com/qmk/qmk_firmware/pull/20917)) -* Pearl Boards Atlas Layout Additions ([#20918](https://github.com/qmk/qmk_firmware/pull/20918)) -* Xiudi XD004: rename LAYOUT_all to LAYOUT_ortho_1x4 ([#20919](https://github.com/qmk/qmk_firmware/pull/20919)) -* Wilba Tech WT80-BC Community Layout Support ([#20920](https://github.com/qmk/qmk_firmware/pull/20920)) -* 4pplet Eagle Viper REP Rev B Community Layout Support ([#20921](https://github.com/qmk/qmk_firmware/pull/20921)) -* FR4Boards unix60 Layout Additions ([#20926](https://github.com/qmk/qmk_firmware/pull/20926)) -* MC-76K: rename LAYOUT_all to LAYOUT ([#20927](https://github.com/qmk/qmk_firmware/pull/20927)) -* Mechlovin Studio Jay60 Community Layout Support ([#20928](https://github.com/qmk/qmk_firmware/pull/20928)) -* MisterKnife Knife66 Layout Additions ([#20929](https://github.com/qmk/qmk_firmware/pull/20929)) -* MisterKnife Knife66 ISO Layout Additions II ([#20930](https://github.com/qmk/qmk_firmware/pull/20930)) -* 4pplet Waffling80 Community Layout Support and Touch-Up ([#20932](https://github.com/qmk/qmk_firmware/pull/20932)) -* Acheron Elongate Delta: rename LAYOUT_all to LAYOUT ([#20956](https://github.com/qmk/qmk_firmware/pull/20956)) -* ADPenrose Akemipad Layout Addition ([#20957](https://github.com/qmk/qmk_firmware/pull/20957)) -* ADPenrose Shisaku: rename LAYOUT_all to LAYOUT ([#20958](https://github.com/qmk/qmk_firmware/pull/20958)) -* AEBoards Aegis Layout Additions ([#20960](https://github.com/qmk/qmk_firmware/pull/20960)) -* rart/rart80:via: restore rules.mk after #20334 ([#21002](https://github.com/qmk/qmk_firmware/pull/21002)) -* Remove HHKB RN42 code ([#21007](https://github.com/qmk/qmk_firmware/pull/21007)) -* Move `thekey` to Drop vendor folder ([#21032](https://github.com/qmk/qmk_firmware/pull/21032)) - -Keyboard fixes: -* userspace/community layout fixes ([#19998](https://github.com/qmk/qmk_firmware/pull/19998)) -* Fix layout macro keys with no matrix position ([#20033](https://github.com/qmk/qmk_firmware/pull/20033)) -* Restore matrix pins for ep/40 ([#20083](https://github.com/qmk/qmk_firmware/pull/20083)) -* kbdfans/tiger80: remove duplicate keys in info.json ([#20148](https://github.com/qmk/qmk_firmware/pull/20148)) -* Fixup z70ultra — replace mis-removed file ([#20157](https://github.com/qmk/qmk_firmware/pull/20157)) -* Fixup CI build for F103C6 onekey. ([#20188](https://github.com/qmk/qmk_firmware/pull/20188)) -* Fix layouts containing keys with multiple matrix positions ([#20191](https://github.com/qmk/qmk_firmware/pull/20191)) -* Fix some more missing `#pragma once`s ([#20241](https://github.com/qmk/qmk_firmware/pull/20241)) -* Fixup CI build for `nack`. ([#20292](https://github.com/qmk/qmk_firmware/pull/20292)) -* Fixup Pointing device functions ([#20311](https://github.com/qmk/qmk_firmware/pull/20311)) -* Fix a handful of CLI errors ([#20321](https://github.com/qmk/qmk_firmware/pull/20321)) -* Fix API errors ([#20326](https://github.com/qmk/qmk_firmware/pull/20326)) -* Set up DEFAULT_FOLDER for primekb/meridian ([#20367](https://github.com/qmk/qmk_firmware/pull/20367)) -* Fix up via keymap builds. ([#20383](https://github.com/qmk/qmk_firmware/pull/20383)) -* Fix up via keymap builds. ([#20397](https://github.com/qmk/qmk_firmware/pull/20397)) -* Fix some missing QMK_KEYBOARD_H includes in user keymaps ([#20417](https://github.com/qmk/qmk_firmware/pull/20417)) -* Update ymdk/id75 config ([#20432](https://github.com/qmk/qmk_firmware/pull/20432)) -* Fix info.json LTO and format encoder definitions ([#20456](https://github.com/qmk/qmk_firmware/pull/20456)) -* Fixup dymium65 RGB Pin on develop ([#20473](https://github.com/qmk/qmk_firmware/pull/20473)) -* Fixup missing include in mxss `via` keymap ([#20475](https://github.com/qmk/qmk_firmware/pull/20475)) -* Fix nk plus ws2812 config ([#20524](https://github.com/qmk/qmk_firmware/pull/20524)) -* cannonkeys/ellipse_hs: correct layout macro references ([#20577](https://github.com/qmk/qmk_firmware/pull/20577)) -* Remove use of layout macros for `music_map` ([#20634](https://github.com/qmk/qmk_firmware/pull/20634)) -* Vertex/angle65 WS2812 pin fix ([#20653](https://github.com/qmk/qmk_firmware/pull/20653)) -* Fix ws2812 pin for phantagom boards ([#20670](https://github.com/qmk/qmk_firmware/pull/20670)) -* Fixup 1upkeyboards/pi50 ([#20733](https://github.com/qmk/qmk_firmware/pull/20733)) -* Fix `test_json2c_no_json()` ([#20756](https://github.com/qmk/qmk_firmware/pull/20756)) -* Fix mxss rgblight.c compilation issues ([#20804](https://github.com/qmk/qmk_firmware/pull/20804)) -* Fixup paladin64 ([#20805](https://github.com/qmk/qmk_firmware/pull/20805)) -* Fixup dogtag ([#20808](https://github.com/qmk/qmk_firmware/pull/20808)) -* Fixup zwag75 ([#20923](https://github.com/qmk/qmk_firmware/pull/20923)) -* Fixup latinpadble ([#20924](https://github.com/qmk/qmk_firmware/pull/20924)) -* Add missing layout data for a handful of boards ([#20931](https://github.com/qmk/qmk_firmware/pull/20931)) -* Fixup evo70 ([#20949](https://github.com/qmk/qmk_firmware/pull/20949)) -* Fixup Crkbd default keymap ([#20962](https://github.com/qmk/qmk_firmware/pull/20962)) -* Fix key display on Corne OLED ([#21044](https://github.com/qmk/qmk_firmware/pull/21044)) - -Others: -* Add layer-cycle example ([#19069](https://github.com/qmk/qmk_firmware/pull/19069)) -* Remove remnants of Vagrant. ([#20000](https://github.com/qmk/qmk_firmware/pull/20000)) -* Develop cleanup IS31FL3736 docs ([#20633](https://github.com/qmk/qmk_firmware/pull/20633)) -* Organise config/rules <-> info mappings ([#20723](https://github.com/qmk/qmk_firmware/pull/20723)) -* Add a change log for PR20584 ([#20998](https://github.com/qmk/qmk_firmware/pull/20998)) - -Bugs: -* Strip whitespace from CONVERT_TO variables ([#19948](https://github.com/qmk/qmk_firmware/pull/19948)) -* Check all rows have the correct number of columns when parsing `g_led_config` ([#19954](https://github.com/qmk/qmk_firmware/pull/19954)) -* Fix OSMs getting stuck ([#20034](https://github.com/qmk/qmk_firmware/pull/20034)) -* Fix rgblight layers when animations aren't enabled ([#20097](https://github.com/qmk/qmk_firmware/pull/20097)) -* Fixed split keyboard issue where custom LED indicators could activate incorrect LEDs (#20203) ([#20204](https://github.com/qmk/qmk_firmware/pull/20204)) -* Reduce _validate complexity ([#20274](https://github.com/qmk/qmk_firmware/pull/20274)) -* `qmk info`: account for ISO enter when calculating layout X offset ([#20325](https://github.com/qmk/qmk_firmware/pull/20325)) -* Disable specific warnings to mitigate compilation problems with `KEEP_INTERMEDIATES=yes`. ([#20339](https://github.com/qmk/qmk_firmware/pull/20339)) -* Fix compilation issue with Swap Hands and Encoder Map ([#20348](https://github.com/qmk/qmk_firmware/pull/20348)) -* Fix preprocessor condition for SPLIT_HAPTIC_ENABLE ([#20411](https://github.com/qmk/qmk_firmware/pull/20411)) -* Fix compilation issues with PS/2 driver on F4x1 controllers ([#20433](https://github.com/qmk/qmk_firmware/pull/20433)) -* Fix capital letters not getting sent with sendstring_swiss_fr.h ([#20515](https://github.com/qmk/qmk_firmware/pull/20515)) -* Duplicate board files for blok converter ([#20629](https://github.com/qmk/qmk_firmware/pull/20629)) -* Fix Mod-Tap combo regression ([#20669](https://github.com/qmk/qmk_firmware/pull/20669)) -* Revert use of legacy wear leveling driver now ChibiOS is fixed ([#20806](https://github.com/qmk/qmk_firmware/pull/20806)) -* Fix compilation error introduced by #20669 ([#20849](https://github.com/qmk/qmk_firmware/pull/20849)) -* Fix English word list retrieval in qmk generate-autocorrect-data ([#20915](https://github.com/qmk/qmk_firmware/pull/20915)) -* Improve keymap folder resolution ([#20981](https://github.com/qmk/qmk_firmware/pull/20981)) -* Fix issue with Repeat Key-Combo test ([#21005](https://github.com/qmk/qmk_firmware/pull/21005)) -* `qmk info` - Remove printing of "Keyboard Folder" ([#21033](https://github.com/qmk/qmk_firmware/pull/21033)) diff --git a/docs/README.md b/docs/README.md deleted file mode 100644 index 9330f0facee5..000000000000 --- a/docs/README.md +++ /dev/null @@ -1,37 +0,0 @@ -# Quantum Mechanical Keyboard Firmware - -## What is QMK Firmware? - -QMK (*Quantum Mechanical Keyboard*) is an open source community centered around developing computer input devices. The community encompasses all sorts of input devices, such as keyboards, mice, and MIDI devices. A core group of collaborators maintains [QMK Firmware](https://github.com/qmk/qmk_firmware), [QMK Configurator](https://config.qmk.fm), [QMK Toolbox](https://github.com/qmk/qmk_toolbox), [qmk.fm](https://qmk.fm), and this documentation with the help of community members like you. - -## Get Started - -
- -?> **Basic** [QMK Configurator](newbs_building_firmware_configurator.md)
-User friendly graphical interfaces, no programming knowledge required. - -?> **Advanced** [Use The Source](newbs.md)
-More powerful, but harder to use. - -
- -## Make It Yours - -QMK has lots of features to explore, and a good deal of reference documentation to dig through. Most features are taken advantage of by modifying your [keymap](keymap.md), and changing the [keycodes](keycodes.md). - -## Need help? - -Check out the [support page](support.md) to see how you can get help using QMK. - -## Give Back - -There are a lot of ways you can contribute to the QMK Community. The easiest way to get started is to use it and spread the word to your friends. - -* Help people out on our forums and chat rooms: - * [/r/olkb](https://www.reddit.com/r/olkb/) - * [Discord Server](https://discord.gg/Uq7gcHh) -* Contribute to our documentation by clicking "Edit This Page" at the bottom -* [Translate our documentation into your language](translating.md) -* [Report a bug](https://github.com/qmk/qmk_firmware/issues/new/choose) -* [Open a Pull Request](contributing.md) diff --git a/docs/_langs.md b/docs/_langs.md deleted file mode 100644 index 8b08c345137c..000000000000 --- a/docs/_langs.md +++ /dev/null @@ -1,4 +0,0 @@ -- Translations - - [:uk: English](/) - - [:cn: 简体中文](/zh-cn/) - - [:jp: 日本語](/ja/) diff --git a/docs/_summary.md b/docs/_summary.md deleted file mode 100644 index 8b7959c2b34f..000000000000 --- a/docs/_summary.md +++ /dev/null @@ -1,204 +0,0 @@ -* Tutorial - * [Introduction](newbs.md) - * [Setup](newbs_getting_started.md) - * [Building Your First Firmware](newbs_building_firmware.md) - * [Flashing Firmware](newbs_flashing.md) - * [Getting Help/Support](support.md) - * [Building With GitHub Userspace](newbs_building_firmware_workflow.md) - * [Other Resources](newbs_learn_more_resources.md) - * [Syllabus](syllabus.md) - -* FAQs - * [General FAQ](faq_general.md) - * [Build/Compile QMK](faq_build.md) - * [Troubleshooting QMK](faq_misc.md) - * [Debugging QMK](faq_debug.md) - * [Keymap FAQ](faq_keymap.md) - * [Squeezing Space from AVR](squeezing_avr.md) - * [Glossary](reference_glossary.md) - -* Configurator - * [Overview](newbs_building_firmware_configurator.md) - * [Step by Step](configurator_step_by_step.md) - * [Troubleshooting](configurator_troubleshooting.md) - * [Architecture](configurator_architecture.md) - * QMK API - * [Overview](api_overview.md) - * [API Documentation](api_docs.md) - * [Keyboard Support](reference_configurator_support.md) - * [Adding Default Keymaps](configurator_default_keymaps.md) - -* CLI - * [Overview](cli.md) - * [Configuration](cli_configuration.md) - * [Commands](cli_commands.md) - * [Tab Completion](cli_tab_complete.md) - -* Using QMK - * Guides - * [Customizing Functionality](custom_quantum_functions.md) - * [Driver Installation with Zadig](driver_installation_zadig.md) - * [Keymap Overview](keymap.md) - * Development Environments - * [Docker Guide](getting_started_docker.md) - * Flashing - * [Flashing](flashing.md) - * [Flashing ATmega32A (ps2avrgb)](flashing_bootloadhid.md) - * IDEs - * [Using Eclipse with QMK](other_eclipse.md) - * [Using VSCode with QMK](other_vscode.md) - * Git Best Practices - * [Introduction](newbs_git_best_practices.md) - * [Your Fork](newbs_git_using_your_master_branch.md) - * [Merge Conflicts](newbs_git_resolving_merge_conflicts.md) - * [Fixing Your Branch](newbs_git_resynchronize_a_branch.md) - - * Simple Keycodes - * [Full List](keycodes.md) - * [Basic Keycodes](keycodes_basic.md) - * [Language-Specific Keycodes](reference_keymap_extras.md) - * [Modifier Keys](feature_advanced_keycodes.md) - * [Quantum Keycodes](quantum_keycodes.md) - * [Magic Keycodes](keycodes_magic.md) - - * Advanced Keycodes - * [Command](feature_command.md) - * [Dynamic Macros](feature_dynamic_macros.md) - * [Grave Escape](feature_grave_esc.md) - * [Leader Key](feature_leader_key.md) - * [Mod-Tap](mod_tap.md) - * [Macros](feature_macros.md) - * [Mouse Keys](feature_mouse_keys.md) - * [Programmable Button](feature_programmable_button.md) - * [Repeat Key](feature_repeat_key.md) - * [Space Cadet Shift](feature_space_cadet.md) - * [US ANSI Shifted Keys](keycodes_us_ansi_shifted.md) - - * Software Features - * [Auto Shift](feature_auto_shift.md) - * [Autocorrect](feature_autocorrect.md) - * [Caps Word](feature_caps_word.md) - * [Combos](feature_combo.md) - * [Debounce API](feature_debounce_type.md) - * [EEPROM](feature_eeprom.md) - * [Key Lock](feature_key_lock.md) - * [Key Overrides](feature_key_overrides.md) - * [Layers](feature_layers.md) - * [One Shot Keys](one_shot_keys.md) - * [OS Detection](feature_os_detection.md) - * [Raw HID](feature_rawhid.md) - * [Secure](feature_secure.md) - * [Send String](feature_send_string.md) - * [Sequencer](feature_sequencer.md) - * [Swap Hands](feature_swap_hands.md) - * [Tap Dance](feature_tap_dance.md) - * [Tap-Hold Configuration](tap_hold.md) - * [Tri Layer](feature_tri_layer.md) - * [Unicode](feature_unicode.md) - * [Userspace](feature_userspace.md) - * [WPM Calculation](feature_wpm.md) - - * Hardware Features - * Displays - * [Quantum Painter](quantum_painter.md) - * [Quantum Painter LVGL Integration](quantum_painter_lvgl.md) - * [HD44780 LCD Driver](feature_hd44780.md) - * [ST7565 LCD Driver](feature_st7565.md) - * [OLED Driver](feature_oled_driver.md) - * Lighting - * [Backlight](feature_backlight.md) - * [LED Matrix](feature_led_matrix.md) - * [RGB Lighting](feature_rgblight.md) - * [RGB Matrix](feature_rgb_matrix.md) - * [Audio](feature_audio.md) - * [Bluetooth](feature_bluetooth.md) - * [Bootmagic Lite](feature_bootmagic.md) - * [Converters](feature_converters.md) - * [Custom Matrix](custom_matrix.md) - * [Digitizer](feature_digitizer.md) - * [DIP Switch](feature_dip_switch.md) - * [Encoders](feature_encoders.md) - * [Haptic Feedback](feature_haptic_feedback.md) - * [Joystick](feature_joystick.md) - * [LED Indicators](feature_led_indicators.md) - * [MIDI](feature_midi.md) - * [Pointing Device](feature_pointing_device.md) - * [PS/2 Mouse](feature_ps2_mouse.md) - * [Split Keyboard](feature_split_keyboard.md) - * [Stenography](feature_stenography.md) - * [Velocikey](feature_velocikey.md) - - * Keyboard Building - * [Easy Maker for One Offs](easy_maker.md) - * [Porting Keyboards](porting_your_keyboard_to_qmk.md) - * [Hand Wiring Guide](hand_wire.md) - * [ISP Flashing Guide](isp_flashing_guide.md) - -* Developing QMK - * [PR Checklist](pr_checklist.md) - * Breaking Changes - * [Overview](breaking_changes.md) - * [My Pull Request Was Flagged](breaking_changes_instructions.md) - * [Most Recent ChangeLog](ChangeLog/20230528.md "QMK v0.21.0 - 2023 May 28") - * [Past Breaking Changes](breaking_changes_history.md) - - * C Development - * [ARM Debugging Guide](arm_debugging.md) - * [Coding Conventions](coding_conventions_c.md) - * [Compatible Microcontrollers](compatible_microcontrollers.md) - * [Drivers](hardware_drivers.md) - * [ADC Driver](adc_driver.md) - * [Audio Driver](audio_driver.md) - * [I2C Driver](i2c_driver.md) - * [SPI Driver](spi_driver.md) - * [WS2812 Driver](ws2812_driver.md) - * [EEPROM Driver](eeprom_driver.md) - * [Flash Driver](flash_driver.md) - * ['serial' Driver](serial_driver.md) - * [UART Driver](uart_driver.md) - * [GPIO Controls](gpio_control.md) - * [Keyboard Guidelines](hardware_keyboard_guidelines.md) - - * Python Development - * [Coding Conventions](coding_conventions_python.md) - * [QMK CLI Development](cli_development.md) - - * Configurator Development - * QMK API - * [Development Environment](api_development_environment.md) - * [Architecture Overview](api_development_overview.md) - - * Hardware Platform Development - * Arm/ChibiOS - * [Selecting an MCU](platformdev_selecting_arm_mcu.md) - * [Early initialization](platformdev_chibios_earlyinit.md) - * [Raspberry Pi RP2040](platformdev_rp2040.md) - * [Proton C](platformdev_proton_c.md) - * [WeAct Blackpill F4x1](platformdev_blackpill_f4x1.md) - - * QMK Reference - * [Contributing to QMK](contributing.md) - * [Translating the QMK Docs](translating.md) - * [Config Options](config_options.md) - * [Data Driven Configuration](data_driven_config.md) - * [Make Documentation](getting_started_make_guide.md) - * [Documentation Best Practices](documentation_best_practices.md) - * [Documentation Templates](documentation_templates.md) - * [Community Layouts](feature_layouts.md) - * [Unit Testing](unit_testing.md) - * [Useful Functions](ref_functions.md) - * [info.json Format](reference_info_json.md) - - * For a Deeper Understanding - * [How Keyboards Work](how_keyboards_work.md) - * [How a Matrix Works](how_a_matrix_works.md) - * [Understanding QMK](understanding_qmk.md) - - * QMK Internals (In Progress) - * [Defines](internals/defines.md) - * [Input Callback Reg](internals/input_callback_reg.md) - * [Midi Device](internals/midi_device.md) - * [Midi Device Setup Process](internals/midi_device_setup_process.md) - * [Midi Util](internals/midi_util.md) - * [Send Functions](internals/send_functions.md) - * [Sysex Tools](internals/sysex_tools.md) diff --git a/docs/adc_driver.md b/docs/adc_driver.md deleted file mode 100644 index 494d90c94fa8..000000000000 --- a/docs/adc_driver.md +++ /dev/null @@ -1,173 +0,0 @@ -# ADC Driver - -QMK can leverage the Analog-to-Digital Converter (ADC) on supported MCUs to measure voltages on certain pins. This can be useful for implementing things such as battery level indicators for Bluetooth keyboards, or volume controls using a potentiometer, as opposed to a [rotary encoder](feature_encoders.md). - -This driver currently supports both AVR and a limited selection of ARM devices. The values returned are 10-bit integers (0-1023) mapped between 0V and VCC (usually 5V or 3.3V for AVR, 3.3V only for ARM), however on ARM there is more flexibility in control of operation through `#define`s if you need more precision. - -## Usage - -To use this driver, add the following to your `rules.mk`: - -```make -SRC += analog.c -``` - -Then place this include at the top of your code: - -```c -#include "analog.h" -``` - -## Channels - -### AVR - -|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P| -|-------|-------------|-------------|---------|----------| -|0 |`F0` |`F0` |`A0` |`C0` | -|1 |`F1` |`F1` |`A1` |`C1` | -|2 |`F2` | |`A2` |`C2` | -|3 |`F3` | |`A3` |`C3` | -|4 |`F4` |`F4` |`A4` |`C4` | -|5 |`F5` |`F5` |`A5` |`C5` | -|6 |`F6` |`F6` |`A6` |* | -|7 |`F7` |`F7` |`A7` |* | -|8 | |`D4` | | | -|9 | |`D6` | | | -|10 | |`D7` | | | -|11 | |`B4` | | | -|12 | |`B5` | | | -|13 | |`B6` | | | - -\* The ATmega328/P possesses two extra ADC channels; however, they are not present on the DIP pinout, and are not shared with GPIO pins. You can use `adc_read()` directly to gain access to these. - -### ARM - -#### STM32 - -Note that some of these pins are doubled-up on ADCs with the same channel. This is because the pins can be used for either ADC. - -Also note that the F0 and F3 use different numbering schemes. The F0 has a single ADC and the channels are 0-indexed, whereas the F3 has 4 ADCs and the channels are 1-indexed. This is because the F0 uses the `ADCv1` implementation of the ADC, whereas the F3 uses the `ADCv3` implementation. - -|ADC|Channel|STM32F0xx|STM32F1xx|STM32F3xx|STM32F4xx| -|---|-------|---------|---------|---------|---------| -|1 |0 |`A0` |`A0` | |`A0` | -|1 |1 |`A1` |`A1` |`A0` |`A1` | -|1 |2 |`A2` |`A2` |`A1` |`A2` | -|1 |3 |`A3` |`A3` |`A2` |`A3` | -|1 |4 |`A4` |`A4` |`A3` |`A4` | -|1 |5 |`A5` |`A5` |`F4` |`A5` | -|1 |6 |`A6` |`A6` |`C0` |`A6` | -|1 |7 |`A7` |`A7` |`C1` |`A7` | -|1 |8 |`B0` |`B0` |`C2` |`B0` | -|1 |9 |`B1` |`B1` |`C3` |`B1` | -|1 |10 |`C0` |`C0` |`F2` |`C0` | -|1 |11 |`C1` |`C1` | |`C1` | -|1 |12 |`C2` |`C2` | |`C2` | -|1 |13 |`C3` |`C3` | |`C3` | -|1 |14 |`C4` |`C4` | |`C4` | -|1 |15 |`C5` |`C5` | |`C5` | -|1 |16 | | | | | -|2 |0 | |`A0`¹ | |`A0`² | -|2 |1 | |`A1`¹ |`A4` |`A1`² | -|2 |2 | |`A2`¹ |`A5` |`A2`² | -|2 |3 | |`A3`¹ |`A6` |`A3`² | -|2 |4 | |`A4`¹ |`A7` |`A4`² | -|2 |5 | |`A5`¹ |`C4` |`A5`² | -|2 |6 | |`A6`¹ |`C0` |`A6`² | -|2 |7 | |`A7`¹ |`C1` |`A7`² | -|2 |8 | |`B0`¹ |`C2` |`B0`² | -|2 |9 | |`B1`¹ |`C3` |`B1`² | -|2 |10 | |`C0`¹ |`F2` |`C0`² | -|2 |11 | |`C1`¹ |`C5` |`C1`² | -|2 |12 | |`C2`¹ |`B2` |`C2`² | -|2 |13 | |`C3`¹ | |`C3`² | -|2 |14 | |`C4`¹ | |`C4`² | -|2 |15 | |`C5`¹ | |`C5`² | -|2 |16 | | | | | -|3 |0 | |`A0`¹ | |`A0`² | -|3 |1 | |`A1`¹ |`B1` |`A1`² | -|3 |2 | |`A2`¹ |`E9` |`A2`² | -|3 |3 | |`A3`¹ |`E13` |`A3`² | -|3 |4 | |`F6`¹ | |`F6`² | -|3 |5 | |`F7`¹ |`B13` |`F7`² | -|3 |6 | |`F8`¹ |`E8` |`F8`² | -|3 |7 | |`F9`¹ |`D10` |`F9`² | -|3 |8 | |`F10`¹ |`D11` |`F10`² | -|3 |9 | | |`D12` |`F3`² | -|3 |10 | |`C0`¹ |`D13` |`C0`² | -|3 |11 | |`C1`¹ |`D14` |`C1`² | -|3 |12 | |`C2`¹ |`B0` |`C2`² | -|3 |13 | |`C3`¹ |`E7` |`C3`² | -|3 |14 | | |`E10` |`F4`² | -|3 |15 | | |`E11` |`F5`² | -|3 |16 | | |`E12` | | -|4 |1 | | |`E14` | | -|4 |2 | | |`E15` | | -|4 |3 | | |`B12` | | -|4 |4 | | |`B14` | | -|4 |5 | | |`B15` | | -|4 |6 | | |`E8` | | -|4 |7 | | |`D10` | | -|4 |8 | | |`D11` | | -|4 |9 | | |`D12` | | -|4 |10 | | |`D13` | | -|4 |11 | | |`D14` | | -|4 |12 | | |`D8` | | -|4 |13 | | |`D9` | | -|4 |14 | | | | | -|4 |15 | | | | | -|4 |16 | | | | | - -¹ As of ChibiOS 20.3.4, the ADC driver for STM32F1xx devices supports only ADC1, therefore any configurations involving ADC2 or ADC3 cannot actually be used. In particular, pins `F6`…`F10`, which are present at least on some STM32F103x[C-G] devices, cannot be used as ADC inputs because of this driver limitation. - -² Not all STM32F4xx devices have ADC2 and/or ADC3, therefore some configurations shown in this table may be unavailable; in particular, pins `F4`…`F10` cannot be used as ADC inputs on devices which do not have ADC3. Check the device datasheet to confirm which pin functions are supported. - -#### RP2040 - -RP2040 has only a single ADC (`ADCD1` in ChibiOS); in the QMK API the index for that ADC is 0. - -|Channel|Pin | -|-------|-------------------| -|0 |`GP26` | -|1 |`GP27` | -|2 |`GP28` | -|3 |`GP29` | -|4 |Temperature sensor*| - - -* The temperature sensor is disabled by default and needs to be enabled by the RP2040-specific function: `adcRPEnableTS(&ADCD1)`. The ADC must be initialized before calling that function; an easy way to ensure that is to perform a dummy conversion. - -## Functions - -### AVR - -|Function |Description | -|----------------------------|-------------------------------------------------------------------------------------------------------------------| -|`analogReference(mode)` |Sets the analog voltage reference source. Must be one of `ADC_REF_EXTERNAL`, `ADC_REF_POWER` or `ADC_REF_INTERNAL`.| -|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `F6` for ADC6 on the ATmega32U4. | -|`pinToMux(pin)` |Translates a given pin to a mux value. If an unsupported pin is given, returns the mux value for "0V (GND)". | -|`adc_read(mux)` |Reads the value from the ADC according to the specified mux. See your MCU's datasheet for more information. | - -### ARM - -|Function |Description | -|----------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|`analogReadPin(pin)` |Reads the value from the specified pin, eg. `A0` for channel 0 on the STM32F0 and ADC1 channel 1 on the STM32F3. Note that if a pin can be used for multiple ADCs, it will pick the lower numbered ADC for this function. eg. `C0` will be channel 6 of ADC 1 when it could be used for ADC 2 as well.| -|`analogReadPinAdc(pin, adc)`|Reads the value from the specified pin and ADC, eg. `C0, 1` will read from channel 6, ADC 2 instead of ADC 1. Note that the ADCs are 0-indexed for this function. | -|`pinToMux(pin)` |Translates a given pin to a channel and ADC combination. If an unsupported pin is given, returns the mux value for "0V (GND)". | -|`adc_read(mux)` |Reads the value from the ADC according to the specified pin and ADC combination. See your MCU's datasheet for more information. | - -## Configuration - -## ARM - -The ARM implementation of the ADC has a few additional options that you can override in your own keyboards and keymaps to change how it operates. Please consult the corresponding `hal_adc_lld.h` in ChibiOS for your specific microcontroller for further documentation on your available options. - -|`#define` |Type |Default |Description | -|---------------------|------|----------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |If `true`, then the implementation will use a circular buffer. | -|`ADC_NUM_CHANNELS` |`int` |`1` |Sets the number of channels that will be scanned as part of an ADC operation. The current implementation only supports `1`. | -|`ADC_BUFFER_DEPTH` |`int` |`2` |Sets the depth of each result. Since we are only getting a 10-bit result by default, we set this to 2 bytes so we can contain our one value. This could be set to 1 if you opt for an 8-bit or lower result.| -|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |Sets the sampling rate of the ADC. By default, it is set to the fastest setting. | -|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_10BIT` or `ADC_CFGR_RES_10BITS`|The resolution of your result. We choose 10 bit by default, but you can opt for 12, 10, 8, or 6 bit. Different MCUs use slightly different names for the resolution constants. | diff --git a/docs/api_development_environment.md b/docs/api_development_environment.md deleted file mode 100644 index 50647c429951..000000000000 --- a/docs/api_development_environment.md +++ /dev/null @@ -1,3 +0,0 @@ -# Development Environment Setup - -To setup a development stack head over to the [qmk_web_stack](https://github.com/qmk/qmk_web_stack). diff --git a/docs/api_development_overview.md b/docs/api_development_overview.md deleted file mode 100644 index e55d0341006b..000000000000 --- a/docs/api_development_overview.md +++ /dev/null @@ -1,44 +0,0 @@ -# QMK Compiler Development Guide - -This page attempts to introduce developers to the QMK Compiler. It does not go into nitty gritty details- for that you should read code. What this will give you is a framework to hang your understanding on as you read the code. - -# Overview - -The QMK Compile API consists of a few movings parts: - -![Architecture Diagram](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg) - -API Clients interact exclusively with the API service. This is where they submit jobs, check status, and download results. The API service inserts compile jobs into [Redis Queue](https://python-rq.org) and checks both RQ and S3 for the results of those jobs. - -Workers fetch new compile jobs from RQ, compile them, and then upload the source and the binary to an S3 compatible storage engine. - -# Workers - -QMK Compiler Workers are responsible for doing the actual building. When a worker pulls a job from RQ it does several things to complete that job: - -* Make a fresh qmk_firmware checkout -* Use the supplied layers and keyboard metadata to build a `keymap.c` -* Build the firmware -* Zip a copy of the source -* Upload the firmware, source zip, and a metadata file to S3. -* Report the status of the job to RQ - -# API Service - -The API service is a relatively simple Flask application. There are a few main views you should understand. - -## @app.route('/v1/compile', methods=['POST']) - -This is the main entrypoint for the API. A client's interaction starts here. The client POST's a JSON document describing their keyboard, and the API does some (very) basic validation of that JSON before submitting the compile job. - -## @app.route('/v1/compile/<string:job_id>', methods=['GET']) - -This is the most frequently called endpoint. It pulls the job details from redis, if they're still available, or the cached job details on S3 if they're not. - -## @app.route('/v1/compile/<string:job_id>/download', methods=['GET']) - -This method allows users to download the compiled firmware file. - -## @app.route('/v1/compile/<string:job_id>/source', methods=['GET']) - -This method allows users to download the source for their firmware. diff --git a/docs/api_docs.md b/docs/api_docs.md deleted file mode 100644 index 3324bc545bca..000000000000 --- a/docs/api_docs.md +++ /dev/null @@ -1,106 +0,0 @@ -# QMK API - -This page describes using the QMK API. If you are an application developer you can use this API to compile firmware for any [QMK](https://qmk.fm) Keyboard. - -## Overview - -This service is an asynchronous API for compiling custom keymaps. You POST some JSON to the API, periodically check the status, and when your firmware has finished compiling you can download the resulting firmware and (if desired) source code for that firmware. - -#### Example JSON Payload: - -```json -{ - "keyboard": "clueboard/66/rev2", - "keymap": "my_awesome_keymap", - "layout": "LAYOUT_all", - "layers": [ - ["KC_GRV","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_GRV","KC_BSPC","KC_PGUP","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_PGDN","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_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_INT1","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_INT5","KC_SPC","KC_SPC","KC_INT4","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"], - ["KC_ESC","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_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SCRL","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"], - ["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","QK_BOOT","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"] - ] -} -``` - -As you can see the payload describes all aspects of a keyboard necessary to create and generate a firmware. Each layer is a single list of QMK keycodes the same length as the keyboard's `LAYOUT` macro. If a keyboard supports multiple `LAYOUT` macros you can specify which macro to use. - -## Submitting a Compile Job - -To compile your keymap into a firmware simply POST your JSON to the `/v1/compile` endpoint. In the following example we've placed the JSON payload into a file named `json_data`. - -``` -$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" https://api.qmk.fm/v1/compile -{ - "enqueued": true, - "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6" -} -``` - -## Checking The Status - -After submitting your keymap you can check the status using a simple HTTP GET call: - -``` -$ curl https://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6 -{ - "created_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "id": "f5f9b992-73b4-479b-8236-df1deb37c163", - "status": "running", - "result": null -} -``` - -This shows us that the job has made it through the queue and is currently running. There are 5 possible statuses: - -* **failed**: Something about the compiling service has broken. -* **finished**: The compilation is complete and you should check `result` to see the results. -* **queued**: The keymap is waiting for a compilation server to become available. -* **running**: The compilation is in progress and should be complete soon. -* **unknown**: A serious error has occurred and you should [file a bug](https://github.com/qmk/qmk_compiler/issues). - -## Examining Finished Results - -Once your compile job has finished you'll check the `result` key. The value of this key is a hash containing several key bits of information: - -* `firmware_binary_url`: A list of URLs for the flashable firmware -* `firmware_keymap_url`: A list of URLs for the `keymap.c` -* `firmware_source_url`: A list of URLs for the full firmware source code -* `output`: The stdout and stderr for this compile job. Errors will be found here. - -## Constants :id=qmk-constants - -If you're writing a tool that leverages constants used within QMK, the API is used to publish "locked-in" versions of those constants in order to ensure that any third-party tooling has a canonical set of information to work with. - -The list of available constants can be retrieved by accessing one of the following endpoints: - -``` -$ curl https://keyboards.qmk.fm/v1/constants_metadata.json # For `master` -{"last_updated": "2022-11-26 00:00:00 GMT", "constants": {"keycodes": ["0.0.1"]}} - -$ curl https://keyboards.develop.qmk.fm/v1/constants_metadata.json # For `develop` -{"last_updated": "2022-11-26 12:00:00 GMT", "constants": {"keycodes": ["0.0.1", "0.0.2"]}} -``` - -!> Versions exported by the `master` endpoint are locked-in. Any extra versions that exist on the `develop` endpoint which don't exist in `master` are subject to change. - -?> Only keycodes are currently published, but over time all other "externally visible" IDs are expected to appear on these endpoints. - -To retrieve the constants associated with a subsystem, the endpoint format is as follows: -``` -# https://keyboards.qmk.fm/v1/constants/{subsystem}_{version}.json -``` -Which, for the metadata endpoint above results in a request of: -``` -$ curl https://keyboards.qmk.fm/v1/constants/keycodes_0.0.1.json -{ - "ranges": { - "0x0000/0x00FF": { - "define": "QK_BASIC" - }, - "0x0100/0x1EFF": { - "define": "QK_MODS" - }, - "0x2000/0x1FFF": { - "define": "QK_MOD_TAP" - -``` diff --git a/docs/api_overview.md b/docs/api_overview.md deleted file mode 100644 index f851a48a4af4..000000000000 --- a/docs/api_overview.md +++ /dev/null @@ -1,15 +0,0 @@ -# QMK API - -The QMK API provides an asynchronous API that Web and GUI tools can use to compile arbitrary keymaps for any keyboard supported by [QMK](https://qmk.fm/). The stock keymap template supports all QMK keycodes that do not require supporting C code. Keyboard maintainers can supply their own custom templates to enable more functionality. - -## App Developers - -If you are an app developer interested in using this API in your application you should head over to [Using The API](api_docs.md). - -## Keyboard Maintainers - -If you would like to enhance your keyboard's support in the QMK Compiler API head over to the [Keyboard Support](reference_configurator_support.md) section. - -## Backend Developers - -If you are interested in working on the API itself you should start by setting up a [Development Environment](api_development_environment.md), then check out [Hacking On The API](api_development_overview.md). diff --git a/docs/arm_debugging.md b/docs/arm_debugging.md deleted file mode 100644 index 04887d88b7c4..000000000000 --- a/docs/arm_debugging.md +++ /dev/null @@ -1,87 +0,0 @@ -# ARM Debugging using Eclipse - -This page describes how to setup debugging for ARM MCUs using an SWD adapter and open-source/free tools. In this guide we will install GNU MCU Eclipse IDE for C/C++ Developers and OpenOCD together with all the necessary dependencies. - -This guide is catered towards advance users and assumes you can compile an ARM compatible keyboard on your machine using the MAKE flow. - -## Installing the software - -The main objective here is to get the MCU Eclipse IDE correctly installed on our machine. The necessary instructions are derived from [this](https://gnu-mcu-eclipse.github.io/install/) install guide. - -### The xPack Manager - -This tool is a software package manager and it is used to help us get the necessary dependencies. - -XPM runs using Node.js so grab that from [here](https://nodejs.org/en/). After installation, open a terminal and type `npm -v`. A reply with the version number means that the installation was successful. - -XPM installation instructions can be found [here](https://www.npmjs.com/package/xpm) and are OS specific. Entering `xpm --version` to your terminal should return the software version. - -### The ARM Toolchain - -Using XPM it is very easy to install the ARM toolchain. Enter the command `xpm install --global @xpack-dev-tools/arm-none-eabi-gcc`. - -### Windows build tools - -If you are using windows you need to install this! - -`xpm install --global @gnu-mcu-eclipse/windows-build-tools` - -### Programmer/Debugger Drivers - -Now it's time to install your programmer's drivers. This tutorial was made using an ST-Link v2 which you can get from almost anywhere. -If you have an ST-Link the drivers can be found [here](https://www.st.com/en/development-tools/stsw-link009.html) otherwise consult the manufacturer of your tool. - -### OpenOCD - -This dependency allows SWD access from GDB and it is essential for debugging. Run `xpm install --global @xpack-dev-tools/openocd`. - -### Java - -Java is needed by Eclipse so please download it from [here](https://www.oracle.com/technetwork/java/javase/downloads/index.html). - -### GNU MCU Eclipse IDE - -Now its finally time to install the IDE. Use the Release page [here](https://github.com/gnu-mcu-eclipse/org.eclipse.epp.packages/releases/) to get the latest version. - -## Configuring Eclipse - -Open up the Eclipse IDE we just downloaded. To import our QMK directory select File -> Import -> C/C++ -> Existing Code as Makefile Project. Select Next and use Browse to select your QMK folder. In the tool-chain list select ARM Cross GCC and select Finish. - -Now you can see the QMK folder on the left hand side. Right click it and select Properties. On the left hand side, expand MCU and select ARM Toolchains Paths. Press xPack and OK. Repeat for OpenOCD Path and if you are on Windows for Build Tools Path. Select Apply and Close. - -Now its time to install the necessary MCU packages. Go to Packs perspective by selecting Window -> Perspective -> Open Perspective -> Other... -> Packs. Now select the yellow refresh symbol next to the Packs tab. This will take a long time as it is requesting the MCU definitions from various places. If some of the links fail you can probably select Ignore. - -When this finishes you must find the MCU which we will be building/debugging for. In this example I will be using the STM32F3 series MCUs. On the left, select STMicroelectronics -> STM32F3 Series. On the middle window we can see the pack. Right click and select Install. Once that is done we can go back to the default perspective, Window -> Perspective -> Open Perspective -> Other... -> C/C++. - -We need to let eclipse know the device we intent to build QMK on. Right click on the QMK folder -> Properties -> C/C++ Build -> Settings. Select the Devices tab and under Devices select the appropriate variant of your MCU. For my example it is STM32F303CC - -While we are here let's setup the build command as well. Select C/C++ Build and then the Behavior tab. On the Build command, replace `all` with your necessary make command. For example for a rev6 Planck with the default keymap this would be `planck/rev6:default`. Select Apply and Close. - -## Building - -If you have setup everything correctly pressing the hammer button should build the firmware for you and a .bin file should appear. - -## Debugging - -### Connecting the Debugger - -ARM MCUs use the Single Wire Debug (SWD) protocol which comprises of the clock (SWCLK) signal and the data (SWDIO) signal. Connecting this two wires and ground should be enough to allow full manipulation of the MCU. Here we assume that the keyboard will be powered though USB. The RESET signal is not necessary as we can manually assert it using the reset button. For a more advance setup, the SWO signal can be used which pipes printf and scanf asynchronously to the host but for our setup we will ignore it. - -NOTE: Make sure the SWCLK and SWDIO pins are not used in the matrix of your keyboard. If they are you can temporarily switch them for some other pins. - -### Configuring the Debugger - -Right click on your QMK folder, select Debug As -> Debug Configurations... . Here double click on GDB OpenOCD Debugging. Select the Debugger tab and enter the configuration necessary for your MCU. This might take some fiddling and Googling to find out. The default script for the STM32F3 is called `stm32f3discovery.cfg`. To let OpenOCD know, in the Config options enter `-f board/stm32f3discovery.cfg`. - -NOTE: In my case this configuration script requires editing to disable the reset assertion. The locations of the scripts can be found in the actual executable field usually under the path `openocd/version/.content/scripts/board`. Here I edited `reset_config srst_only` to `reset_config none`. - -Select Apply and Close. - -### Running the Debugger. - -Reset your keyboard. - -Press the bug icon and if all goes well you should soon find yourself in the Debug perspective. Here the program counter will pause at the beginning of the main function and wait for you to press Play. Most of the features of all debuggers work on Arm MCUs but for exact details Google is your friend! - - -Happy debugging! diff --git a/docs/audio_driver.md b/docs/audio_driver.md deleted file mode 100644 index a0bbb22e1962..000000000000 --- a/docs/audio_driver.md +++ /dev/null @@ -1,219 +0,0 @@ -# Audio Driver :id=audio-driver - -The [Audio feature](feature_audio.md) breaks the hardware specifics out into separate, exchangeable driver units, with a common interface to the audio-"core" - which itself handles playing songs and notes while tracking their progress in an internal state, initializing/starting/stopping the driver as needed. - -Not all MCUs support every available driver, either the platform-support is not there (yet?) or the MCU simply does not have the required hardware peripheral. - - -## AVR :id=avr - -Boards built around an Atmega32U4 can use two sets of PWM capable pins, each driving a separate speaker. -The possible configurations are: - -| | Timer3 | Timer1 | -|--------------|-------------|--------------| -| one speaker | C4,C5 or C6 | | -| one speaker | | B4, B5 or B7 | -| two speakers | C4,C5 or C6 | B4, B5 or B7 | - -Currently there is only one/default driver for AVR based boards, which is automatically configured to: - -```make -AUDIO_DRIVER = pwm_hardware -``` - - -## ARM :id=arm - -For Arm based boards, QMK depends on ChibiOS - hence any MCU supported by the later is likely usable, as long as certain hardware peripherals are available. - -Supported wiring configurations, with their ChibiOS/MCU peripheral requirement are listed below; -piezo speakers are marked with :one: for the first/primary and :two: for the secondary. - - | driver | GPTD6
Tim6 | GPTD7
Tim7 | GPTD8
Tim8 | PWMD11
Tim1_Ch1 | - |--------------|------------------------------------------|------------------------|---------------|-------------------------------| - | dac_basic | A4+DACD1 = :one: | A5+DACD2 = :one: | state | | - | | A4+DACD1 = :one: + Gnd | A5+DACD2 = :two: + Gnd | state | | - | | A4+DACD1 = :two: + Gnd | A5+DACD2 = :one: + Gnd | state | | - | | A4+DACD1 = :one: + Gnd | | state | | - | | | A5+DACD2 = :one: + Gnd | state | | - | dac_additive | A4+DACD1 = :one: + Gnd | | | | - | | A5+DACD2 = :one: + Gnd | | | | - | | A4+DACD1 + A5+DACD2 = :one: 2 | | | | - | pwm_software | state-update | | | any = :one: | - | pwm hardware | state-update | | | A8 = :one: 3 | - - -1: the routing and alternate functions for PWM differ sometimes between STM32 MCUs, if in doubt consult the data-sheet -2: one piezo connected to A4 and A5, with AUDIO_PIN_ALT_AS_NEGATIVE set -3: TIM1_CH1 = A8 on STM32F103C8, other combinations are possible, see Data-sheet. configured with: AUDIO_PWM_DRIVER and AUDIO_PWM_CHANNEL - - - -### DAC basic :id=dac-basic - -The default driver for ARM boards, in absence of an overriding configuration. -This driver needs one Timer per enabled/used DAC channel, to trigger conversion; and a third timer to trigger state updates with the audio-core. - -Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timers 6, 7 and 8: - -```c -//halconf.h: -#define HAL_USE_DAC TRUE -#define HAL_USE_GPT TRUE -#include_next -``` - -```c -// mcuconf.h: -#include_next -#undef STM32_DAC_USE_DAC1_CH1 -#define STM32_DAC_USE_DAC1_CH1 TRUE -#undef STM32_DAC_USE_DAC1_CH2 -#define STM32_DAC_USE_DAC1_CH2 TRUE -#undef STM32_GPT_USE_TIM6 -#define STM32_GPT_USE_TIM6 TRUE -#undef STM32_GPT_USE_TIM7 -#define STM32_GPT_USE_TIM7 TRUE -#undef STM32_GPT_USE_TIM8 -#define STM32_GPT_USE_TIM8 TRUE -``` - -?> Note: DAC1 (A4) uses TIM6, DAC2 (A5) uses TIM7, and the audio state timer uses TIM8 (configurable). - -You can also change the timer used for the overall audio state by defining the driver. For instance: - -```c -#define AUDIO_STATE_TIMER GPTD9 -``` - -### DAC additive :id=dac-additive - -only needs one timer (GPTD6, Tim6) to trigger the DAC unit to do a conversion; the audio state updates are in turn triggered during the DAC callback. - -Additionally, in the board config, you'll want to make changes to enable the DACs, GPT for Timer 6: - -```c -//halconf.h: -#define HAL_USE_DAC TRUE -#define HAL_USE_GPT TRUE -#include_next -``` - -```c -// mcuconf.h: -#include_next -#undef STM32_DAC_USE_DAC1_CH1 -#define STM32_DAC_USE_DAC1_CH1 TRUE -#undef STM32_DAC_USE_DAC1_CH2 -#define STM32_DAC_USE_DAC1_CH2 TRUE -#undef STM32_GPT_USE_TIM6 -#define STM32_GPT_USE_TIM6 TRUE -``` - -### DAC Config - -| Define | Defaults | Description | -| -------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `AUDIO_DAC_SAMPLE_MAX` | `4095U` | Highest value allowed. Lower value means lower volume. And 4095U is the upper limit, since this is limited to a 12 bit value. Only effects non-pregenerated samples. | -| `AUDIO_DAC_OFF_VALUE` | `AUDIO_DAC_SAMPLE_MAX / 2` | The value of the DAC when notplaying anything. Some setups may require a high (`AUDIO_DAC_SAMPLE_MAX`) or low (`0`) value here. | -| `AUDIO_MAX_SIMULTANEOUS_TONES` | __see next table__ | The number of tones that can be played simultaneously. A value that is too high may freeze the controller or glitch out when too many tones are being played. | -| `AUDIO_DAC_SAMPLE_RATE` | __see next table__ | Effective bit rate of the DAC (in hertz), higher limits simultaneous tones, and lower sacrifices quality. | - -There are a number of predefined quality settings that you can use, with "sane minimum" being the default. You can use custom values by simply defining the sample rate and number of simultaneous tones, instead of using one of the listed presets. - -| Define | Sample Rate | Simultaneous tones | -| --------------------------------- | ----------- | ------------------- | -| `AUDIO_DAC_QUALITY_VERY_LOW` | `11025U` | `8` | -| `AUDIO_DAC_QUALITY_LOW` | `22040U` | `4` | -| `AUDIO_DAC_QUALITY_HIGH` | `44100U` | `2` | -| `AUDIO_DAC_QUALITY_VERY_HIGH` | `88200U` | `1` | -| `AUDIO_DAC_QUALITY_SANE_MINIMUM` | `16384U` | `8` | - - -```c - /* zero crossing (or approach, whereas zero == DAC_OFF_VALUE, which can be configured to anything from 0 to DAC_SAMPLE_MAX) - * ============================*=*========================== AUDIO_DAC_SAMPLE_MAX - * * * - * * * - * --------------------------------------------------------- - * * * } AUDIO_DAC_SAMPLE_MAX/100 - * --------------------------------------------------------- AUDIO_DAC_OFF_VALUE - * * * } AUDIO_DAC_SAMPLE_MAX/100 - * --------------------------------------------------------- - * * - * * * - * * * - * =====*=*================================================= 0x0 - */ -``` - - -### PWM hardware :id=pwm-hardware - -This driver uses the ChibiOS-PWM system to produce a square-wave on specific output pins that are connected to the PWM hardware. -The hardware directly toggles the pin via its alternate function. See your MCU's data-sheet for which pin can be driven by what timer - looking for TIMx_CHy and the corresponding alternate function. - -A configuration example for the STM32F103C8 would be: -```c -//halconf.h: -#define HAL_USE_PWM TRUE -#define HAL_USE_PAL TRUE -#include_next -``` - -```c -// mcuconf.h: -#include_next -#undef STM32_PWM_USE_TIM1 -#define STM32_PWM_USE_TIM1 TRUE -``` - -If we now target pin A8, looking through the data-sheet of the STM32F103C8, for the timers and alternate functions -- TIM1_CH1 = PA8 <- alternate0 -- TIM1_CH2 = PA9 -- TIM1_CH3 = PA10 -- TIM1_CH4 = PA11 - -with all this information, the configuration would contain these lines: -```c -//config.h: -#define AUDIO_PIN A8 -#define AUDIO_PWM_DRIVER PWMD1 -#define AUDIO_PWM_CHANNEL 1 -``` - -ChibiOS uses GPIOv1 for the F103, which only knows of one alternate function. -On 'larger' STM32s, GPIOv2 or GPIOv3 are used; with them it is also necessary to configure `AUDIO_PWM_PAL_MODE` to the correct alternate function for the selected pin, timer and timer-channel. - - -### PWM software :id=pwm-software - -This driver uses the PWM callbacks from PWMD1 with TIM1_CH1 to toggle the selected AUDIO_PIN in software. -During the same callback, with AUDIO_PIN_ALT_AS_NEGATIVE set, the AUDIO_PIN_ALT is toggled inversely to AUDIO_PIN. This is useful for setups that drive a piezo from two pins (instead of one and Gnd). - -You can also change the timer used for software PWM by defining the driver. For instance: - -```c -#define AUDIO_STATE_TIMER GPTD8 -``` - - -### Testing Notes :id=testing-notes - -While not an exhaustive list, the following table provides the scenarios that have been partially validated: - -| | DAC basic | DAC additive | PWM hardware | PWM software | -| ------------------------ | ------------------ | ------------------ | ------------------ | ------------------ | -| Atmega32U4 | :o: | :o: | :heavy_check_mark: | :o: | -| RP2040 | :x: | :x: | :heavy_check_mark: | ? | -| STM32F103C8 (bluepill) | :x: | :x: | :heavy_check_mark: | :heavy_check_mark: | -| STM32F303CCT6 (proton-c) | :heavy_check_mark: | :heavy_check_mark: | ? | :heavy_check_mark: | -| STM32F405VG | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: | -| L0xx | :x: (no Tim8) | ? | ? | ? | - -:heavy_check_mark: : works and was tested -:o: : does not apply -:x: : not supported by MCU - -*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* diff --git a/docs/breaking_changes.md b/docs/breaking_changes.md deleted file mode 100644 index f4560b746f7c..000000000000 --- a/docs/breaking_changes.md +++ /dev/null @@ -1,180 +0,0 @@ -# Breaking Changes - -This document describes QMK's Breaking Change process. A Breaking Change is any change which modifies how QMK behaves in a way that in incompatible or potentially dangerous. We limit these changes so that users can have confidence that updating their QMK tree will not break their keymaps. - -This also includes any keyboard moves within the repository. - -The breaking change period is when we will merge PRs that change QMK in dangerous or unexpected ways. There is a built-in period of testing so we are confident that any problems caused are rare or unable to be predicted. - -Practically, this means QMK merges the `develop` branch into the `master` branch on a 3-month cadence. - -## What has been included in past Breaking Changes? - -* [2023 May 28](ChangeLog/20230528.md) -* [2023 Feb 26](ChangeLog/20230226.md) -* [2022 Nov 26](ChangeLog/20221126.md) -* [Older Breaking Changes](breaking_changes_history.md) - -## When is the next Breaking Change? - -The next Breaking Change is scheduled for August 27, 2023. - -### Important Dates - -* 2023 May 28 - `develop` is tagged with a new release version. Each push to `master` is subsequently merged to `develop` by GitHub actions. -* 2023 Jul 30 - `develop` closed to new PRs. -* 2023 Jul 30 - Call for testers. -* 2023 Aug 13 - Last day for merges -- after this point `develop` is locked for testing and accepts only bugfixes -* 2023 Aug 20 - `develop` is locked, only critical bugfix PRs merged. -* 2023 Aug 25 - `master` is locked, no PRs merged. -* 2023 Aug 27 - Merge `develop` to `master`. -* 2023 Aug 27 - `master` is unlocked. PRs can be merged again. - -## What changes will be included? - -To see a list of breaking changes merge candidates you can look at the [`core` label](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Acore+is%3Apr). This label is applied whenever a PR is raised or changed, but only if the PR includes changes to core areas of QMK Firmware. A PR with that label applied is not guaranteed to be merged in the current cycle. New changes might be added between now and when `develop` is closed, and it is generally the responsibility of the submitter to handle conflicts. There is also another label used by QMK Collaborators -- `breaking_change_YYYYqN` -- which signifies to maintainers that it is a strong candidate for inclusion, and should be prioritized for review. - -If you want your breaking change to be included in this round you need to create a PR and have it accepted by QMK Collaborators before `develop` closes. After `develop` closes, new submissions will be deferred to the next breaking changes cycle. - -The simpler your PR is, the easier it is for maintainers to review, thus a higher likelihood of a faster merge. Large PRs tend to require a lot of attention, refactoring, and back-and-forth with subsequent reviews -- with other PRs getting merged in the meantime larger unmerged PRs are far more likely to be susceptible to conflicts. - -Criteria for acceptance: - -* The PR is complete and ready to merge -* GitHub checks for the PR are green whenever possible - * A "red" check may be disregarded by maintainers if the items flagged are unrelated to the change proposed in the PR - * Modifications to existing files should not need to add license headers to pass lint, for instance. - * If it's not directly related to your PR's functionality, prefer avoiding making a change. - -Strongly suggested: - -* The PR has a ChangeLog file describing the changes under `/docs/Changelog/20230827`. - * This should be in Markdown format, with a name in the format `PR12345.md`, substituting the digits for your PRs ID. - * One strong recommendation that the ChangeLog document matches the PR description on GitHub, so as to ensure traceability. - -## Checklists - -This section documents various processes we use when running the Breaking Changes process. - -### 4 Weeks Before Merge - -* `develop` is now closed to new PRs, only fixes for current PRs may be merged -* Post call for testers: message `@Breaking Changes Updates` on `#qmk_firmware` in Discord: - * `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be raised against qmk_firmware for this breaking changes cycle is today.` - -### 2 Weeks Before Merge - -* `develop` is now closed to existing PR merges, only bugfixes for previous merges may be included -* Post call for testers: message `@Breaking Changes Updates` on `#qmk_firmware` in Discord. - * `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.` - -### 1 Week Before Merge - -* `develop` is now closed to PR merges, only critical bugfixes may be included -* Announce that master will be closed from <2 Days Before> to -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord: - * `@Breaking Changes Updates -- Hey folks, last day for functional PRs to be merged into qmk_firmware for this breaking changes cycle is today. After that, we're handling bugfixes only.` - -### 2 Days Before Merge - -* `master` is now closed to PR merges -* Announce that master is closed for 2 days - * `@Breaking Changes Updates -- Hey folks, the master branch of qmk_firmware is now locked for the next couple of days while we prepare to merge the newest batch of changes from develop.` - -### Day Of Merge - -* `qmk_firmware` git commands - * `git checkout develop` - * `git pull --ff-only` - * Edit `readme.md` - * Remove the notes about `develop` - * Roll up the ChangeLog into one file. - * `git commit -m 'Merge point for Breaking Change'` - * `git push upstream develop` -* GitHub Actions - * Create a PR for `develop` - * **Turn off 'Automatically delete head branches' for the repository** -- confirm with @qmk/directors that it is done before continuing -* `qmk_firmware` git commands - * `git checkout master` - * `git pull --ff-only` - * `git merge --no-ff develop` - * `git tag ` # Prevent the breakpoint tag from confusing version incrementing - * `git push upstream ` - * `git push upstream master` - -## Post-merge operations - -### Updating the `develop` branch - -This happens immediately after the previous `develop` branch is merged to `master`. - -* `qmk_firmware` git commands - * `git checkout master` - * `git pull --ff-only` - * `git checkout develop` - * `git pull --ff-only` - * `git merge --no-ff master` - * Edit `readme.md` - * Add a big notice at the top that this is a testing branch. See previous revisions of the `develop` branch. - * Include a link to this document - * `git commit -m 'Branch point for Breaking Change'` - * `git tag breakpoint___
` - * `git push upstream breakpoint___
` - * `git push upstream develop` - -* All submodules under `lib` now need to be checked against their QMK-based forks: - * `git submodule foreach git log -n1` - * Validate each submodule SHA1 matches the qmk fork, e.g. for ChibiOS: - * Go to [qmk/ChibiOS](https://github.com/qmk/ChibiOS) - * Compare the commit hash in the above output to the commit hash in the repository - * If there's a mismatch, that repository needs to have its `qmk-master` branch updated to match (otherwise Configurator won't work): - * `cd lib/chibios` - * `git fetch --all` - * `git checkout qmk-master` - * `git reset --hard ` - * `git push origin qmk-master --force-with-lease` - -* Announce that both `master` and `develop` are now unlocked -- message `@Breaking Changes Updates` on `#qmk_firmware` in Discord: - * `@Breaking Changes Updates -- Hey folks, develop has now been merged into master -- newest batch of changes are now available for everyone to use!` - -* (Optional) [update ChibiOS + ChibiOS-Contrib on `develop`](chibios_upgrade_instructions.md) - - -### Set up Discord events for the next cycle - -* Update this file with the new dates: `docs/breaking_changes.md` -* Create Events on the QMK Discord - "Somewhere Else" => "GitHub": - * Event #1: - | Field | Value | - |-------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - | Topic | Last `develop` functionality PRs to be raised | - | Start Date | ((5 weeks before merge)), 12:00am | - | End Date | ((4 weeks before merge)), 12:00am | - | Description | This is the last window for functional PRs to be raised against `develop` for the current breaking changes cycle. After ((4 weeks before merge)), any new PRs targeting `develop` will be deferred to the next cycle. | - * Event #2: - | Field | Value | - |-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - | Topic | Last `develop` functionality PRs to be merged | - | Start Date | ((4 weeks before merge)), 12:00am | - | End Date | ((2 weeks before merge)), 12:00am | - | Description | This is the last window for functional PRs to be merged into `develop` for the current breaking changes cycle. After ((2 weeks before merge)), only bugfix PRs targeting `develop` will be considered for merge. | - * Event #3: - | Field | Value | - |-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| - | Topic | `develop` closed for merges | - | Start Date | ((2 weeks before merge)), 12:00am | - | End Date | ((day of merge)), 12:00am | - | Description | This is the deadline for functionality bugfix PRs to be merged into `develop` for the current breaking changes cycle. After ((1 week before merge)), only critical bugfix PRs targeting `develop` will be considered for merge. | - * Event #4: - | Field | Value | - |-------------|----------------------------------------------------------------------------------------------------------------------| - | Topic | `master` closed for merges | - | Start Date | ((2 days before merge)), 12:00am | - | End Date | ((day of merge)), 12:00am | - | Description | This is the period that no PRs are to be merged to `master`, so that the merge of `develop` into `master` is stable. | - * Event #5: - | Field | Value | - |-------------|--------------------------------------------------------------------------------------------------------------------------------------------| - | Topic | `develop` merges to `master` | - | Start Date | ((day of merge)), 12:00am | - | End Date | ((day of merge)), 11:45pm | - | Description | At some point, QMK will merge `develop` into `master` and everyone will be able to reap the benefits of the newest batch of functionality. | diff --git a/docs/breaking_changes_history.md b/docs/breaking_changes_history.md deleted file mode 100644 index 79f2899d2cf6..000000000000 --- a/docs/breaking_changes_history.md +++ /dev/null @@ -1,19 +0,0 @@ -# Past Breaking Changes - -This page links to all previous changelogs from the QMK Breaking Changes process. - -* [2023 May 28](ChangeLog/20230528.md) - version 0.21.0 -* [2023 Feb 26](ChangeLog/20230226.md) - version 0.20.0 -* [2022 Nov 26](ChangeLog/20221126.md) - version 0.19.0 -* [2022 Aug 27](ChangeLog/20220827.md) - version 0.18.0 -* [2022 May 28](ChangeLog/20220528.md) - version 0.17.0 -* [2022 Feb 26](ChangeLog/20220226.md) - version 0.16.0 -* [2021 Nov 27](ChangeLog/20211127.md) - version 0.15.0 -* [2021 Aug 28](ChangeLog/20210828.md) - version 0.14.0 -* [2021 May 29](ChangeLog/20210529.md) - version 0.13.0 -* [2021 Feb 27](ChangeLog/20210227.md) - version 0.12.0 -* [2020 Nov 28](ChangeLog/20201128.md) - version 0.11.0 -* [2020 Aug 29](ChangeLog/20200829.md) - version 0.10.0 -* [2020 May 30](ChangeLog/20200530.md) - version 0.9.0 -* [2020 Feb 29](ChangeLog/20200229.md) - version 0.8.0 -* [2019 Aug 30](ChangeLog/20190830.md) - version 0.7.0 diff --git a/docs/breaking_changes_instructions.md b/docs/breaking_changes_instructions.md deleted file mode 100644 index 7bde4b600451..000000000000 --- a/docs/breaking_changes_instructions.md +++ /dev/null @@ -1,34 +0,0 @@ -# Breaking Changes: My Pull Request Was Flagged - -A QMK member may have replied to your pull request stating that your submission is a breaking change. In their judgment, the changes you have proposed have greater implications for either QMK, or its users. - -Some things that may cause a pull request to be flagged are: - -- **Edits to User Keymaps** - A user may submit their keymap to QMK, then some time later open a pull request with further updates, only to find it can't be merged because it was edited in the `qmk/qmk_firmware` repository. As not all users are proficient at using Git or GitHub, the user may find themself unable to fix the issue on their own. -- **Changes to Expected Behavior** - Changes to QMK behavior may cause users to believe their hardware or QMK is broken if they flash new firmware that incorporates changes to existing QMK features, and find themselves without a means to restore the desired behavior. -- **Changes Requiring User Action** - Changes may also require action to be taken by users, such as updating a toolchain or taking some action in Git. -- **Changes Necessitating Increased Scrutiny** - On occasion, a submission may have implications for QMK as a project. This could be copyright/licensing issues, coding conventions, large feature overhauls, "high-risk" changes that need wider testing by our community, or something else entirely. -- **Changes Requiring Communication to End Users** - This includes warnings about future deprecations, outdated practices, and anything else that needs to be communicated but doesn't fit into one of the above categories. - -## What Do I Do? - -If it is determined that your submission is a breaking change, there are a few things you can do to smooth the process: - -### Consider Splitting Up Your PR - -If you are contributing core code, and the only reason it needs to go through breaking changes is that you are updating keymaps to match your change, consider whether you can submit your feature in a way that the old keymaps continue to work. Then submit a separate PR that goes through the breaking changes process to remove the old code. - -### Document Your Changes - -Understanding the purpose for your submission, and possible implications or actions it will require can make the review process more straightforward. A changelog may suffice for this purpose, but more extensive changes may require a level of detail that is ill-suited for a changelog. - -Commenting on your pull request and being responsive to questions, comments, and change requests is much appreciated. - -### Ask for Help - -Having your submission flagged may have caught you off guard. If you find yourself intimidated or overwhelmed, let us know. Comment on your pull request, or [reach out to the QMK team on Discord](https://discord.gg/Uq7gcHh). diff --git a/docs/chibios_upgrade_instructions.md b/docs/chibios_upgrade_instructions.md deleted file mode 100644 index 62f16d0d25f3..000000000000 --- a/docs/chibios_upgrade_instructions.md +++ /dev/null @@ -1,72 +0,0 @@ -# ChibiOS Upgrade Procedure - -ChibiOS and ChibiOS-Contrib need to be updated in tandem -- the latter has a branch tied to the ChibiOS version in use and should not be mixed with different versions. - -## Getting ChibiOS - -* `svn` Initialization: - * Only needed to be done once - * You might need to separately install `git-svn` package in your OS's package manager - * `git svn init --stdlayout --prefix='svn/' http://svn.osdn.net/svnroot/chibios/` - * `git remote add qmk git@github.com:qmk/ChibiOS.git` -* Updating: - * `git svn fetch` - * First time around this will take several hours - * Subsequent updates will be incremental only -* Tagging example (work out which version first!): - * `git tag -a ver20.3.4 -m ver20.3.4 svn/tags/ver20.3.4` - * `git push qmk ver20.3.4` - * `git tag -a develop_YYYY_qN -m develop_YYYY_qN svn/tags/ver20.3.4` - * `git push qmk develop_YYYY_qN` - -## Getting ChibiOS-Contrib - -* `git` Initialization: - * `git clone git@github.com:qmk/ChibiOS-Contrib` - * `git remote add upstream https://github.com/ChibiOS/ChibiOS-Contrib` - * `git checkout -b chibios-20.3.x upstream/chibios-20.3.x` -* Updating: - * `git fetch --all --tags --prune` - * `git checkout chibios-20.3.x` - * `git pull --ff-only` - * `git push origin chibios-20.3.x` - * `git tag -a develop_YYYY_qN -m develop_YYYY_qN chibios-20.3.x` - * `git push origin develop_YYYY_qN` - -## Updating submodules - -* Update the submodules - * `cd $QMK_FIRMWARE` - * `git checkout develop` - * `git pull --ff-only` - * `git checkout -b chibios-version-bump` - * `cd lib/chibios` - * `git fetch --all --tags --prune` - * `git checkout develop_YYYY_qN` - * `cd ../chibios-contrib` - * `git fetch --all --tags --prune` - * `git checkout develop_YYYY_qN` -* Update ChibiOS configs within QMK - * `cd $QMK_FIRMWARE` - * `./util/chibios_conf_updater.sh` -* Build everything - * `cd $QMK_FIRMWARE` - * `qmk mass-compile -j 4` - * Make sure there are no errors -* Push to the repo - * `git commit -am 'Update ChibiOS to 99.9.9'` - * `git push --set-upstream origin chibios-version-bump` -* Make a PR to qmk_firmware with the new branch - -## When merging a PR containing an upgrade of ChibiOS/ChibiOS-Contrib: - -* Update the target branch if the merge target was `master`: - * `git checkout qmk-master` - * `git reset --hard develop_YYYY_qN` - * `git push origin qmk-master --force-with-lease` -* Update the target branch if the merge target was `develop`: - * `git checkout qmk-develop` - * `git reset --hard develop_YYYY_qN` - * `git push origin qmk-develop --force-with-lease` - -Note that when merging `develop` to `master`, the first workflow should still be followed. diff --git a/docs/cli.md b/docs/cli.md deleted file mode 100644 index 8684479d0c1d..000000000000 --- a/docs/cli.md +++ /dev/null @@ -1,38 +0,0 @@ -# QMK CLI :id=qmk-cli - -## Overview :id=overview - -The QMK CLI makes building and working with QMK keyboards easier. We have provided a number of commands to simplify and streamline tasks such as obtaining and compiling the QMK firmware, creating keymaps, and more. - -### Requirements :id=requirements - -QMK requires Python 3.6 or greater. We try to keep the number of requirements small but you will also need to install the packages listed in [`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt). These are installed automatically when you install the QMK CLI. - -### Install Using Homebrew (macOS, some Linux) :id=install-using-homebrew - -If you have installed [Homebrew](https://brew.sh) you can tap and install QMK: - -``` -brew install qmk/qmk/qmk -export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` -qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment -``` - -### Install Using pip :id=install-using-easy_install-or-pip - -If your system is not listed above you can install QMK manually. First ensure that you have Python 3.6 (or later) installed and have installed pip. Then install QMK with this command: - -``` -python3 -m pip install qmk -export QMK_HOME='~/qmk_firmware' # Optional, set the location for `qmk_firmware` -qmk setup # This will clone `qmk/qmk_firmware` and optionally set up your build environment -``` - -### Packaging For Other Operating Systems :id=packaging-for-other-operating-systems - -We are looking for people to create and maintain a `qmk` package for more operating systems. If you would like to create a package for your OS please follow these guidelines: - -* Follow best practices for your OS when they conflict with these guidelines - * Document why in a comment when you do deviate -* Install using a virtualenv -* Instruct the user to set the environment variable `QMK_HOME` to have the firmware source checked out somewhere other than `~/qmk_firmware`. diff --git a/docs/cli_commands.md b/docs/cli_commands.md deleted file mode 100644 index 79fd9de57576..000000000000 --- a/docs/cli_commands.md +++ /dev/null @@ -1,658 +0,0 @@ -# QMK CLI Commands - -# User Commands - -## `qmk compile` - -This command allows you to compile firmware from any directory. You can compile JSON exports from , compile keymaps in the repo, or compile the keyboard in the current working directory. - -This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. - -**Usage for Configurator Exports**: - -``` -qmk compile [-c] -``` - -**Usage for Keymaps**: - -``` -qmk compile [-c] [-e =] [-j ] -kb -km -``` - -**Usage in Keyboard Directory**: - -Must be in keyboard directory with a default keymap, or in keymap directory for keyboard, or supply one with `--keymap ` -``` -qmk compile -``` - -**Usage for building all keyboards that support a specific keymap**: - -``` -qmk compile -kb all -km -``` - -**Example**: -``` -$ qmk config compile.keymap=default -$ cd ~/qmk_firmware/keyboards/planck/rev6 -$ qmk compile -Ψ Compiling keymap with make planck/rev6:default -... -``` -or with optional keymap argument - -``` -$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4 -$ qmk compile -km 66_iso -Ψ Compiling keymap with make clueboard/66/rev4:66_iso -... -``` -or in keymap directory - -``` -$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak -$ qmk compile -Ψ Compiling keymap with make gh60/satan:colemak -... -``` - -**Usage in Layout Directory**: - -Must be under `qmk_firmware/layouts/`, and in a keymap folder. -``` -qmk compile -kb -``` - -**Example**: -``` -$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi -$ qmk compile -kb dz60 -Ψ Compiling keymap with make dz60:mechmerlin-ansi -... -``` - -**Parallel Compilation**: - -It is possible to speed up compilation by adding the `-j`/`--parallel` flag. -``` -qmk compile -j -kb -``` -The `num_jobs` argument determines the maximum number of jobs that can be used. Setting it to zero will enable parallel compilation without limiting the maximum number of jobs. -``` -qmk compile -j 0 -kb -``` - -## `qmk flash` - -This command is similar to `qmk compile`, but can also target a bootloader. The bootloader is optional, and is set to `:flash` by default. To specify a different bootloader, use `-bl `. Visit the [Flashing Firmware](flashing.md) guide for more details of the available bootloaders. - -This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. - -This command can also flash binary firmware files (hex or bin) such as the ones produced by [Configurator](https://config.qmk.fm). - -**Usage for Configurator Exports**: - -``` -qmk flash [-bl ] [-c] [-e =] [-j ] -``` - -**Usage for Keymaps**: - -``` -qmk flash -kb -km [-bl ] [-c] [-e =] [-j ] -``` - -**Usage for pre-compiled firmwares**: - -**Note**: The microcontroller needs to be specified (`-m` argument) for keyboards with the following bootloaders: -* HalfKay -* QMK HID -* USBaspLoader - -ISP flashing is also supported with the following flashers and require the microcontroller to be specified: -* USBasp -* USBtinyISP - -``` -qmk flash [-m ] -``` - -**Listing the Bootloaders** - -``` -qmk flash -b -``` - -## `qmk config` - -This command lets you configure the behavior of QMK. For the full `qmk config` documentation see [CLI Configuration](cli_configuration.md). - -**Usage**: - -``` -qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] -``` - -## `qmk cd` - -This command opens a new shell in your `qmk_firmware` directory. - -Note that if you are already somewhere within `QMK_HOME` (for example, the `keyboards/` folder), nothing will happen. - -To exit out into the parent shell, simply type `exit`. - -**Usage**: - -``` -qmk cd -``` - -## `qmk find` - -This command allows for searching through keyboard/keymap targets, filtering by specific criteria. `info.json` and `rules.mk` files contribute to the search data, as well as keymap configurations, and the results can be filtered using "dotty" syntax matching the overall `info.json` file format. - -For example, one could search for all keyboards using STM32F411: - -``` -qmk find -f 'processor=STM32F411' -``` - -...and one can further constrain the list to keyboards using STM32F411 as well as rgb_matrix support: - -``` -qmk find -f 'processor=STM32F411' -f 'features.rgb_matrix=true' -``` - -The following filter expressions are also supported: - - - `exists(key)`: Match targets where `key` is present. - - `absent(key)`: Match targets where `key` is not present. - - `contains(key, value)`: Match targets where `key` contains `value`. Can be used for strings, arrays and object keys. - - `length(key, value)`: Match targets where the length of `key` is `value`. Can be used for strings, arrays and objects. - -You can also list arbitrary values for each matched target with `--print`: - -``` -qmk find -f 'processor=STM32F411' -p 'keyboard_name' -p 'features.rgb_matrix' -``` - -**Usage**: - -``` -qmk find [-h] [-km KEYMAP] [-p PRINT] [-f FILTER] - -options: - -km KEYMAP, --keymap KEYMAP - The keymap name to build. Default is 'default'. - -p PRINT, --print PRINT - For each matched target, print the value of the supplied info.json key. May be passed multiple times. - -f FILTER, --filter FILTER - Filter the list of keyboards based on their info.json data. Accepts the formats key=value, function(key), or function(key,value), eg. 'features.rgblight=true'. Valid functions are 'absent', 'contains', 'exists' and 'length'. May be passed multiple times; all filters need to match. Value may include wildcards such as '*' and '?'. -``` - -## `qmk console` - -This command lets you connect to keyboard consoles to get debugging messages. It only works if your keyboard firmware has been compiled with `CONSOLE_ENABLE=yes`. - -**Usage**: - -``` -qmk console [-d :[:]] [-l] [-n] [-t] [-w ] -``` - -**Examples**: - -Connect to all available keyboards and show their console messages: - -``` -qmk console -``` - -List all devices: - -``` -qmk console -l -``` - -Show only messages from clueboard/66/rev3 keyboards: - -``` -qmk console -d C1ED:2370 -``` - -Show only messages from the second clueboard/66/rev3: - -``` -qmk console -d C1ED:2370:2 -``` - -Show timestamps and VID:PID instead of names: - -``` -qmk console -n -t -``` - -Disable bootloader messages: - -``` -qmk console --no-bootloaders -``` - -## `qmk doctor` - -This command examines your environment and alerts you to potential build or flash problems. It can fix many of them if you want it to. - -**Usage**: - -``` -qmk doctor [-y] [-n] -``` - -**Examples**: - -Check your environment for problems and prompt to fix them: - - qmk doctor - -Check your environment and automatically fix any problems found: - - qmk doctor -y - -Check your environment and report problems only: - - qmk doctor -n - -## `qmk format-json` - -Formats a JSON file in a (mostly) human-friendly way. Will usually correctly detect the format of the JSON (info.json or keymap.json) but you can override this with `--format` if necessary. - -**Usage**: - -``` -qmk format-json [-f FORMAT] -``` - -## `qmk info` - -Displays information about keyboards and keymaps in QMK. You can use this to get information about a keyboard, show the layouts, display the underlying key matrix, or to pretty-print JSON keymaps. - -**Usage**: - -``` -qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD] -``` - -This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. - -**Examples**: - -Show basic information for a keyboard: - - qmk info -kb planck/rev5 - -Show the matrix for a keyboard: - - qmk info -kb ergodox_ez -m - -Show a JSON keymap for a keyboard: - - qmk info -kb clueboard/california -km default - -## `qmk json2c` - -Creates a keymap.c from a QMK Configurator export. - -**Usage**: - -``` -qmk json2c [-o OUTPUT] filename -``` - -## `qmk c2json` - -Creates a keymap.json from a keymap.c. - -**Note:** Parsing C source files is not easy, therefore this subcommand may not work with your keymap. In some cases not using the C pre-processor helps. - -**Usage**: - -``` -qmk c2json -km KEYMAP -kb KEYBOARD [-q] [--no-cpp] [-o OUTPUT] filename -``` - -## `qmk lint` - -Checks over a keyboard and/or keymap and highlights common errors, problems, and anti-patterns. - -**Usage**: - -``` -qmk lint [-km KEYMAP] [-kb KEYBOARD] [--strict] -``` - -This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. - -**Examples**: - -Do a basic lint check: - - qmk lint -kb rominronin/katana60/rev2 - -## `qmk list-keyboards` - -This command lists all the keyboards currently defined in `qmk_firmware` - -**Usage**: - -``` -qmk list-keyboards -``` - -## `qmk list-keymaps` - -This command lists all the keymaps for a specified keyboard (and revision). - -This command is directory aware. It will automatically fill in KEYBOARD if you are in a keyboard directory. - -**Usage**: - -``` -qmk list-keymaps -kb planck/ez -``` - -## `qmk new-keyboard` - -This command creates a new keyboard based on available templates. - -Any arguments that are not provided will prompt for input. If `-u` is not passed and `user.name` is set in .gitconfig, it will be used as the default username in the prompt. - -**Usage**: - -``` -qmk new-keyboard [-kb KEYBOARD] [-t {atmega32u4,STM32F303,etc}] [-l {60_ansi,75_iso,etc}] -u USERNAME -``` - -## `qmk new-keymap` - -This command creates a new keymap based on a keyboard's existing default keymap. - -This command is directory aware. It will automatically fill in KEYBOARD and/or KEYMAP if you are in a keyboard or keymap directory. - -**Usage**: - -``` -qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] -``` - -## `qmk clean` - -This command cleans up the `.build` folder. If `--all` is passed, any .hex or .bin files present in the `qmk_firmware` directory will also be deleted. - -**Usage**: - -``` -qmk clean [-a] -``` - -## `qmk via2json` - -This command an generate a keymap.json from a VIA keymap backup. Both the layers and the macros are converted, enabling users to easily move away from a VIA-enabled firmware without writing any code or reimplementing their keymaps in QMK Configurator. - -**Usage**: - -``` -qmk via2json -kb KEYBOARD [-l LAYOUT] [-km KEYMAP] [-o OUTPUT] filename -``` - -**Example:** - -``` -$ qmk via2json -kb ai03/polaris -o polaris_keymap.json polaris_via_backup.json -Ψ Wrote keymap to /home/you/qmk_firmware/polaris_keymap.json -``` - -## `qmk import-keyboard` - -This command imports a data-driven `info.json` keyboard into the repo. - -**Usage**: - -``` -usage: qmk import-keyboard [-h] filename -``` - -**Example:** - -``` -$ qmk import-keyboard ~/Downloads/forever60.json -Ψ Importing forever60.json. - -Ψ Imported a new keyboard named forever60. -Ψ To start working on things, `cd` into keyboards/forever60, -Ψ or open the directory in your preferred text editor. -Ψ And build with qmk compile -kb forever60 -km default. -``` - -## `qmk import-keymap` - -This command imports a data-driven `keymap.json` keymap into the repo. - -**Usage**: - -``` -usage: qmk import-keymap [-h] filename -``` - -**Example:** - -``` -qmk import-keymap ~/Downloads/asdf2.json -Ψ Importing asdf2.json. - -Ψ Imported a new keymap named asdf2. -Ψ To start working on things, `cd` into keyboards/takashicompany/dogtag/keymaps/asdf2, -Ψ or open the directory in your preferred text editor. -Ψ And build with qmk compile -kb takashicompany/dogtag -km asdf2. -``` - -## `qmk import-kbfirmware` - -This command creates a new keyboard based on a [Keyboard Firmware Builder](https://kbfirmware.com/) export. - -**Usage**: - -``` -usage: qmk import-kbfirmware [-h] filename -``` - -**Example:** - -``` -$ qmk import-kbfirmware ~/Downloads/gh62.json -Ψ Importing gh62.json. - -⚠ Support here is basic - Consider using 'qmk new-keyboard' instead -Ψ Imported a new keyboard named gh62. -Ψ To start working on things, `cd` into keyboards/gh62, -Ψ or open the directory in your preferred text editor. -Ψ And build with qmk compile -kb gh62 -km default. -``` - ---- - -# Developer Commands - -## `qmk format-text` - -This command formats text files to have proper line endings. - -Every text file in the repository needs to have Unix (LF) line ending. -If you are working on **Windows**, you must ensure that line endings are corrected in order to get your PRs merged. - -``` -qmk format-text -``` - -## `qmk format-c` - -This command formats C code using clang-format. - -Run it with no arguments to format all core code that has been changed. Default checks `origin/master` with `git diff`, branch can be changed using `-b ` - -Run it with `-a` to format all core code, or pass filenames on the command line to run it on specific files. - -**Usage for specified files**: - -``` -qmk format-c [file1] [file2] [...] [fileN] -``` - -**Usage for all core files**: - -``` -qmk format-c -a -``` - -**Usage for only changed files against origin/master**: - -``` -qmk format-c -``` - -**Usage for only changed files against branch_name**: - -``` -qmk format-c -b branch_name -``` - -## `qmk generate-compilation-database` - -**Usage**: - -``` -qmk generate-compilation-database [-kb KEYBOARD] [-km KEYMAP] -``` - -Creates a `compile_commands.json` file. - -Does your IDE/editor use a language server but doesn't _quite_ find all the necessary include files? Do you hate red squigglies? Do you wish your editor could figure out `#include QMK_KEYBOARD_H`? You might need a [compilation database](https://clang.llvm.org/docs/JSONCompilationDatabase.html)! The qmk tool can build this for you. - -This command needs to know which keyboard and keymap to build. It uses the same configuration options as the `qmk compile` command: arguments, current directory, and config files. - -**Example:** - -``` -$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak -$ qmk generate-compilation-database -Ψ Making clean -Ψ Gathering build instructions from make -n gh60/satan:colemak -Ψ Found 50 compile commands -Ψ Writing build database to /Users/you/src/qmk_firmware/compile_commands.json -``` - -Now open your dev environment and live a squiggly-free life. - -## `qmk docs` - -This command starts a local HTTP server which you can use for browsing or improving the docs. Default port is 8936. -Use the `-b`/`--browser` flag to automatically open the local webserver in your default browser. - -This command runs `docsify serve` if `docsify-cli` is installed (which provides live reload), otherwise Python's builtin HTTP server module will be used. - -**Usage**: - -``` -qmk docs [-b] [-p PORT] -``` - -## `qmk generate-docs` - -This command allows you to generate QMK documentation locally. It can be uses for general browsing or improving the docs. External tools such as [serve](https://www.npmjs.com/package/serve) can be used to browse the generated files. - -**Usage**: - -``` -qmk generate-docs -``` - -## `qmk generate-rgb-breathe-table` - -This command generates a lookup table (LUT) header file for the [RGB Lighting](feature_rgblight.md) feature's breathing animation. Place this file in your keyboard or keymap directory as `rgblight_breathe_table.h` to override the default LUT in `quantum/rgblight/`. - -**Usage**: - -``` -qmk generate-rgb-breathe-table [-q] [-o OUTPUT] [-m MAX] [-c CENTER] -``` - -## `qmk kle2json` - -This command allows you to convert from raw KLE data to QMK Configurator JSON. It accepts either an absolute file path, or a file name in the current directory. By default it will not overwrite `info.json` if it is already present. Use the `-f` or `--force` flag to overwrite. - -**Usage**: - -``` -qmk kle2json [-f] -``` - -**Examples**: - -``` -$ qmk kle2json kle.txt -☒ File info.json already exists, use -f or --force to overwrite. -``` - -``` -$ qmk kle2json -f kle.txt -f -Ψ Wrote out to info.json -``` - -## `qmk format-python` - -This command formats python code in `qmk_firmware`. - -**Usage**: - -``` -qmk format-python -``` - -## `qmk pytest` - -This command runs the python test suite. If you make changes to python code you should ensure this runs successfully. - -**Usage**: - -``` -qmk pytest [-t TEST] -``` - -**Examples**: - -Run entire test suite: - - qmk pytest - -Run test group: - - qmk pytest -t qmk.tests.test_cli_commands - -Run single test: - - qmk pytest -t qmk.tests.test_cli_commands.test_c2json - qmk pytest -t qmk.tests.test_qmk_path - -## `qmk painter-convert-graphics` - -This command converts images to a format usable by QMK, i.e. the QGF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command. - -## `qmk painter-make-font-image` - -This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command. - -## `qmk painter-convert-font-image` - -This command converts an intermediate font image to the QFF File Format. See the [Quantum Painter](quantum_painter.md?id=quantum-painter-cli) documentation for more information on this command. - diff --git a/docs/cli_configuration.md b/docs/cli_configuration.md deleted file mode 100644 index 50f5dc6e2804..000000000000 --- a/docs/cli_configuration.md +++ /dev/null @@ -1,121 +0,0 @@ -# QMK CLI Configuration - -This document explains how `qmk config` works. - -# Introduction - -Configuration for the QMK CLI is a key/value system. Each key consists of a subcommand and an argument name separated by a period. This allows for a straightforward and direct translation between config keys and the arguments they set. - -## Simple Example - -As an example let's look at the command `qmk compile --keyboard clueboard/66/rev4 --keymap default`. - -There are two command line arguments that could be read from configuration instead: - -* `compile.keyboard` -* `compile.keymap` - -Let's set these now: - -``` -$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default -compile.keyboard: None -> clueboard/66/rev4 -compile.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -Now I can run `qmk compile` without specifying my keyboard and keymap each time. - -## Setting User Defaults - -Sometimes you want to share a setting between multiple commands. For example, multiple commands take the argument `--keyboard`. Rather than setting this value for every command you can set a user value which will be used by any command that takes that argument. - -Example: - -``` -$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default -user.keyboard: None -> clueboard/66/rev4 -user.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# CLI Documentation (`qmk config`) - -The `qmk config` command is used to interact with the underlying configuration. When run with no argument it shows the current configuration. When arguments are supplied they are assumed to be configuration tokens, which are strings containing no spaces with the following form: - - [.][=] - -## Setting Configuration Values - -You can set configuration values by putting an equal sign (=) into your config key. The key must always be the full `
.` form. - -Example: - -``` -$ qmk config default.keymap=default -default.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## Reading Configuration Values - -You can read configuration values for the entire configuration, a single key, or for an entire section. You can also specify multiple keys to display more than one value. - -### Entire Configuration Example - - qmk config - -### Whole Section Example - - qmk config compile - -### Single Key Example - - qmk config compile.keyboard - -### Multiple Keys Example - - qmk config user compile.keyboard compile.keymap - -## Deleting Configuration Values - -You can delete a configuration value by setting it to the special string `None`. - -Example: - -``` -$ qmk config default.keymap=None -default.keymap: default -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## Multiple Operations - -You can combine multiple read and write operations into a single command. They will be executed and displayed in order: - -``` -$ qmk config compile default.keymap=default compile.keymap=None -compile.keymap=skully -compile.keyboard=clueboard/66_hotswap/gen1 -default.keymap: None -> default -compile.keymap: skully -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# User Configuration Options - -| Key | Default Value | Description | -|-----|---------------|-------------| -| user.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | -| user.keymap | None | The keymap name (Example: `default`) | -| user.name | None | The user's GitHub username. | - -# All Configuration Options - -| Key | Default Value | Description | -|-----|---------------|-------------| -| compile.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | -| compile.keymap | None | The keymap name (Example: `default`) | -| hello.name | None | The name to greet when run. | -| new_keyboard.keyboard | None | The keyboard path (Example: `clueboard/66/rev4`) | -| new_keyboard.keymap | None | The keymap name (Example: `default`) | diff --git a/docs/cli_development.md b/docs/cli_development.md deleted file mode 100644 index d878deff17c4..000000000000 --- a/docs/cli_development.md +++ /dev/null @@ -1,219 +0,0 @@ -# QMK CLI Development - -This document has useful information for developers wishing to write new `qmk` subcommands. - -# Overview - -The QMK CLI operates using the subcommand pattern made famous by git. The main `qmk` script is simply there to setup the environment and pick the correct entrypoint to run. Each subcommand is a self-contained module with an entrypoint (decorated by `@cli.subcommand()`) that performs some action and returns a shell returncode, or None. - -## Developer mode: - -If you intend to maintain keyboards and/or contribute to QMK, you can enable the CLI's "Developer" mode: - -`qmk config user.developer=True` - -This will allow you to see all available subcommands. -**Note:** You will have to install additional requirements: -``` -python3 -m pip install -r requirements-dev.txt -``` - -# Subcommands - -[MILC](https://github.com/clueboard/milc) is the CLI framework `qmk` uses to handle argument parsing, configuration, logging, and many other features. It lets you focus on writing your tool without wasting your time writing glue code. - -Subcommands in the local CLI are always found in `qmk_firmware/lib/python/qmk/cli`. - -Let's start by looking at an example subcommand. This is `lib/python/qmk/cli/hello.py`: - -```python -"""QMK Python Hello World - -This is an example QMK CLI script. -""" -from milc import cli - - -@cli.argument('-n', '--name', default='World', help='Name to greet.') -@cli.subcommand('QMK Hello World.') -def hello(cli): - """Log a friendly greeting. - """ - cli.log.info('Hello, %s!', cli.config.hello.name) -``` - -First we import the `cli` object from `milc`. This is how we interact with the user and control the script's behavior. We use `@cli.argument()` to define a command line flag, `--name`. This also creates a configuration variable named `hello.name` (and the corresponding `user.name`) which the user can set so they don't have to specify the argument. The `cli.subcommand()` decorator designates this function as a subcommand. The name of the subcommand will be taken from the name of the function. - -Once inside our function we find a typical "Hello, World!" program. We use `cli.log` to access the underlying [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects), whose behavior is user controllable. We also access the value for name supplied by the user as `cli.config.hello.name`. The value for `cli.config.hello.name` will be determined by looking at the `--name` argument supplied by the user, if not provided it will use the value in the `qmk.ini` config file, and if neither of those is provided it will fall back to the default supplied in the `cli.argument()` decorator. - -# User Interaction - -MILC and the QMK CLI have several nice tools for interacting with the user. Using these standard tools will allow you to colorize your text for easier interactions, and allow the user to control when and how that information is displayed and stored. - -## Printing Text - -There are two main methods for outputting text in a subcommand- `cli.log` and `cli.echo()`. They operate in similar ways but you should prefer to use `cli.log.info()` for most general purpose printing. - -You can use special tokens to colorize your text, to make it easier to understand the output of your program. See [Colorizing Text](#colorizing-text) below. - -Both of these methods support built-in string formatting using python's [printf style string format operations](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting). You can use tokens such as `%s` and `%d` within your text strings then pass the values as arguments. See our Hello, World program above for an example. - -You should never use the format operator (`%`) directly, always pass values as arguments. - -### Logging (`cli.log`) - -The `cli.log` object gives you access to a [Logger Object](https://docs.python.org/3.6/library/logging.html#logger-objects). We have configured our log output to show the user a nice emoji for each log level (or the log level name if their terminal does not support unicode.) This way the user can tell at a glance which messages are most important when something goes wrong. - -The default log level is `INFO`. If the user runs `qmk -v ` the default log level will be set to `DEBUG`. - -| Function | Emoji | -|----------|-------| -| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` | -| cli.log.error | `{fg_red}☒{style_reset_all}` | -| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` | -| cli.log.info | `{fg_blue}Ψ{style_reset_all}` | -| cli.log.debug | `{fg_cyan}☐{style_reset_all}` | -| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` | - -### Printing (`cli.echo`) - -Sometimes you simply need to print text outside of the log system. This is appropriate if you are outputting fixed data or writing out something that should never be logged. Most of the time you should prefer `cli.log.info()` over `cli.echo`. - -### Colorizing Text - -You can colorize the output of your text by including color tokens within text. Use color to highlight, not to convey information. Remember that the user can disable color, and your subcommand should still be usable if they do. - -You should generally avoid setting the background color, unless it's integral to what you are doing. Remember that users have a lot of preferences when it comes to their terminal color, so you should pick colors that work well against both black and white backgrounds. - -Colors prefixed with 'fg' will affect the foreground (text) color. Colors prefixed with 'bg' will affect the background color. - -| Color | Background | Extended Background | Foreground | Extended Foreground| -|-------|------------|---------------------|------------|--------------------| -| Black | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} | -| Blue | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} | -| Cyan | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} | -| Green | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} | -| Magenta | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} | -| Red | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} | -| White | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} | -| Yellow | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} | - -There are also control sequences that can be used to change the behavior of -ANSI output: - -| Control Sequences | Description | -|-------------------|-------------| -| {style_bright} | Make the text brighter | -| {style_dim} | Make the text dimmer | -| {style_normal} | Make the text normal (neither `{style_bright}` nor `{style_dim}`) | -| {style_reset_all} | Reset all text attributes to default. (This is automatically added to the end of every string.) | -| {bg_reset} | Reset the background color to the user's default | -| {fg_reset} | Reset the foreground color to the user's default | - -# Arguments and Configuration - -QMK handles the details of argument parsing and configuration for you. When you add a new argument it is automatically incorporated into the config tree based on your subcommand's name and the long name of the argument. You can access this configuration in `cli.config`, using either attribute-style access (`cli.config..`) or dictionary-style access (`cli.config['']['']`). - -Under the hood QMK uses [ConfigParser](https://docs.python.org/3/library/configparser.html) to store configurations. This gives us an easy and straightforward way to represent the configuration in a human-editable way. We have wrapped access to this configuration to provide some nicities that ConfigParser does not normally have. - -## Reading Configuration Values - -You can interact with `cli.config` in all the ways you'd normally expect. For example the `qmk compile` command gets the keyboard name from `cli.config.compile.keyboard`. It does not need to know whether that value came from the command line, an environment variable, or the configuration file. - -Iteration is also supported: - -``` -for section in cli.config: - for key in cli.config[section]: - cli.log.info('%s.%s: %s', section, key, cli.config[section][key]) -``` - -## Setting Configuration Values - -You can set configuration values in the usual ways. - -Dictionary style: - -``` -cli.config['
'][''] = -``` - -Attribute style: - -``` -cli.config.
. = -``` - -## Deleting Configuration Values - -You can delete configuration values in the usual ways. - -Dictionary style: - -``` -del(cli.config['
']['']) -``` - -Attribute style: - -``` -del(cli.config.
.) -``` - -## Writing The Configuration File - -The configuration is not written out when it is changed. Most commands do not need to do this. We prefer to have the user change their configuration deliberately using `qmk config`. - -You can use `cli.save_config()` to write out the configuration. - -## Excluding Arguments From Configuration - -Some arguments should not be propagated to the configuration file. These can be excluded by adding `arg_only=True` when creating the argument. - -Example: - -``` -@cli.argument('-o', '--output', arg_only=True, help='File to write to') -@cli.argument('filename', arg_only=True, help='Configurator JSON file') -@cli.subcommand('Create a keymap.c from a QMK Configurator export.') -def json_keymap(cli): - pass -``` - -You will only be able to access these arguments using `cli.args`. For example: - -``` -cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output) -``` - -# Testing, and Linting, and Formatting (oh my!) - -We use nose2, flake8, and yapf to test, lint, and format code. You can use the `pytest` and `format-python` subcommands to run these tests: - -### Testing and Linting - - qmk pytest - -### Formatting - - qmk format-python - -## Formatting Details - -We use [yapf](https://github.com/google/yapf) to automatically format code. Our configuration is in the `[yapf]` section of `setup.cfg`. - -?> Tip- Many editors can use yapf as a plugin to automatically format code as you type. - -## Testing Details - -Our tests can be found in `lib/python/qmk/tests/`. You will find both unit and integration tests in this directory. We hope you will write both unit and integration tests for your code, but if you do not please favor integration tests. - -If your PR does not include a comprehensive set of tests please add comments like this to your code so that other people know where they can help: - - # TODO(unassigned/): Write tests - -We use [nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) to run our tests. You can refer to the nose2 documentation for more details on what you can do in your test functions. - -## Linting Details - -We use flake8 to lint our code. Your code should pass flake8 before you open a PR. This will be checked when you run `qmk pytest` and by CI when you submit a PR. diff --git a/docs/cli_tab_complete.md b/docs/cli_tab_complete.md deleted file mode 100644 index 90950b82da15..000000000000 --- a/docs/cli_tab_complete.md +++ /dev/null @@ -1,31 +0,0 @@ -# Tab Completion for QMK - -If you are using Bash 4.2 or later, Zsh, or FiSH you can enable Tab Completion for the QMK CLI. This will let you tab complete the names of flags, keyboards, files, and other `qmk` options. - -## Setup - -There are several ways you can setup tab completion. - -### For Your User Only - -Add this to the end of your `.profile` or `.bashrc`: - - source ~/qmk_firmware/util/qmk_tab_complete.sh - -If you put `qmk_firmware` into another location you will need to adjust this path. - -Zsh users will need to load `bashcompinit`. The following can be added to `~/.zshrc` file: - - autoload -Uz bashcompinit && bashcompinit - -### System Wide Symlink - -If you want the tab completion available to all users of the system you can add a symlink to the `qmk_tab_complete.sh` script: - - ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh - -### System Wide Copy - -In some cases a symlink may not work. Instead you can copy the file directly into place. Be aware that updates to the tab complete script may happen from time to time, you will want to recopy the file periodically. - - cp util/qmk_tab_complete.sh /etc/profile.d diff --git a/docs/coding_conventions_c.md b/docs/coding_conventions_c.md deleted file mode 100644 index 3f44da713d48..000000000000 --- a/docs/coding_conventions_c.md +++ /dev/null @@ -1,58 +0,0 @@ -# Coding Conventions (C) - -Most of our style is pretty easy to pick up on, but right now it's not entirely consistent. You should match the style of the code surrounding your change, but if that code is inconsistent or unclear use the following guidelines: - -* We indent using four (4) spaces (soft tabs) -* We use a modified One True Brace Style - * Opening Brace: At the end of the same line as the statement that opens the block - * Closing Brace: Lined up with the first character of the statement that opens the block - * Else If: Place the closing brace at the beginning of the line and the next opening brace at the end of the same line. - * Optional Braces: Always include optional braces. - * Good: if (condition) { return false; } - * Bad: if (condition) return false; -* We encourage use of C style comments: `/* */` - * Think of them as a story describing the feature - * Use them liberally to explain why particular decisions were made. - * Do not write obvious comments - * If you're not sure if a comment is obvious, go ahead and include it. -* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns. -* We use `#pragma once` at the start of header files rather than old-style include guards (`#ifndef THIS_FILE_H`, `#define THIS_FILE_H`, ..., `#endif`) -* We accept both forms of preprocessor if's: `#ifdef DEFINED` and `#if defined(DEFINED)` - * If you are not sure which to prefer use the `#if defined(DEFINED)` form. - * Do not change existing code from one style to the other, except when moving to a multiple condition `#if`. -* When deciding how (or if) to indent preprocessor directives, keep these points in mind: - * Readability is more important than consistency. - * Follow the file's existing style. If the file is mixed, follow the style that makes sense for the section you are modifying. - * When indenting, keep the hash at the start of the line and add whitespace between `#` and `if`, starting with 4 spaces after the `#`. - * You can follow the indentation level of the surrounding C code, or preprocessor directives can have their own indentation levels. Choose the style that best communicates the intent of your code. - -Here is an example for easy reference: - -```c -/* Enums for foo */ -enum foo_state { - FOO_BAR, - FOO_BAZ, -}; - -/* Returns a value */ -int foo(void) { - if (some_condition) { - return FOO_BAR; - } else { - return -1; - } -} -``` - -# Auto-formatting with clang-format - -[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) is part of LLVM and can automatically format your code for you, because ain't nobody got time to do it manually. We supply a configuration file for it that applies most of the coding conventions listed above. It will only change whitespace and newlines, so you will still have to remember to include optional braces yourself. - -Use the [full LLVM installer](https://llvm.org/builds/) to get clang-format on Windows, or use `sudo apt install clang-format` on Ubuntu. - -If you run it from the command-line, pass `-style=file` as an option and it will automatically find the .clang-format configuration file in the QMK root directory. - -If you use VSCode, the standard C/C++ plugin supports clang-format, alternatively there is a [separate extension](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat) for it. - -Some things (like LAYOUT macros) are destroyed by clang-format, so either don't run it on those files, or wrap the sensitive code in `// clang-format off` and `// clang-format on`. diff --git a/docs/coding_conventions_python.md b/docs/coding_conventions_python.md deleted file mode 100644 index 2b6870344873..000000000000 --- a/docs/coding_conventions_python.md +++ /dev/null @@ -1,326 +0,0 @@ -# Coding Conventions (Python) - -Most of our style follows PEP8 with some local modifications to make things less nit-picky. - -* We target Python 3.7 for compatibility with all supported platforms. -* We indent using four (4) spaces (soft tabs) -* We encourage liberal use of comments - * Think of them as a story describing the feature - * Use them liberally to explain why particular decisions were made. - * Do not write obvious comments - * If you're not sure if a comment is obvious, go ahead and include it. -* We require useful docstrings for all functions. -* In general we don't wrap lines, they can be as long as needed. If you do choose to wrap lines please do not wrap any wider than 76 columns. -* Some of our practices conflict with the wider python community to make our codebase more approachable to non-pythonistas. - -# YAPF - -You can use [yapf](https://github.com/google/yapf) to style your code. We provide a config in [setup.cfg](setup.cfg). - -# Imports - -We don't have a hard and fast rule for when to use `import ...` vs `from ... import ...`. Understandability and maintainability is our ultimate goal. - -Generally we prefer to import specific function and class names from a module to keep code shorter and easier to understand. Sometimes this results in a name that is ambiguous, and in such cases we prefer to import the module instead. You should avoid using the "as" keyword when importing, unless you are importing a compatibility module. - -Imports should be one line per module. We group import statements together using the standard python rules- system, 3rd party, local. - -Do not use `from foo import *`. Supply a list of objects you want to import instead, or import the whole module. - -## Import Examples - -Good: - -``` -from qmk import effects - -effects.echo() -``` - -Bad: - -``` -from qmk.effects import echo - -echo() # It's unclear where echo comes from -``` - -Good: - -``` -from qmk.keymap import compile_firmware - -compile_firmware() -``` - -OK, but the above is better: - -``` -import qmk.keymap - -qmk.keymap.compile_firmware() -``` - -# Statements - -One statement per line. - -Even when allowed (EG `if foo: bar`) we do not combine 2 statements onto a single line. - -# Naming - -`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`, `function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`, `function_parameter_name`, `local_var_name`. - -Function names, variable names, and filenames should be descriptive; eschew abbreviation. In particular, do not use abbreviations that are ambiguous or unfamiliar to readers outside your project, and do not abbreviate by deleting letters within a word. - -Always use a .py filename extension. Never use dashes. - -## Names to Avoid - -* single character names except for counters or iterators. You may use `e` as an exception identifier in try/except statements. -* dashes (`-`) in any package/module name -* `__double_leading_and_trailing_underscore__` names (reserved by Python) - -# Docstrings - -To maintain consistency with our docstrings we've set out the following guidelines. - -* Use markdown formatting -* Always use triple-dquote docstrings with at least one linebreak: `"""\n"""` -* First line is a short (< 70 char) description of what the function does -* If you need more in your docstring leave a blank line between the description and the rest. -* Start indented lines at the same indent level as the opening triple-dquote -* Document all function arguments using the format described below -* If present, Args:, Returns:, and Raises: should be the last three things in the docstring, separated by a blank line each. - -## Simple docstring example - -``` -def my_awesome_function(): - """Return the number of seconds since 1970 Jan 1 00:00 UTC. - """ - return int(time.time()) -``` - -## Complex docstring example - -``` -def my_awesome_function(): - """Return the number of seconds since 1970 Jan 1 00:00 UTC. - - This function always returns an integer number of seconds. - """ - return int(time.time()) -``` - -## Function arguments docstring example - -``` -def my_awesome_function(start=None, offset=0): - """Return the number of seconds since 1970 Jan 1 00:00 UTC. - - This function always returns an integer number of seconds. - - - Args: - start - The time to start at instead of 1970 Jan 1 00:00 UTC - - offset - Return an answer that has this number of seconds subtracted first - - Returns: - An integer describing a number of seconds. - - Raises: - ValueError - When `start` or `offset` are not positive numbers - """ - if start < 0 or offset < 0: - raise ValueError('start and offset must be positive numbers.') - - if not start: - start = time.time() - - return int(start - offset) -``` - -# Exceptions - -Exceptions are used to handle exceptional situations. They should not be used for flow control. This is a break from the python norm of "ask for forgiveness." If you are catching an exception it should be to handle a situation that is unusual. - -If you use a catch-all exception for any reason you must log the exception and stacktrace using cli.log. - -Make your try/except blocks as short as possible. If you need a lot of try statements you may need to restructure your code. - -# Tuples - -When defining one-item tuples always include a trailing comma so that it is obvious you are using a tuple. Do not rely on implicit one-item tuple unpacking. Better still use a list which is unambiguous. - -This is particularly important when using the printf-style format strings that are commonly used. - -# Lists and Dictionaries - -We have configured YAPF to differentiate between sequence styles with a trailing comma. When a trailing comma is omitted YAPF will format the sequence as a single line. When a trailing comma is included YAPF will format the sequence with one item per line. - -You should generally prefer to keep short definition on a single line. Break out to multiple lines sooner rather than later to aid readability and maintainability. - -# Parentheses - -Avoid excessive parentheses, but do use parentheses to make code easier to understand. Do not use them in return statements unless you are explicitly returning a tuple, or it is part of a math expression. - -# Format Strings - -We generally prefer printf-style format strings. Example: - -``` -name = 'World' -print('Hello, %s!' % (name,)) -``` - -This style is used by the logging module, which we make use of extensively, and we have adopted it in other places for consistency. It is also more familiar to C programmers, who are a big part of our casual audience. - -Our included CLI module has support for using these without using the percent (%) operator. Look at `cli.echo()` and the various `cli.log` functions (EG, `cli.log.info()`) for more details. - -# Comprehensions & Generator Expressions - -We encourage the liberal use of comprehensions and generators, but do not let them get too complex. If you need complexity fall back to a for loop that is easier to understand. - -# Lambdas - -OK to use but probably should be avoided. With comprehensions and generators the need for lambdas is not as strong as it once was. - -# Conditional Expressions - -OK in variable assignment, but otherwise should be avoided. - -Conditional expressions are if statements that are in line with code. For example: - -``` -x = 1 if cond else 2 -``` - -It's generally not a good idea to use these as function arguments, sequence items, etc. It's too easy to overlook. - -# Default Argument Values - -Encouraged, but values must be immutable objects. - -When specifying default values in argument lists always be careful to specify objects that can't be modified in place. If you use a mutable object the changes you make will persist between calls, which is usually not what you want. Even if that is what you intend to do it is confusing for others and will hinder understanding. - -Bad: - -``` -def my_func(foo={}): - pass -``` - -Good: - -``` -def my_func(foo=None): - if not foo: - foo = {} -``` - -# Properties - -Always use properties instead of getter and setter functions. - -``` -class Foo(object): - def __init__(self): - self._bar = None - - @property - def bar(self): - return self._bar - - @bar.setter - def bar(self, bar): - self._bar = bar -``` - -# True/False Evaluations - -You should generally prefer the implicit True/False evaluation in if statements, rather than checking equivalency. - -Bad: - -``` -if foo == True: - pass - -if bar == False: - pass -``` - -Good: - -``` -if foo: - pass - -if not bar: - pass -``` - -# Decorators - -Use when appropriate. Try to avoid too much magic unless it helps with understanding. - -# Threading and Multiprocessing - -Should be avoided. If you need this you will have to make a strong case before we merge your code. - -# Power Features - -Python is an extremely flexible language and gives you many fancy features such as custom metaclasses, access to bytecode, on-the-fly compilation, dynamic inheritance, object reparenting, import hacks, reflection, modification of system internals, etc. - -Don't use these. - -Performance is not a critical concern for us, and code understandability is. We want our codebase to be approachable by someone who only has a day or two to play with it. These features generally come with a cost to easy understanding, and we would prefer to have code that can be readily understood over faster or more compact code. - -Note that some standard library modules use these techniques and it is ok to make use of those modules. But please keep readability and understandability in mind when using them. - -# Type Annotated Code - -For now we are not using any type annotation system, and would prefer that code remain unannotated. We may revisit this in the future. - -# Function length - -Prefer small and focused functions. - -We recognize that long functions are sometimes appropriate, so no hard limit is placed on function length. If a function exceeds about 40 lines, think about whether it can be broken up without harming the structure of the program. - -Even if your long function works perfectly now, someone modifying it in a few months may add new behavior. This could result in bugs that are hard to find. Keeping your functions short and simple makes it easier for other people to read and modify your code. - -You could find long and complicated functions when working with some code. Do not be intimidated by modifying existing code: if working with such a function proves to be difficult, you find that errors are hard to debug, or you want to use a piece of it in several different contexts, consider breaking up the function into smaller and more manageable pieces. - -# FIXMEs - -It is OK to leave FIXMEs in code. Why? Encouraging people to at least document parts of code that need to be thought out more (or that are confusing) is better than leaving this code undocumented. - -All FIXMEs should be formatted like: - -``` -FIXME(username): Revisit this code when the frob feature is done. -``` - -...where username is your GitHub username. - -# Testing - -We use a combination of Integration and Unit testing to ensure that the our code is as bug-free as possible. All the tests can be found in `lib/python/qmk/tests/`. You can run all the tests with `qmk pytest`. - -At the time of this writing our tests are not very comprehensive. Looking at the current tests and writing new test cases for untested situations is a great way to both familiarize yourself with the codebase and contribute to QMK. - -## Integration Tests - -Integration tests can be found in `lib/python/qmk/tests/test_cli_commands.py`. This is where CLI commands are actually run and their overall behavior is verified. We use [`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) to launch each CLI command and a combination of checking output and returncode to determine if the right thing happened. - -## Unit Tests - -The other `test_*.py` files in `lib/python/qmk/tests/` contain unit tests. You can write tests for individual functions inside `lib/python/qmk/` here. Generally these files are named after the module, with dots replaced by underscores. - -At the time of this writing we do not do any mocking for our tests. If you would like to help us change this please [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and start a conversation there. diff --git a/docs/compatible_microcontrollers.md b/docs/compatible_microcontrollers.md deleted file mode 100644 index cc9c0b7f92a2..000000000000 --- a/docs/compatible_microcontrollers.md +++ /dev/null @@ -1,84 +0,0 @@ -# Compatible Microcontrollers - -QMK runs on any USB-capable AVR or ARM microcontroller with enough flash space - generally 32kB+ for AVR, and 64kB+ for ARM. With significant disabling of features, QMK may *just* squeeze into 16kB AVR MCUs. - -Features within QMK may or may not be compatible with every microcontroller. - -## Atmel AVR - -The following use [LUFA](https://www.fourwalledcubicle.com/LUFA.php) as the USB stack: - -* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) -* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) - * SparkFun Pro Micro (and clones) - * PJRC Teensy 2.0 - * Adafruit Feather 32U4 -* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) - * PJRC Teensy++ 2.0 -* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162) - -Certain MCUs which do not have native USB will use [V-USB](https://www.obdev.at/products/vusb/index.html) instead: - -* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) -* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) -* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328) - -## ARM - -You can also use any ARM chip with USB that [ChibiOS](https://www.chibios.org) supports. Most have plenty of flash. Known to work are: - -### STMicroelectronics (STM32) - - * [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html) - * [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html) - * Bluepill (with STM32duino bootloader) - * [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html) - * QMK Proton-C - * [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html) - * WeAct Blackpill - * [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html) - * [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html) - * [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html) - * WeAct Blackpill - * [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html) - * [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html) - * [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) - * [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L432](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) - * [STM32L442](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) - * [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) - -### WestBerryTech (WB32) - - * [WB32F3G71xx](http://www.westberrytech.com) - * [WB32FQ95xx](http://www.westberrytech.com) - -### NXP (Kinetis) - - * [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) - * PJRC Teensy LC - * [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50) - * [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72) - * PJRC Teensy 3.2 - * [MK64FX512](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k64-120-mhz-256-kb-sram-microcontrollers-mcus-based-on-arm-cortex-m4-core:K64_120) - * PJRC Teensy 3.5 - * [MK66FX1M0](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k6x-ethernet/kinetis-k66-180-mhz-dual-high-speed-full-speed-usbs-2mb-flash-microcontrollers-mcus-based-on-arm-cortex-m4-core:K66_180) - * PJRC Teensy 3.6 - -### Raspberry Pi - -* [RP2040](https://www.raspberrypi.com/documentation/microcontrollers/rp2040.html) - -For a detailed overview about the RP2040 support by QMK see the [dedicated RP2040 page](platformdev_rp2040.md). - -## Atmel ATSAM - -There is limited support for one of Atmel's ATSAM microcontrollers, that being the [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) used by the [Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop). However, it is not recommended to design a board with this microcontroller as the support is quite specialized to Massdrop hardware. - -## RISC-V - -### GigaDevice - -[ChibiOS-Contrib](https://github.com/ChibiOS/ChibiOS-Contrib) has support for the GigaDevice [GD32VF103 series](https://www.gigadevice.com/products/microcontrollers/gd32/risc-v/mainstream-line/gd32vf103-series/) microcontrollers and provides configurations for the [SiPeed Longan Nano](https://longan.sipeed.com/en/) development board that uses this microcontroller. It is largely pin and feature compatible with STM32F103 and STM32F303 microcontrollers. diff --git a/docs/config_options.md b/docs/config_options.md deleted file mode 100644 index 4698260118f3..000000000000 --- a/docs/config_options.md +++ /dev/null @@ -1,485 +0,0 @@ -# Configuring QMK - -QMK is nearly infinitely configurable. Wherever possible we err on the side of allowing users to customize their keyboard, even at the expense of code size. That level of flexibility makes for a daunting configuration experience, however. - -There are three main types of configuration files in QMK: - -* `config.h`, which contains various preprocessor directives (`#define`, `#ifdef`) -* `rules.mk`, which contains additional variables -* `info.json`, which is utilized for [data-driven configuration](https://docs.qmk.fm/#/data_driven_config) - -This page will only discuss the first two types, `config.h` and `rules.mk`. - -?> While not all settings have data-driven equivalents yet, keyboard makers are encouraged to utilize the `info.json` file to set the metadata for their boards when possible. See the [`info.json` Format](https://docs.qmk.fm/#/reference_info_json) page for more details. - -These files exist at various levels in QMK and all files of the same type are combined to build the final configuration. The levels, from lowest priority to highest priority, are: - -* QMK Default -* Keyboard -* Folders (Up to 5 levels deep) -* Keymap - -## QMK Default - -Every available setting in QMK has a default. If that setting is not set at the Keyboard, Folder, or Keymap level this is the setting that will be used. - -## Keyboard - -This level contains config options that should apply to the whole keyboard. Some settings won't change in revisions, or most keymaps. Other settings are merely defaults for this keyboard and can be overridden by folders and/or keymaps. - -## Folders - -Some keyboards have folders and sub-folders to allow for different hardware configurations. Most keyboards only go 1 folder deep, but QMK supports structures up to 5 folders deep. Each folder can have its own `config.h` and `rules.mk` files that are incorporated into the final configuration. - -## Keymap - -This level contains all of the options for that particular keymap. If you wish to override a previous declaration, you can use `#undef ` to undefine it, where you can then redefine it without an error. - -# The `config.h` File - -This is a C header file that is one of the first things included, and will persist over the whole project (if included). Lots of variables can be set here and accessed elsewhere. The `config.h` file shouldn't be including other `config.h` files. - -## Hardware Options -* `#define VENDOR_ID 0x1234` - * defines your VID, and for most DIY projects, can be whatever you want -* `#define PRODUCT_ID 0x5678` - * defines your PID, and for most DIY projects, can be whatever you want -* `#define DEVICE_VER 0x0100` - * defines the device version (often used for revisions) -* `#define MANUFACTURER "Me"` - * generally who/whatever brand produced the board -* `#define PRODUCT "Board"` - * the name of the keyboard -* `#define MATRIX_ROWS 5` - * the number of rows in your keyboard's matrix -* `#define MATRIX_COLS 15` - * the number of columns in your keyboard's matrix -* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }` - * pins of the rows, from top to bottom - * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information. -* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }` - * pins of the columns, from left to right - * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information. -* `#define MATRIX_IO_DELAY 30` - * the delay in microseconds when between changing matrix pin state and reading values -* `#define MATRIX_HAS_GHOST` - * define is matrix has ghost (unlikely) -* `#define MATRIX_UNSELECT_DRIVE_HIGH` - * On un-select of matrix pins, rather than setting pins to input-high, sets them to output-high. -* `#define DIODE_DIRECTION COL2ROW` - * COL2ROW or ROW2COL - how your matrix is configured. COL2ROW means the black mark on your diode is facing to the rows, and between the switch and the rows. -* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` - * pins mapped to rows and columns, from left to right. Defines a matrix where each switch is connected to a separate pin and ground. -* `#define AUDIO_VOICES` - * turns on the alternate audio voices (to cycle through) -* `#define C4_AUDIO` - * enables audio on pin C4 - * Deprecated. Use `#define AUDIO_PIN C4` -* `#define C5_AUDIO` - * enables audio on pin C5 - * Deprecated. Use `#define AUDIO_PIN C5` -* `#define C6_AUDIO` - * enables audio on pin C6 - * Deprecated. Use `#define AUDIO_PIN C6` -* `#define B5_AUDIO` - * enables audio on pin B5 (duophony is enabled if one of B pins is enabled along with one of C pins) - * Deprecated. Use `#define AUDIO_PIN B5`, or use `#define AUDIO_PIN_ALT B5` if a `C` pin is enabled with `AUDIO_PIN` -* `#define B6_AUDIO` - * enables audio on pin B6 (duophony is enabled if one of B pins is enabled along with one of C pins) - * Deprecated. Use `#define AUDIO_PIN B6`, or use `#define AUDIO_PIN_ALT B6` if a `C` pin is enabled with `AUDIO_PIN` -* `#define B7_AUDIO` - * enables audio on pin B7 (duophony is enabled if one of B pins is enabled along with one of C pins) - * Deprecated. Use `#define AUDIO_PIN B7`, or use `#define AUDIO_PIN_ALT B7` if a `C` pin is enabled with `AUDIO_PIN` -* `#define BACKLIGHT_PIN B7` - * pin of the backlight -* `#define BACKLIGHT_LEVELS 3` - * number of levels your backlight will have (maximum 31 excluding off) -* `#define BACKLIGHT_BREATHING` - * enables backlight breathing -* `#define BREATHING_PERIOD 6` - * the length of one backlight "breath" in seconds -* `#define DEBOUNCE 5` - * the delay when reading the value of the pin (5 is default) -* `#define LOCKING_SUPPORT_ENABLE` - * mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap -* `#define LOCKING_RESYNC_ENABLE` - * tries to keep switch state consistent with keyboard LED state -* `#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)` - * key combination that allows the use of magic commands (useful for debugging) -* `#define USB_MAX_POWER_CONSUMPTION 500` - * sets the maximum power (in mA) over USB for the device (default: 500) -* `#define USB_POLLING_INTERVAL_MS 10` - * sets the USB polling rate in milliseconds for the keyboard, mouse, and shared (NKRO/media keys) interfaces -* `#define USB_SUSPEND_WAKEUP_DELAY 0` - * sets the number of milliseconds to pause after sending a wakeup packet. - Disabled by default, you might want to set this to 200 (or higher) if the - keyboard does not wake up properly after suspending. -* `#define F_SCL 100000L` - * sets the I2C clock rate speed for keyboards using I2C. The default is `400000L`, except for keyboards using `split_common`, where the default is `100000L`. - -## Features That Can Be Disabled - -If you define these options you will disable the associated feature, which can save on code size. - -* `#define NO_DEBUG` - * disable debugging -* `#define NO_PRINT` - * disable printing/debugging using hid_listen -* `#define NO_ACTION_LAYER` - * disable layers -* `#define NO_ACTION_TAPPING` - * disable tap dance and other tapping features -* `#define NO_ACTION_ONESHOT` - * disable one-shot modifiers - -## Features That Can Be Enabled - -If you define these options you will enable the associated feature, which may increase your code size. - -* `#define ENABLE_COMPILE_KEYCODE` - * Enables the `QK_MAKE` keycode -* `#define FORCE_NKRO` - * NKRO by default requires to be turned on, this forces it on during keyboard startup regardless of EEPROM setting. NKRO can still be turned off but will be turned on again if the keyboard reboots. -* `#define STRICT_LAYER_RELEASE` - * force a key release to be evaluated using the current layer stack instead of remembering which layer it came from (used for advanced cases) - -## Behaviors That Can Be Configured - -* `#define TAPPING_TERM 200` - * how long before a key press becomes a hold -* `#define TAPPING_TERM_PER_KEY` - * enables handling for per key `TAPPING_TERM` settings -* `#define RETRO_TAPPING` - * tap anyway, even after `TAPPING_TERM`, if there was no other key interruption between press and release - * See [Retro Tapping](tap_hold.md#retro-tapping) for details -* `#define RETRO_TAPPING_PER_KEY` - * enables handling for per key `RETRO_TAPPING` settings -* `#define TAPPING_TOGGLE 2` - * how many taps before triggering the toggle -* `#define PERMISSIVE_HOLD` - * makes tap and hold keys trigger the hold if another key is pressed before releasing, even if it hasn't hit the `TAPPING_TERM` - * See [Permissive Hold](tap_hold.md#permissive-hold) for details -* `#define PERMISSIVE_HOLD_PER_KEY` - * enabled handling for per key `PERMISSIVE_HOLD` settings -* `#define QUICK_TAP_TERM 100` - * tap-then-hold timing to use a dual role key to repeat keycode - * See [Quick Tap Term](tap_hold.md#quick-tap-term) - * Changes the timing of Tap Toggle functionality (`TT` or the One Shot Tap Toggle) - * Defaults to `TAPPING_TERM` if not defined -* `#define QUICK_TAP_TERM_PER_KEY` - * enables handling for per key `QUICK_TAP_TERM` settings -* `#define HOLD_ON_OTHER_KEY_PRESS` - * selects the hold action of a dual-role key as soon as the tap of the dual-role key is interrupted by the press of another key. - * See "[hold on other key press](tap_hold.md#hold-on-other-key-press)" for details -* `#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY` - * enables handling for per key `HOLD_ON_OTHER_KEY_PRESS` settings -* `#define LEADER_TIMEOUT 300` - * how long before the leader key times out - * If you're having issues finishing the sequence before it times out, you may need to increase the timeout setting. Or you may want to enable the `LEADER_PER_KEY_TIMING` option, which resets the timeout after each key is tapped. -* `#define LEADER_PER_KEY_TIMING` - * sets the timer for leader key chords to run on each key press rather than overall -* `#define LEADER_KEY_STRICT_KEY_PROCESSING` - * Disables keycode filtering for Mod-Tap and Layer-Tap keycodes. Eg, if you enable this, you would need to specify `MT(MOD_CTL, KC_A)` if you want to use `KC_A`. -* `#define MOUSE_EXTENDED_REPORT` - * Enables support for extended reports (-32767 to 32767, instead of -127 to 127), which may allow for smoother reporting, and prevent maxing out of the reports. Applies to both Pointing Device and Mousekeys. -* `#define ONESHOT_TIMEOUT 300` - * how long before oneshot times out -* `#define ONESHOT_TAP_TOGGLE 2` - * how many taps before oneshot toggle is triggered -* `#define COMBO_TERM 200` - * how long for the Combo keys to be detected. Defaults to `TAPPING_TERM` if not defined. -* `#define COMBO_MUST_HOLD_MODS` - * Flag for enabling extending timeout on Combos containing modifiers -* `#define COMBO_MOD_TERM 200` - * Allows for extending COMBO_TERM for mod keys while mid-combo. -* `#define COMBO_MUST_HOLD_PER_COMBO` - * Flag to enable per-combo COMBO_TERM extension and `get_combo_must_hold()` function -* `#define COMBO_TERM_PER_COMBO` - * Flag to enable per-combo COMBO_TERM extension and `get_combo_term()` function -* `#define COMBO_STRICT_TIMER` - * Only start the combo timer on the first key press instead of on all key presses. -* `#define COMBO_NO_TIMER` - * Disable the combo timer completely for relaxed combos. -* `#define TAP_CODE_DELAY 100` - * Sets the delay between `register_code` and `unregister_code`, if you're having issues with it registering properly (common on VUSB boards). The value is in milliseconds and defaults to `0`. -* `#define TAP_HOLD_CAPS_DELAY 80` - * Sets the delay for Tap Hold keys (`LT`, `MT`) when using `KC_CAPS_LOCK` keycode, as this has some special handling on MacOS. The value is in milliseconds, and defaults to 80 ms if not defined. For macOS, you may want to set this to 200 or higher. -* `#define KEY_OVERRIDE_REPEAT_DELAY 500` - * Sets the key repeat interval for [key overrides](feature_key_overrides.md). -* `#define LEGACY_MAGIC_HANDLING` - * Enables magic configuration handling for advanced keycodes (such as Mod Tap and Layer Tap) - - -## RGB Light Configuration - -* `#define WS2812_DI_PIN D7` - * pin the DI on the WS2812 is hooked-up to -* `#define RGBLIGHT_LAYERS` - * Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state. -* `#define RGBLIGHT_MAX_LAYERS` - * Defaults to 8. Can be expanded up to 32 if more [lighting layers](feature_rgblight.md?id=lighting-layers) are needed. - * Note: Increasing the maximum will increase the firmware size and slow sync on split keyboards. -* `#define RGBLIGHT_LAYER_BLINK` - * Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action). -* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` - * If defined, then [lighting layers](feature_rgblight?id=overriding-rgb-lighting-onoff-status) will be shown even if RGB Light is off. -* `#define RGBLED_NUM 12` - * number of LEDs -* `#define RGBLIGHT_SPLIT` - * Needed if both halves of the board have RGB LEDs wired directly to the RGB output pin on the controllers instead of passing the output of the left half to the input of the right half -* `#define RGBLED_SPLIT { 6, 6 }` - * number of LEDs connected that are directly wired to the RGB pin on each half of a split keyboard - * First value indicates number of LEDs for left half, second value is for the right half - * When RGBLED_SPLIT is defined, RGBLIGHT_SPLIT is implicitly defined. -* `#define RGBLIGHT_HUE_STEP 12` - * units to step when in/decreasing hue -* `#define RGBLIGHT_SAT_STEP 25` - * units to step when in/decreasing saturation -* `#define RGBLIGHT_VAL_STEP 12` - * units to step when in/decreasing value (brightness) -* `#define RGBW` - * Enables RGBW LED support - -## Mouse Key Options - -* `#define MOUSEKEY_INTERVAL 20` -* `#define MOUSEKEY_DELAY 0` -* `#define MOUSEKEY_TIME_TO_MAX 60` -* `#define MOUSEKEY_MAX_SPEED 7` -* `#define MOUSEKEY_WHEEL_DELAY 0` - -## Split Keyboard Options - -Split Keyboard specific options, make sure you have 'SPLIT_KEYBOARD = yes' in your rules.mk - -* `SPLIT_TRANSPORT = custom` - * Allows replacing the standard split communication routines with a custom one. ARM based split keyboards must use this at present. - -### Setting Handedness - -One thing to remember, the side that the USB port is plugged into is always the master half. The side not plugged into USB is the slave. - -There are a few different ways to set handedness for split keyboards (listed in order of precedence): - -1. Set `SPLIT_HAND_PIN`: Reads a pin to determine handedness. If pin is high, it's the left side, if low, the half is determined to be the right side -2. Set `EE_HANDS` and flash `eeprom-lefthand.eep`/`eeprom-righthand.eep` to each half - * For boards with DFU bootloader you can use `:dfu-split-left`/`:dfu-split-right` to flash these EEPROM files - * For boards with Caterina bootloader (like stock Pro Micros), use `:avrdude-split-left`/`:avrdude-split-right` - * For boards with ARM DFU bootloader (like Proton C), use `:dfu-util-split-left`/`:dfu-util-split-right` -3. Set `MASTER_RIGHT`: Half that is plugged into the USB port is determined to be the master and right half (inverse of the default) -4. Default: The side that is plugged into the USB port is the master half and is assumed to be the left half. The slave side is the right half - -#### Defines for handedness - -* `#define SPLIT_HAND_PIN B7` - * For using high/low pin to determine handedness, low = right hand, high = left hand. Replace `B7` with the pin you are using. This is optional, and if you leave `SPLIT_HAND_PIN` undefined, then you can still use the EE_HANDS method or MASTER_LEFT / MASTER_RIGHT defines like the stock Let's Split uses. - -* `#define SPLIT_HAND_MATRIX_GRID ,` - * The handedness is determined by using the intersection of the keyswitches in the key matrix, which does not exist. Normally, when this intersection is shorted (level low), it is considered left. If you define `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT`, it is determined to be right when the level is low. - -* `#define EE_HANDS` (only works if `SPLIT_HAND_PIN` and `SPLIT_HAND_MATRIX_GRID` are not defined) - * Reads the handedness value stored in the EEPROM after `eeprom-lefthand.eep`/`eeprom-righthand.eep` has been flashed to their respective halves. - -* `#define MASTER_RIGHT` - * Master half is defined to be the right half. - -### Other Options - -* `#define USE_I2C` - * For using I2C instead of Serial (default is serial; serial transport is supported on ARM -- I2C is AVR-only) - -* `#define SOFT_SERIAL_PIN D0` - * When using serial, define this. `D0` or `D1`,`D2`,`D3`,`E6`. - -* `#define MATRIX_ROW_PINS_RIGHT { }` -* `#define MATRIX_COL_PINS_RIGHT { }` - * If you want to specify a different pinout for the right half than the left half, you can define `MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT`. Currently, the size of `MATRIX_ROW_PINS` must be the same as `MATRIX_ROW_PINS_RIGHT` and likewise for the definition of columns. - * may be omitted by the keyboard designer if matrix reads are handled in an alternate manner. See [low-level matrix overrides](custom_quantum_functions.md?id=low-level-matrix-overrides) for more information. - -* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` - * If you want to specify a different direct pinout for the right half than the left half, you can define `DIRECT_PINS_RIGHT`. Currently, the size of `DIRECT_PINS` must be the same as `DIRECT_PINS_RIGHT`. - -* `#define RGBLED_SPLIT { 6, 6 }` - * See [RGB Light Configuration](#rgb-light-configuration) - -* `#define SELECT_SOFT_SERIAL_SPEED ` (default speed is 1) - * Sets the protocol speed when using serial communication - * Speeds: - * 0: about 189kbps (Experimental only) - * 1: about 137kbps (default) - * 2: about 75kbps - * 3: about 39kbps - * 4: about 26kbps - * 5: about 20kbps - -* `#define SPLIT_USB_DETECT` - * Detect (with timeout) USB connection when delegating master/slave - * Default behavior for ARM - * Required for AVR Teensy (without hardware mods) - -* `#define SPLIT_USB_TIMEOUT 2000` - * Maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT` - -* `#define SPLIT_USB_TIMEOUT_POLL 10` - * Poll frequency when detecting master/slave when using `SPLIT_USB_DETECT` - -* `#define SPLIT_WATCHDOG_ENABLE` - * Reboot slave if no communication from master within timeout. - * Helps resolve issue where both sides detect as slave using `SPLIT_USB_DETECT` - -* `#define SPLIT_WATCHDOG_TIMEOUT 3000` - * Maximum slave timeout when waiting for communication from master when using `SPLIT_WATCHDOG_ENABLE` - -* `#define FORCED_SYNC_THROTTLE_MS 100` - * Deadline for synchronizing data from master to slave when using the QMK-provided split transport. - -* `#define SPLIT_TRANSPORT_MIRROR` - * Mirrors the master-side matrix on the slave when using the QMK-provided split transport. - -* `#define SPLIT_LAYER_STATE_ENABLE` - * Ensures the current layer state is available on the slave when using the QMK-provided split transport. - -* `#define SPLIT_LED_STATE_ENABLE` - * Ensures the current host indicator state (caps/num/scroll) is available on the slave when using the QMK-provided split transport. - -* `#define SPLIT_MODS_ENABLE` - * Ensures the current modifier state (normal, weak, and oneshot) is available on the slave when using the QMK-provided split transport. - -* `#define SPLIT_WPM_ENABLE` - * Ensures the current WPM is available on the slave when using the QMK-provided split transport. - -* `#define SPLIT_OLED_ENABLE` - * Syncs the on/off state of the OLED between the halves. - -* `#define SPLIT_ST7565_ENABLE` - * Syncs the on/off state of the ST7565 screen between the halves. - -* `#define SPLIT_TRANSACTION_IDS_KB .....` -* `#define SPLIT_TRANSACTION_IDS_USER .....` - * Allows for custom data sync with the slave when using the QMK-provided split transport. See [custom data sync between sides](feature_split_keyboard.md#custom-data-sync) for more information. - -# The `rules.mk` File - -This is a [make](https://www.gnu.org/software/make/manual/make.html) file that is included by the top-level `Makefile`. It is used to set some information about the MCU that we will be compiling for as well as enabling and disabling certain features. - -## Build Options - -* `DEFAULT_FOLDER` - * Used to specify a default folder when a keyboard has more than one sub-folder. -* `FIRMWARE_FORMAT` - * Defines which format (bin, hex) is copied to the root `qmk_firmware` folder after building. -* `SRC` - * Used to add files to the compilation/linking list. -* `LIB_SRC` - * Used to add files as a library to the compilation/linking list. - The files specified by `LIB_SRC` is linked after the files specified by `SRC`. - For example, if you specify: - ``` - SRC += a.c - LIB_SRC += lib_b.c - SRC += c.c - LIB_SRC += lib_d.c - ``` - The link order is as follows. - ``` - ... a.o c.o ... lib_b.a lib_d.a ... - ``` -* `LAYOUTS` - * A list of [layouts](feature_layouts.md) this keyboard supports. -* `LTO_ENABLE` - * Enables Link Time Optimization (LTO) when compiling the keyboard. This makes the process take longer, but it can significantly reduce the compiled size (and since the firmware is small, the added time is not noticeable). - -## AVR MCU Options -* `MCU = atmega32u4` -* `F_CPU = 16000000` -* `ARCH = AVR8` -* `F_USB = $(F_CPU)` -* `OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT` -* `BOOTLOADER = atmel-dfu` with the following options: - * `atmel-dfu` - * `lufa-dfu` - * `qmk-dfu` - * `halfkay` - * `caterina` - * `bootloadhid` - * `usbasploader` - -## Feature Options :id=feature-options - -Use these to enable or disable building certain features. The more you have enabled the bigger your firmware will be, and you run the risk of building a firmware too large for your MCU. - -* `MAGIC_ENABLE` - * MAGIC actions (BOOTMAGIC without the boot) -* `BOOTMAGIC_ENABLE` - * Enable Bootmagic Lite -* `MOUSEKEY_ENABLE` - * Mouse keys -* `EXTRAKEY_ENABLE` - * Audio control and System control -* `CONSOLE_ENABLE` - * Console for debug -* `COMMAND_ENABLE` - * Commands for debug and configuration -* `COMBO_ENABLE` - * Key combo feature -* `NKRO_ENABLE` - * USB N-Key Rollover - if this doesn't work, see here: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -* `RING_BUFFERED_6KRO_REPORT_ENABLE` - * USB 6-Key Rollover - Instead of stopping any new input once 6 keys are pressed, the oldest key is released and the new key is pressed. -* `AUDIO_ENABLE` - * Enable the audio subsystem. -* `KEY_OVERRIDE_ENABLE` - * Enable the key override feature -* `RGBLIGHT_ENABLE` - * Enable keyboard underlight functionality -* `LEADER_ENABLE` - * Enable leader key chording -* `MIDI_ENABLE` - * MIDI controls -* `UNICODE_ENABLE` - * Unicode -* `BLUETOOTH_ENABLE` - * Current options are BluefruitLE, RN42 -* `SPLIT_KEYBOARD` - * Enables split keyboard support (dual MCU like the let's split and bakingpy's boards) and includes all necessary files located at quantum/split_common -* `CUSTOM_MATRIX` - * Allows replacing the standard matrix scanning routine with a custom one. -* `DEBOUNCE_TYPE` - * Allows replacing the standard key debouncing routine with an alternative or custom one. -* `WAIT_FOR_USB` - * Forces the keyboard to wait for a USB connection to be established before it starts up -* `NO_USB_STARTUP_CHECK` - * Disables usb suspend check after keyboard startup. Usually the keyboard waits for the host to wake it up before any tasks are performed. This is useful for split keyboards as one half will not get a wakeup call but must send commands to the master. -* `DEFERRED_EXEC_ENABLE` - * Enables deferred executor support -- timed delays before callbacks are invoked. See [deferred execution](custom_quantum_functions.md#deferred-execution) for more information. -* `DYNAMIC_TAPPING_TERM_ENABLE` - * Allows to configure the global tapping term on the fly. - -## USB Endpoint Limitations - -In order to provide services over USB, QMK has to use USB endpoints. -These are a finite resource: each microcontroller has only a certain number. -This limits what features can be enabled together. -If the available endpoints are exceeded, a build error is thrown. - -The following features can require separate endpoints: - -* `MOUSEKEY_ENABLE` -* `EXTRAKEY_ENABLE` -* `CONSOLE_ENABLE` -* `NKRO_ENABLE` -* `MIDI_ENABLE` -* `RAW_ENABLE` -* `VIRTSER_ENABLE` - -In order to improve utilisation of the endpoints, the HID features can be combined to use a single endpoint. -By default, `MOUSEKEY`, `EXTRAKEY`, and `NKRO` are combined into a single endpoint. - -The base keyboard functionality can also be combined into the endpoint, -by setting `KEYBOARD_SHARED_EP = yes`. -This frees up one more endpoint, -but it can prevent the keyboard working in some BIOSes, -as they do not implement Boot Keyboard protocol switching. - -Combining the mouse also breaks Boot Mouse compatibility. -The mouse can be uncombined by setting `MOUSE_SHARED_EP = no` if this functionality is required. diff --git a/docs/configurator_architecture.md b/docs/configurator_architecture.md deleted file mode 100644 index 0d7fc8a73b4f..000000000000 --- a/docs/configurator_architecture.md +++ /dev/null @@ -1,61 +0,0 @@ -# QMK Configurator Architecture - -This page describes the web architecture behind QMK Configurator at a high level. If you are interested in the architecture of the QMK Configurator code itself you should start at the [qmk_configurator](https://github.com/qmk/qmk_configurator) repository. - -# Overview - -![QMK Configurator Architecture Diagram](configurator_diagram.svg) - -# Detailed Description - -QMK Configurator is a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) that allows users to create custom keymaps for their QMK-compatible keyboard. They can export JSON representation of their keymaps and compile firmware binaries that can be flashed to their keyboard using a tool like [QMK Toolbox](https://github.com/qmk/qmk_toolbox). - -Configurator gets metadata about keyboards from the Keyboard Metadata store and submits compile requests to the QMK API. The results of those compile requests will be made available on [Digital Ocean Spaces](https://www.digitalocean.com/products/spaces/), an S3-compatible data store. - -## Configurator Frontend - -Address: - -The [Configurator Frontend](https://config.qmk.fm) is compiled into a set of static files that are served by Github Pages. This action happens every time a commit is pushed to the [qmk_configurator `master`](https://github.com/qmk/qmk_configurator) branch. You can view the status of these jobs on the [qmk_configurator actions tab](https://github.com/qmk/qmk_configurator/actions/workflows/build.yml). - -## Keyboard Metadata - -Address: - -The Keyboard Metadata is generated every time a keyboard in [qmk_firmware](https://github.com/qmk/qmk_firmware) changes. The resulting JSON files are uploaded to Spaces and used by Configurator to generate UI for each keyboard. You can view the status of this job on the [qmk_firmware actions tab](https://github.com/qmk/qmk_firmware/actions/workflows/api.yml). If you are a QMK Collaborator you can manually run this job using the `workflow_dispatch` event trigger. - -## QMK API - -Address: - -The QMK API accepts `keymap.json` files for compilation. These are the same files you can use directly with `qmk compile` and `qmk flash`. When a `keymap.json` is submitted the browser will poll the status of the job periodically (every 2 seconds or longer, preferably) until the job has completed. The final status JSON will contain pointers to source and binary downloads for the keymap. - -QMK API always presents the source and binary downloads side-by-side to comply with the GPL. - -There are 3 non-error status responses from the API- - -1. Compile Job Queued -2. Compile Job Running -3. Compile Job Finished - -### Compile Job Queued - -This status indicates that the job has not yet been picked up by a [QMK Compiler](#qmk-compiler) node. Configurator shows this status as "Waiting for an oven". - -### Compile Job Running - -This status indicates that the job has started compiling. Configurator shows this status as "Baking". - -### Compile Job Finished - -This status indicates that the job has completed. There will be keys in the status JSON for source and binary downloads. - -## Redis/RQ - -QMK API uses RQ to distribute jobs to the available [QMK Compiler](#qmk-compiler) nodes. When a `keymap.json` is received it's put into the RQ queue, where a `qmk_compiler` node will pick it up from. - -## QMK Compiler - -[QMK Compiler](https://github.com/qmk/qmk_compiler) is what actually performs the compilation of the `keymap.json`. It does so by checking out the requested `qmk_firmware` branch, running `qmk compile keymap.json`, and then uploading the resulting source and binary to Digital Ocean Spaces. - -When users download their source/binary, API will redirect them to the authenticated Spaces download URL. diff --git a/docs/configurator_default_keymaps.md b/docs/configurator_default_keymaps.md deleted file mode 100644 index 4d3c1b8f47c1..000000000000 --- a/docs/configurator_default_keymaps.md +++ /dev/null @@ -1,191 +0,0 @@ -# Adding Default Keymaps to QMK Configurator :id=adding-default-keymaps - -This page covers how to add a default keymap for a keyboard to QMK Configurator. - - -## Technical Information :id=technical-information - -QMK Configurator uses JSON as its native file format for keymaps. As much as possible, these should be kept such that they behave the same as running `make :default` from `qmk_firmware`. - -Keymaps in this directory require four key-value pairs: - -* `keyboard` (string) - * This is the name of the keyboard, the same as would be used when running a compile job through `make` (e.g. `make 1upkeyboards/1up60rgb:default`). -* `keymap` (string) - * Should be set to `default`. -* `layout` (string) - * This is the layout macro used by the default keymap. -* `layers` (array) - * The keymap itself. This key should contain one array per layer, which themselves should contain the keycodes that make up that layer. - -Additionally, most keymaps contain a `commit` key. This key is not consumed by the API that back-stops QMK Configurator, but is used by Configurator's maintainers to tell which version of a keymap was used to create the JSON keymap in this repository. The value is the SHA of the last commit to modify a board's default `keymap.c` in the `qmk_firmware` repository. The SHA is found by checking out [the `master` branch of the `qmk/qmk_firmware` repository](https://github.com/qmk/qmk_firmware/tree/master/) and running `git log -1 --pretty=oneline -- keyboards//keymaps/default/keymap.c` (use `keymap.json` if the keyboard in question has this file instead), which should return something similar to: - -``` -f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from default keymaps (#5625) -``` - -In this example, `f14629ed1cd7c7ec9089604d64f29a99981558e8` is the value that should be used for `commit`. - - -## Example :id=example - -If one wished to add a default keymap for the H87a by Hineybush, one would run the `git log` command above against the H87a's default keymap in `qmk_firmware`: - -``` -user ~/qmk_firmware (master) -$ git log -1 --pretty=oneline master -- keyboards/hineybush/h87a/keymaps/default/keymap.c -ef8878fba5d3786e3f9c66436da63a560cd36ac9 Hineybush h87a lock indicators (#8237) -``` - -Now that we have the commit hash, we need the keymap (edited for readability): - -```c -... -#include QMK_KEYBOARD_H - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - - [0] = LAYOUT_all( - KC_ESC, 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_PSCR, KC_SCRL, KC_PAUS, - KC_GRV, 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_INS, KC_HOME, KC_PGUP, - 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_END, KC_PGDN, - 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_NUHS, KC_ENT, - KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_TRNS, KC_UP, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), - - [1] = LAYOUT_all( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DOWN, BL_UP, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), - -}; -``` - -The default keymap uses the `LAYOUT_all` macro, so that will be the value of the `layout` key. Compiled to a QMK Configurator JSON keymap, our resulting file should be: - -```json -{ - "keyboard": "hineybush/h87a", - "keymap": "default", - "commit": "ef8878fba5d3786e3f9c66436da63a560cd36ac9", - "layout": "LAYOUT_all", - "layers": [ - [ - "KC_ESC", "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_PSCR", "KC_SCRL", "KC_PAUS", - "KC_GRV", "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_INS", "KC_HOME", "KC_PGUP", - "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_END", "KC_PGDN", - "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_NUHS", "KC_ENT", - "KC_LSFT", "KC_NUBS", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", "KC_RSFT", "KC_TRNS", "KC_UP", - "KC_LCTL", "KC_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "MO(1)", "KC_RGUI", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RGHT" - ], - [ - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DOWN", "BL_UP", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "QK_BOOT", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS" - ] - ] -} -``` - -The white space in the `layers` arrays have no effect on the functionality of the keymap, but are used to make these files easier for humans to read. - - -## Caveats :id=caveats - -### Layers can only be referenced by number :id=layer-references - -A common QMK convention is to name layers using a series of `#define`s, or an `enum` statement: - -```c -enum layer_names { - _BASE, - _MEDIA, - _FN -}; -``` - -This works in C, but for Configurator, you *must* use the layer's numeric index – `MO(_FN)` would need to be `MO(2)` in the above example. - -### No support for custom code of any kind :id=custom-code - -Features that require adding functions to the keymap.c file, such as Tap Dance or Unicode, can not be compiled in Configurator **at all**. Even setting `TAP_DANCE_ENABLE = yes` in the `qmk_firmware` repository at the keyboard level will prevent Configurator from compiling **any** firmware for that keyboard. This is limited both by the API and the current spec of our JSON keymap format. - -### Limited Support for Custom keycodes :id=custom-keycodes - -There is a way to support custom keycodes: if the logic for a custom keycode is implemented at the keyboard level instead of the keymap level in qmk_firmware, that keycode *can* be used in Configurator and it *will* compile and work. Instead of using the following in your `keymap.c`: - -```c -enum custom_keycodes { - CUSTOM_1 = SAFE_RANGE, - CUSTOM_2, - CUSTOM_3 -}; -... -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case CUSTOM_1: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #1."); - } - return false; - case CUSTOM_2: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #2."); - } - return false; - case CUSTOM_3: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #3."); - } - return false; - } - return true; -}; -``` - -... add the keycode `enum` block to your keyboard's header file (`.h`) as follows (note that the `enum` is named `keyboard_keycodes` here): - -```c -enum keyboard_keycodes { - CUSTOM_1 = QK_KB_0, - CUSTOM_2, - CUSTOM_3, -}; -``` - -... then the logic to your `.c` through `process_record_kb()`: - -```c -bool process_record_kb(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case CUSTOM_1: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #1."); - } - return false; - case CUSTOM_2: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #2."); - } - return false; - case CUSTOM_3: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #3."); - } - return false; - } - return process_record_user(keycode, record); -}; -``` - -Note the call to `process_record_user()` at the end. - -## Additional Reading :id=additional-reading - -For QMK Configurator to support your keyboard, your keyboard must be present in the `master` branch of the `qmk_firmware` repository. For instructions on this, please see [Supporting Your Keyboard in QMK Configurator](reference_configurator_support.md). diff --git a/docs/configurator_diagram.drawio b/docs/configurator_diagram.drawio deleted file mode 100644 index 091a3a76b8c3..000000000000 --- a/docs/configurator_diagram.drawio +++ /dev/null @@ -1 +0,0 @@ -5VvbcqM4EP2a1O4+hOLqy2Ni5zKX1CTxzszOU0oG2dZEIBZEYu/XbwuEDQg7csZ2vFlXjQca0RLdR+eohXPiDML5VYLi2Q0LMD2xzWB+4gxPbNvqezb8JywLaTFtr7BMExJI28owIv/gsqG0ZiTAaa0hZ4xyEteNPosi7POaDSUJe643mzBa7zVGU6wYRj6iqvU7CfissPY8c2W/xmQ6K3u2THklRGVjaUhnKGDPFZNzceIMEsZ4cRTOB5iK6JVxKe67XHN1ObAER1znhgfT76Zzxxp3Z49j5+7zjw/z+NSS+XlCNJNPLEfLF2UIcAARkacs4TM2ZRGiFyvrecKyKMCiHxPOVm0+MxaD0QLjT8z5QqYXZZyBacZDKq/iKDgTyYLTiEW4sFwSSqXLAKWz3L9orD64jEXKssTHG57WlQBCyRTzTVGRDsWTV3qQcb3CLMQ8WUCDBFPEyVMdK0hCbrpst8oKHMjEbJEk9+UckTDHcTWm0jQk4RR6pWQM3z4l8QNKuDhkYZxxnKRw/J0ljymHJ2HRg2X35vDPiKPp2kA/4YTj+cbIyKunjmv0zMpHeljSQXH6XJla0jSrzKrStvPIei9Hdgm9HNoZpyTCgyXZmPWYI0qmERz7EDGcgIGiMaa3LCUittULIoQEaOZzo8GYcc7CSoMz6ZKLqXQOJBKLgYXzqSBc4xmPKcy11JgSPsvG0GLCIn6JQkJFiK8xfcLCjbwgJyDM+uJ8wChL8ud0ivSILnjCHnHblQlMyIp9kn/ADkMJCK55G14OL4YXmybrFhhyOzXQtKEGdMVwVeBUzDvHTjmKjdS54jWfojQlfpP3YCR/CRwZXnn6o3ptOJcgK84W8gwma8JVz7lZ0qZVI9Ff401PkzddTdqsJM5rme6lTZtdZQ+3jMCTLXFjlRkqyaZJI8Vzy7uqytl01Gk4chqOisAojnJYLR/7F5BWTpkV0gZUTDjgbnOUxTEorqCosxO7QyGG5+MEjqbiaDBLoPsTGzo2L0mCJ2yuNhri9FHQi21+iehCAfHzjHA8ilEOkWegnTqGm0QVkiDIVwU5950j/3Garw9Kdsjd7YYZlmurkhlUYrDNFoB19qUnltPCCUW40xhFZcBnnIvl65noTChxNCFT4+/w0ZiEZXOwV+9Qk9bmd0SiKYTeNm+F9AM2RKTX3tno4iN6QiM/IbFYHXz7eqHeOJI8AeM2YbTQDL4fiuFnCeIs0RvmNUt54eWqUK1iwOnaZ28Asr7cfC0894E/q2PYehDs7w2CGqtFdbndqklVRaoI1BpN2tEaXVdryql2JGKzTKiEgvdasXHchqNDi01XAz/vpiK0tOHW0YTbYUpC6/1ULj9TuH0XlWZ93riOuhjotsz/rmf09pWkjpKkuvI/4sWYoSRIG+K/ks9PsgV4ucEcBYgjXV2ekCR8hoiq7a+uoeGZX+RN3PQ1BsdiwXB2+wG+h629rFR7SKDaRPSLj4VIm7n2ptsuG2voPKRIu7Zt9N9apHtbiXRr7VirASVHVgtAc4cFoDZNekclypZnWK5p9Tp9y+v1up1y73nRQMbWBWHdz3LP90ASbav14HuW6L4m9spsHotE95Us3d18Kkm2mS5KSZziik76lGXBy+XNLpTTq8O5Y6rKadkts3Rv27JlZ2uFE8VkrWTeX4z+nGS0DLSeWILDTYp3jyJ/Bqsf2xRrFXP4Bb6+3fy2tegdUuc6pqenct29pVFjkfryDulhtzDLWXskCnbarCtd75WadaoUlpqqBelBi0qzWDRINwzZanTkOObmkTVv8Pq1G+CgGMNuRVSl53csonZXV0R7RyWitrobIasPMMoCRGF4WY807b+PnD+OS3idXh347fuHrdrbt8qWu4+5WpzU1RcE81QocLTwHcMPIiMoUsJEPtI8+obPWqRZRlNK7+kLoqskejut3UWCeg1msh3L6PYrn54qsf2WbO3thYOjrpTeTGK1Oea4ikSQ/EaSX7t1qwiZfeC9W6ft9dO71TSn/D3YS3hz7KPSNEct3+/vlDyVciS2/FLOEnwYSWpskXS7ai3YOSjB2WqwcEDEm+9cjEwRuqaGfGTineJdhrOW3c/2AjApnO6/BNxBkpqVXrfz1pWes91Lx73KkPZ+UTkP31qHyiw26zFt2fEacGiWiPtWHXWNXvwuIIwpETNmDbPhuZhhAcvG+RWrJj3Wm2x99Vt+QXLYrS9XXdAVu4YDCCehIpztbHefRVH+a07dX22sc/efoLy+/daU5+pswh+I8vRXQt3joDyZVbeW015ztaxLgHU3/eZbnT3Tn6uuULYGwoF/z+lo7wYdF16AHes00GuuO/V3Qxui2bP0ULP1bqjTYK5yS2Gvm5vu/6sQ1IVzKa67KwTXEJK3GVu6KLWd14H0ZRjB6eovj4rmqz/gci7+BQ== \ No newline at end of file diff --git a/docs/configurator_diagram.svg b/docs/configurator_diagram.svg deleted file mode 100644 index bcf0bf76d1ec..000000000000 --- a/docs/configurator_diagram.svg +++ /dev/null @@ -1,3 +0,0 @@ - - -
Clients Supported:
Chrome, Firefox
Desktop Only
Clients Supported:...
https://config.qmk.fm
Single Page Site
JavaScript/VUE
Source: qmk/qmk_configurator
Host: Github Pages
https://config.qmk.fm...
https://keyboards.qmk.fm
Keyboard Metadata
Source: qmk/qmk_firmware
GH Action: Update API Data
Host: DigitalOcean Spaces
https://keyboards.qmk.fm...
QMK API
QMK API
https://api.qmk.fm
RESTful API
Source: qmk/qmk_api
Host: Rancher on DO VM's
https://api.qmk.fm...
Digital Ocean
Spaces
(S3)
Digital Ocean...
https://qmk-api.nyc3.cdn.digitaloceanspaces.com
Space: qmk-api
Host: Digital Ocean
https://qmk-api.nyc3.cdn.digitaloceanspaces.com...
RQ
RQ
Redis / RQ
Job Queue
Source: qmk/qmk_redis
Host: Rancher on DO VM's
Redis / RQ...
qmk_complier
qmk_complier
QMK Compiler
Job Runners
Source: qmk/qmk_compiler
Host: Rancher on DO VM's
QMK Compiler...
Viewer does not support full SVG 1.1
\ No newline at end of file diff --git a/docs/configurator_step_by_step.md b/docs/configurator_step_by_step.md deleted file mode 100644 index c3cc2bfcdbcb..000000000000 --- a/docs/configurator_step_by_step.md +++ /dev/null @@ -1,58 +0,0 @@ -# QMK Configurator: Step by Step - -This page describes the steps for building your firmware in QMK Configurator. - -## Step 1: Select Your Keyboard - -Click the drop down box and select the keyboard you want to create a keymap for. - -?> If your keyboard has several versions, make sure you select the correct one. - -I'll say that again because it's important: - -!> **MAKE SURE YOU SELECT THE RIGHT VERSION!** - -If your keyboard has been advertised to be powered by QMK but is not in the list, chances are a developer hasn't gotten to it yet or we haven't had a chance to merge it in yet. File an issue at [qmk_firmware](https://github.com/qmk/qmk_firmware/issues) requesting to support that particular keyboard, if there is no active [Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) for it. There are also QMK powered keyboards that are in their manufacturer's own GitHub accounts. Double check for that as well. - -## Step 2: Select Your Keyboard Layout - -Choose the layout that best represents the keymap you want to create. Some keyboards do not have enough layouts or correct layouts defined yet. They will be supported in the future. - -!> Sometimes there isn't a layout that supports your exact build. In that case select `LAYOUT_all`. - -## Step 3: Name Your Keymap - -Call this keymap what you want. - -?> If you are running into issues when compiling, it may be worth changing this name, as it may already exist in the QMK Firmware repo. - -## Step 4: Define Your Keymap - -Keycode Entry is accomplished in one of 3 ways: - -1. Drag and drop -2. Clicking on an empty spot on the layout, then clicking the keycode you desire -3. Clicking on an empty spot on the layout, then pressing the physical key on your keyboard - -?> Hover your mouse over a key and a short blurb will tell you what that keycode does. For a more verbose description please see: - -* [Basic Keycode Reference](keycodes_basic.md) -* [Advanced Keycode Reference](feature_advanced_keycodes.md) - -!> If your selected layout doesn't match your physical build leave the unused keys blank. If you're not sure which key is in use, for example you have a one backspace key but `LAYOUT_all` has 2 keys, put the same keycode in both locations. - -## Step 5: Save Your Keymap for Future Changes - -When you're satisfied with your keymap or just want to work on it later, press the `Download this QMK Keymap JSON File` button. It will save your keymap to your computer. You can then load this .json file in the future by pressing the `Upload a QMK Keymap JSON File` button. - -!> **CAUTION:** This is not the same type of .json file used for kbfirmware.com or any other tool. If you try to use this for those tools, or the .json from those tools with QMK Configurator, you will encounter problems. - -## Step 6: Compile Your Firmware File - -Press the green `Compile` button. - -When the compilation is done, you will be able to press the green `Download Firmware` button. - -## Next steps: Flashing Your Keyboard - -Please refer to [Flashing Firmware](newbs_flashing.md). diff --git a/docs/configurator_troubleshooting.md b/docs/configurator_troubleshooting.md deleted file mode 100644 index 80b9713b64ea..000000000000 --- a/docs/configurator_troubleshooting.md +++ /dev/null @@ -1,26 +0,0 @@ -# Configurator Troubleshooting - -## My .json file is not working - -If the .json file was generated with QMK Configurator, congratulations you have stumbled upon a bug. File an issue at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues). - -If not... how did you miss the big bold message at the top saying not to use other .json files? - -## There are extra spaces in my layout? What do I do? - -If you're referring to having three spots for space bar, the best course of action is to just fill them all with Space. The same can be done for Backspace and Shift keys. - -## What is the keycode for... - -Please see: - -* [Basic Keycode Reference](keycodes_basic.md) -* [Advanced Keycode Reference](feature_advanced_keycodes.md) - -## It won't compile - -Please double check the other layers of your keymap to make sure there are no random keys present. - -## Problems and Bugs - -We are always accepting customer requests and bug reports. Please file them at [qmk_configurator](https://github.com/qmk/qmk_configurator/issues). diff --git a/docs/contributing.md b/docs/contributing.md deleted file mode 100644 index bb46add7892b..000000000000 --- a/docs/contributing.md +++ /dev/null @@ -1,168 +0,0 @@ -# How to Contribute - -👍🎉 First off, thanks for taking the time to read this and contribute! 🎉👍 - -Third-party contributions help us grow and improve QMK. We want to make the pull request and contribution process useful and easy for both contributors and maintainers. To this end we've put together some guidelines for contributors to help your pull request be accepted without major changes. - -* [Project Overview](#project-overview) -* [Coding Conventions](#coding-conventions) -* [General Guidelines](#general-guidelines) -* [What does the Code of Conduct mean for me?](#what-does-the-code-of-conduct-mean-for-me) - -## I Don't Want to Read This Whole Thing! I Just Have a Question! - -If you'd like to ask questions about QMK you can do so on the [OLKB Subreddit](https://reddit.com/r/olkb) or on [Discord](https://discord.gg/Uq7gcHh). - -Please keep these things in mind: - -* It may take several hours for someone to respond to your question. Please be patient! -* Everyone involved with QMK is donating their time and energy. We don't get paid to work on or answer questions about QMK. -* Try to ask your question so it's as easy to answer as possible. If you're not sure how to do that these are some good guides: - * https://opensource.com/life/16/10/how-ask-technical-questions - * http://www.catb.org/esr/faqs/smart-questions.html - -# Project Overview - -QMK is largely written in C, with specific features and parts written in C++. It targets embedded processors found in keyboards, particularly AVR ([LUFA](https://www.fourwalledcubicle.com/LUFA.php)) and ARM ([ChibiOS](https://www.chibios.org)). If you are already well versed in Arduino programming you'll find a lot of the concepts and limitations familiar. Prior experience with Arduino is not required to successfully contribute to QMK. - - - -# Where Can I Go for Help? - -If you need help you can [open an issue](https://github.com/qmk/qmk_firmware/issues) or [chat on Discord](https://discord.gg/Uq7gcHh). - -# How Do I Make a Contribution? - -Never made an open source contribution before? Wondering how contributions work in QMK? Here's a quick rundown! - -0. Sign up for a [GitHub](https://github.com) account. -1. Put together a keymap to contribute, [find an issue](https://github.com/qmk/qmk_firmware/issues) you are interested in addressing, or [a feature](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature) you would like to add. -2. Fork the repository associated with the issue to your GitHub account. This means that you will have a copy of the repository under `your-GitHub-username/qmk_firmware`. -3. Clone the repository to your local machine using `git clone https://github.com/github-username/repository-name.git`. -4. If you're working on a new feature consider opening an issue to talk with us about the work you're about to undertake. -5. Create a new branch for your fix using `git checkout -b branch-name-here`. -6. Make the appropriate changes for the issue you are trying to address or the feature that you want to add. -7. Use `git add insert-paths-of-changed-files-here` to add the file contents of the changed files to the "snapshot" git uses to manage the state of the project, also known as the index. -8. Use `git commit -m "Insert a short message of the changes made here"` to store the contents of the index with a descriptive message. -9. Push the changes to your repository on GitHub using `git push origin branch-name-here`. -10. Submit a pull request to [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master). -11. Title the pull request with a short description of the changes made and the issue or bug number associated with your change. For example, you can title an issue like so "Added more log outputting to resolve #4352". -12. In the description of the pull request explain the changes that you made, any issues you think exist with the pull request you made, and any questions you have for the maintainer. It's OK if your pull request is not perfect (no pull request is), the reviewer will be able to help you fix any problems and improve it! -13. Wait for the pull request to be reviewed by a maintainer. -14. Make changes to the pull request if the reviewing maintainer recommends them. -15. Celebrate your success after your pull request is merged! - -# Coding Conventions - -Most of our style is pretty easy to pick up on. If you are familiar with either C or Python you should not have too much trouble with our local styles. - -* [Coding Conventions - C](coding_conventions_c.md) -* [Coding Conventions - Python](coding_conventions_python.md) - -# General Guidelines - -We have a few different types of changes in QMK, each requiring a different level of rigor. We'd like you to keep the following guidelines in mind no matter what type of change you're making. - -* Separate PRs into logical units. For example, do not submit one PR covering two separate features, instead submit a separate PR for each feature. -* Check for unnecessary whitespace with `git diff --check` before committing. -* Make sure your code change actually compiles. - * Keymaps: Make sure that `make keyboard:your_new_keymap` does not return any errors. - * Keyboards: Make sure that `make keyboard:all` does not return any errors. - * Core: Make sure that `make all` does not return any errors. -* Make sure commit messages are understandable on their own. You should put a short description (no more than 70 characters) on the first line, the second line should be empty, and on the 3rd and later lines you should describe your commit in detail, if required. Example: - -``` -Adjust the fronzlebop for the kerpleplork - -The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations. - -Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure. -``` - -!> **IMPORTANT:** If you would like to contribute a bugfix or improvement to user code, such as non-default keymaps, userspace and layouts, be sure to tag the original submitter of the code in your PR. Many users, regardless of skill level with Git and GitHub, may be confused or frustrated at their code being modified without their knowledge. - -## Documentation - -Documentation is one of the easiest ways to get started contributing to QMK. Finding places where the documentation is wrong or incomplete and fixing those is easy! We also very badly need someone to edit our documentation, so if you have editing skills but aren't sure where or how to jump in please [reach out for help](#where-can-i-go-for-help)! - -You'll find all our documentation in the `qmk_firmware/docs` directory, or if you'd rather use a web based workflow you can click the "Edit this page" link at the bottom of each page on https://docs.qmk.fm/. - -When providing code examples in your documentation, try to observe naming conventions used elsewhere in the docs. For example, standardizing enums as `my_layers` or `my_keycodes` for consistency: - -```c -enum my_layers { - _FIRST_LAYER, - _SECOND_LAYER -}; - -enum my_keycodes { - FIRST_LAYER = SAFE_RANGE, - SECOND_LAYER -}; -``` - -### Previewing the Documentation :id=previewing-the-documentation - -Before opening a pull request, you can preview your changes if you have set up the development environment by running this command from the `qmk_firmware/` folder: - - qmk docs - -or if you only have Python 3 installed: - - python3 -m http.server 8936 --directory docs - -and navigating to `http://localhost:8936/`. - -## Keymaps - -Most first-time QMK contributors start with their personal keymaps. We try to keep keymap standards pretty casual (keymaps, after all, reflect the personality of their creators) but we do ask that you follow these guidelines to make it easier for others to discover and learn from your keymap. - -* Write a `readme.md` using [the template](documentation_templates.md). -* All Keymap PRs are squashed, so if you care about how your commits are squashed you should do it yourself -* Do not lump features in with keymap PRs. Submit the feature first and then a second PR for the keymap. -* Do not include `Makefile`s in your keymap folder (they're no longer used) -* Update copyrights in file headers (look for `%YOUR_NAME%`) - -## Keyboards - -Keyboards are the raison d'être for QMK. Some keyboards are community maintained, while others are maintained by the people responsible for making a particular keyboard. The `readme.md` should tell you who maintains a particular keyboard. If you have questions relating to a particular keyboard you can [Open An Issue](https://github.com/qmk/qmk_firmware/issues) and tag the maintainer in your question. - -We also ask that you follow these guidelines: - -* Write a `readme.md` using [the template](documentation_templates.md). -* Keep the number of commits reasonable or we will squash your PR -* Do not lump core features in with new keyboards. Submit the feature first and then submit a separate PR for the keyboard. -* Name `.c`/`.h` file after the immediate parent folder, eg `/keyboards///.[ch]` -* Do not include `Makefile`s in your keyboard folder (they're no longer used) -* Update copyrights in file headers (look for `%YOUR_NAME%`) - -## Quantum/TMK Core - -Before you put a lot of work into building your new feature you should make sure you are implementing it in the best way. You can get a basic understanding of QMK by reading [Understanding QMK](understanding_qmk.md), which will take you on a tour of the QMK program flow. From here you should talk to us to get a sense of the best way to implement your idea. There are two main ways to do this: - -* [Chat on Discord](https://discord.gg/Uq7gcHh) -* [Open an Issue](https://github.com/qmk/qmk_firmware/issues/new) - -Feature and Bug Fix PRs affect all keyboards. We are also in the process of restructuring QMK. For this reason it is especially important for significant changes to be discussed before implementation has happened. If you open a PR without talking to us first please be prepared to do some significant rework if your choices do not mesh well with our planned direction. - -Here are some things to keep in mind when working on your feature or bug fix. - -* **Disabled by default** - memory is a pretty limited on most chips QMK supports, and it's important that current keymaps aren't broken, so please allow your feature to be turned **on**, rather than being turned off. If you think it should be on by default, or reduces the size of the code, please talk with us about it. -* **Compile locally before submitting** - hopefully this one is obvious, but things need to compile! You should always make sure your changes compile before opening a pull request. -* **Consider revisions and different chip-bases** - there are several keyboards that have revisions that allow for slightly different configurations, and even different chip-bases. Try to make a feature supported in ARM and AVR, or automatically disabled on platforms it doesn't work on. -* **Explain your feature** - Document it in `docs/`, either as a new file or as part of an existing file. If you don't document it other people won't be able to benefit from your hard work. - -We also ask that you follow these guidelines: - -* Keep the number of commits reasonable or we will squash your PR -* Do not lump keyboards or keymaps in with core changes. Submit your core changes first. -* Write [Unit Tests](unit_testing.md) for your feature -* Follow the style of the file you are editing. If the style is unclear or there are mixed styles you should conform to the [coding conventions](#coding-conventions) above. - -## Refactoring - -To maintain a clear vision of how things are laid out in QMK we try to plan out refactors in-depth and have a collaborator make the changes. If you have an idea for refactoring, or suggestions, [open an issue](https://github.com/qmk/qmk_firmware/issues), we'd love to talk about how QMK can be improved. - -# What Does the Code of Conduct Mean for Me? - -Our [Code of Conduct](https://qmk.fm/coc/) means that you are responsible for treating everyone on the project with respect and courtesy regardless of their identity. If you are the victim of any inappropriate behavior or comments as described in our Code of Conduct, we are here for you and will do the best to ensure that the abuser is reprimanded appropriately, per our code. diff --git a/docs/custom_matrix.md b/docs/custom_matrix.md deleted file mode 100644 index ef206944e181..000000000000 --- a/docs/custom_matrix.md +++ /dev/null @@ -1,108 +0,0 @@ -# Custom Matrix - -QMK provides a mechanism to supplement or replace the default matrix scanning routine with your own code. - -The reasons to use this feature include: - -* Extra hardware between the keyboard's switches and MCU pins - * I/O multiplexer - * Line decoder -* Irregular switch matrix - * Simultaneous use of `COL2ROW` and `ROW2COL` - -## Prerequisites - -Implementing custom matrix usually involves compilation of an additional source file. It is recommended that for consistency, this file is called `matrix.c`. - -Add a new file to your keyboard directory: -``` -keyboards//matrix.c -``` - -And to configure compilation for the new file, add this to your `rules.mk`: -```make -SRC += matrix.c -``` - -## 'lite' - -Provides a default implementation for various scanning functions, reducing the boilerplate code when implementing custom matrix. -To configure it, add this to your `rules.mk`: - -```make -CUSTOM_MATRIX = lite -``` - -And implement the following functions in a `matrix.c` file in your keyboard folder: - -```c -void matrix_init_custom(void) { - // TODO: initialize hardware here -} - -bool matrix_scan_custom(matrix_row_t current_matrix[]) { - bool matrix_has_changed = false; - - // TODO: add matrix scanning routine here - - return matrix_has_changed; -} -``` - - -## Full Replacement - -When more control over the scanning routine is required, you can choose to implement the full scanning routine. -To configure it, add this to your rules.mk: - -```make -CUSTOM_MATRIX = yes -``` - -And implement the following functions in a `matrix.c` file in your keyboard folder: - -```c -matrix_row_t matrix_get_row(uint8_t row) { - // TODO: return the requested row data -} - -void matrix_print(void) { - // TODO: use print() to dump the current matrix state to console -} - -void matrix_init(void) { - // TODO: initialize hardware and global matrix state here - - // Unless hardware debouncing - Init the configured debounce routine - debounce_init(MATRIX_ROWS); - - // This *must* be called for correct keyboard behavior - matrix_init_kb(); -} - -uint8_t matrix_scan(void) { - bool changed = false; - - // TODO: add matrix scanning routine here - - // Unless hardware debouncing - use the configured debounce routine - changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed); - - // This *must* be called for correct keyboard behavior - matrix_scan_kb(); - - return changed; -} -``` - -And also provide defaults for the following callbacks: - -```c -__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } - -__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } - -__attribute__((weak)) void matrix_init_user(void) {} - -__attribute__((weak)) void matrix_scan_user(void) {} -``` diff --git a/docs/custom_quantum_functions.md b/docs/custom_quantum_functions.md deleted file mode 100644 index 5d63f3cfb7d0..000000000000 --- a/docs/custom_quantum_functions.md +++ /dev/null @@ -1,362 +0,0 @@ -# How to Customize Your Keyboard's Behavior - -For a lot of people a custom keyboard is about more than sending button presses to your computer. You want to be able to do things that are more complex than simple button presses and macros. QMK has hooks that allow you to inject code, override functionality, and otherwise customize how your keyboard behaves in different situations. - -This page does not assume any special knowledge about QMK, but reading [Understanding QMK](understanding_qmk.md) will help you understand what is going on at a more fundamental level. - -## A Word on Core vs Keyboards vs Keymap :id=a-word-on-core-vs-keyboards-vs-keymap - -We have structured QMK as a hierarchy: - -* Core (`_quantum`) - * Keyboard/Revision (`_kb`) - * Keymap (`_user`) - -Each of the functions described below can be defined with a `_kb()` suffix or a `_user()` suffix. We intend for you to use the `_kb()` suffix at the Keyboard/Revision level, while the `_user()` suffix should be used at the Keymap level. - -When defining functions at the Keyboard/Revision level it is important that your `_kb()` implementation call `_user()` before executing anything else- otherwise the keymap level function will never be called. - -# Custom Keycodes - -By far the most common task is to change the behavior of an existing keycode or to create a new keycode. From a code standpoint the mechanism for each is very similar. - -## Defining a New Keycode - -The first step to creating your own custom keycode(s) is to enumerate them. This means both naming them and assigning a unique number to that keycode. Rather than limit custom keycodes to a fixed range of numbers QMK provides the `SAFE_RANGE` macro. You can use `SAFE_RANGE` when enumerating your custom keycodes to guarantee that you get a unique number. - - -Here is an example of enumerating 2 keycodes. After adding this block to your `keymap.c` you will be able to use `FOO` and `BAR` inside your keymap. - -```c -enum my_keycodes { - FOO = SAFE_RANGE, - BAR -}; -``` - -## Programming the Behavior of Any Keycode :id=programming-the-behavior-of-any-keycode - -When you want to override the behavior of an existing key, or define the behavior for a new key, you should use the `process_record_kb()` and `process_record_user()` functions. These are called by QMK during key processing before the actual key event is handled. If these functions return `true` QMK will process the keycodes as usual. That can be handy for extending the functionality of a key rather than replacing it. If these functions return `false` QMK will skip the normal key handling, and it will be up to you to send any key up or down events that are required. - -These function are called every time a key is pressed or released. - -### Example `process_record_user()` Implementation - -This example does two things. It defines the behavior for a custom keycode called `FOO`, and it supplements our Enter key by playing a tone whenever it is pressed. - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // Do something when pressed - } else { - // Do something else when release - } - return false; // Skip all further processing of this key - case KC_ENTER: - // Play a tone when enter is pressed - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // Let QMK send the enter press/release events - default: - return true; // Process all other keycodes normally - } -} -``` - -### `process_record_*` Function Documentation - -* Keyboard/Revision: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` -* Keymap: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` - -The `keycode` argument is whatever is defined in your keymap, eg `MO(1)`, `KC_L`, etc. You should use a `switch...case` block to handle these events. - -The `record` argument contains information about the actual press: - -```c -keyrecord_t record { - keyevent_t event { - keypos_t key { - uint8_t col - uint8_t row - } - bool pressed - uint16_t time - } -} -``` - -# Keyboard Initialization Code - -There are several steps in the keyboard initialization process. Depending on what you want to do, it will influence which function you should use. - -These are the three main initialization functions, listed in the order that they're called. - -* `keyboard_pre_init_*` - Happens before most anything is started. Good for hardware setup that you want running very early. -* `matrix_init_*` - Happens midway through the firmware's startup process. Hardware is initialized, but features may not be yet. -* `keyboard_post_init_*` - Happens at the end of the firmware's startup process. This is where you'd want to put "customization" code, for the most part. - -!> For most people, the `keyboard_post_init_user` function is what you want to call. For instance, this is where you want to set up things for RGB Underglow. - -## Keyboard Pre Initialization code - -This runs very early during startup, even before the USB has been started. - -Shortly after this, the matrix is initialized. - -For most users, this shouldn't be used, as it's primarily for hardware oriented initialization. - -However, if you have hardware stuff that you need initialized, this is the best place for it (such as initializing LED pins). - -### Example `keyboard_pre_init_user()` Implementation - -This example, at the keyboard level, sets up B0, B1, B2, B3, and B4 as LED pins. - -```c -void keyboard_pre_init_user(void) { - // Call the keyboard pre init code. - - // Set our LED pins as output - setPinOutput(B0); - setPinOutput(B1); - setPinOutput(B2); - setPinOutput(B3); - setPinOutput(B4); -} -``` - -### `keyboard_pre_init_*` Function Documentation - -* Keyboard/Revision: `void keyboard_pre_init_kb(void)` -* Keymap: `void keyboard_pre_init_user(void)` - -## Matrix Initialization Code - -This is called when the matrix is initialized, and after some of the hardware has been set up, but before many of the features have been initialized. - -This is useful for setting up stuff that you may need elsewhere, but isn't hardware related nor is dependant on where it's started. - - -### `matrix_init_*` Function Documentation - -* Keyboard/Revision: `void matrix_init_kb(void)` -* Keymap: `void matrix_init_user(void)` - -### Low-level Matrix Overrides Function Documentation :id=low-level-matrix-overrides - -* GPIO pin initialisation: `void matrix_init_pins(void)` - * This needs to perform the low-level initialisation of all row and column pins. By default this will initialise the input/output state of each of the GPIO pins listed in `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no initialisation of pin state will occur within QMK itself, instead deferring to the keyboard's override. -* `COL2ROW`-based row reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` -* `ROW2COL`-based column reads: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter)` -* `DIRECT_PINS`-based reads: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` - * These three functions need to perform the low-level retrieval of matrix state of relevant input pins, based on the matrix type. Only one of the functions should be implemented, if needed. By default this will iterate through `MATRIX_ROW_PINS` and `MATRIX_COL_PINS`, configuring the inputs and outputs based on whether or not the keyboard is set up for `ROW2COL`, `COL2ROW`, or `DIRECT_PINS`. Should the keyboard designer override this function, no manipulation of matrix GPIO pin state will occur within QMK itself, instead deferring to the keyboard's override. - -## Keyboard Post Initialization code - -This is ran as the very last task in the keyboard initialization process. This is useful if you want to make changes to certain features, as they should be initialized by this point. - - -### Example `keyboard_post_init_user()` Implementation - -This example, running after everything else has initialized, sets up the rgb underglow configuration. - -```c -void keyboard_post_init_user(void) { - // Call the post init code. - rgblight_enable_noeeprom(); // enables Rgb, without saving settings - rgblight_sethsv_noeeprom(180, 255, 255); // sets the color to teal/cyan without saving - rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // sets mode to Fast breathing without saving -} -``` - -### `keyboard_post_init_*` Function Documentation - -* Keyboard/Revision: `void keyboard_post_init_kb(void)` -* Keymap: `void keyboard_post_init_user(void)` - -# Matrix Scanning Code - -Whenever possible you should customize your keyboard by using `process_record_*()` and hooking into events that way, to ensure that your code does not have a negative performance impact on your keyboard. However, in rare cases it is necessary to hook into the matrix scanning. Be extremely careful with the performance of code in these functions, as it will be called at least 10 times per second. - -### Example `matrix_scan_*` Implementation - -This example has been deliberately omitted. You should understand enough about QMK internals to write this without an example before hooking into such a performance sensitive area. If you need help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) or [chat with us on Discord](https://discord.gg/Uq7gcHh). - -### `matrix_scan_*` Function Documentation - -* Keyboard/Revision: `void matrix_scan_kb(void)` -* Keymap: `void matrix_scan_user(void)` - -This function gets called at every matrix scan, which is basically as often as the MCU can handle. Be careful what you put here, as it will get run a lot. - -You should use this function if you need custom matrix scanning code. It can also be used for custom status output (such as LEDs or a display) or other functionality that you want to trigger regularly even when the user isn't typing. - -# Keyboard housekeeping - -* Keyboard/Revision: `void housekeeping_task_kb(void)` -* Keymap: `void housekeeping_task_user(void)` - -This function gets called at the end of all QMK processing, before starting the next iteration. You can safely assume that QMK has dealt with the last matrix scan at the time that these functions are invoked -- layer states have been updated, USB reports have been sent, LEDs have been updated, and displays have been drawn. - -Similar to `matrix_scan_*`, these are called as often as the MCU can handle. To keep your board responsive, it's suggested to do as little as possible during these function calls, potentially throtting their behaviour if you do indeed require implementing something special. - -### Example `void housekeeping_task_user(void)` implementation - -This example will show you how to use `void housekeeping_task_user(void)` to turn off [RGB Light](feature_rgblight.md). For RGB Matrix, the [builtin](https://docs.qmk.fm/#/feature_rgb_matrix?id=additional-configh-options) `RGB_MATRIX_TIMEOUT` should be used. - -First, add the following lines to your keymap's `config.h`: - -```c -#define RGBLIGHT_SLEEP // enable rgblight_suspend() and rgblight_wakeup() in keymap.c -#define RGBLIGHT_TIMEOUT 900000 // ms to wait until rgblight time out, 900K ms is 15min. -``` - -Next, add the following code to your `keymap.c`: - -```c -static uint32_t key_timer; // timer for last keyboard activity, use 32bit value and function to make longer idle time possible -static void refresh_rgb(void); // refreshes the activity timer and RGB, invoke whenever any activity happens -static void check_rgb_timeout(void); // checks if enough time has passed for RGB to timeout -bool is_rgb_timeout = false; // store if RGB has timed out or not in a boolean - -void refresh_rgb(void) { - key_timer = timer_read32(); // store time of last refresh - if (is_rgb_timeout) - { - is_rgb_timeout = false; - rgblight_wakeup(); - } -} -void check_rgb_timeout(void) { - if (!is_rgb_timeout && timer_elapsed32(key_timer) > RGBLIGHT_TIMEOUT) // check if RGB has already timeout and if enough time has passed - { - rgblight_suspend(); - is_rgb_timeout = true; - } -} -/* Then, call the above functions from QMK's built in post processing functions like so */ -/* Runs at the end of each scan loop, check if RGB timeout has occured or not */ -void housekeeping_task_user(void) { -#ifdef RGBLIGHT_TIMEOUT - check_rgb_timeout(); -#endif -} -/* Runs after each key press, check if activity occurred */ -void post_process_record_user(uint16_t keycode, keyrecord_t *record) { -#ifdef RGBLIGHT_TIMEOUT - if (record->event.pressed) - refresh_rgb(); -#endif -} -/* Runs after each encoder tick, check if activity occurred */ -void post_encoder_update_user(uint8_t index, bool clockwise) { -#ifdef RGBLIGHT_TIMEOUT - refresh_rgb(); -#endif -} -``` - -# Keyboard Idling/Wake Code - -If the board supports it, it can be "idled", by stopping a number of functions. A good example of this is RGB lights or backlights. This can save on power consumption, or may be better behavior for your keyboard. - -This is controlled by two functions: `suspend_power_down_*` and `suspend_wakeup_init_*`, which are called when the system board is idled and when it wakes up, respectively. - - -### Example `suspend_power_down_user()` and `suspend_wakeup_init_user()` Implementation - - -```c -void suspend_power_down_user(void) { - // code will run multiple times while keyboard is suspended -} - -void suspend_wakeup_init_user(void) { - // code will run on keyboard wakeup -} -``` - -### Keyboard suspend/wake Function Documentation - -* Keyboard/Revision: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` -* Keymap: `void suspend_power_down_kb(void)` and `void suspend_wakeup_init_user(void)` - -# Deferred Execution :id=deferred-execution - -QMK has the ability to execute a callback after a specified period of time, rather than having to manually manage timers. To enable this functionality, set `DEFERRED_EXEC_ENABLE = yes` in rules.mk. - -## Deferred executor callbacks - -All _deferred executor callbacks_ have a common function signature and look like: - -```c -uint32_t my_callback(uint32_t trigger_time, void *cb_arg) { - /* do something */ - bool repeat = my_deferred_functionality(); - return repeat ? 500 : 0; -} -``` - -The first argument `trigger_time` is the intended time of execution. If other delays prevent executing at the exact trigger time, this allows for "catch-up" or even skipping intervals, depending on the required behaviour. - -The second argument `cb_arg` is the same argument passed into `defer_exec()` below, and can be used to access state information from the original call context. - -The return value is the number of milliseconds to use if the function should be repeated -- if the callback returns `0` then it's automatically unregistered. In the example above, a hypothetical `my_deferred_functionality()` is invoked to determine if the callback needs to be repeated -- if it does, it reschedules for a `500` millisecond delay, otherwise it informs the deferred execution background task that it's done, by returning `0`. - -?> Note that the returned delay will be applied to the intended trigger time, not the time of callback invocation. This allows for generally consistent timing even in the face of occasional late execution. - -## Deferred executor registration - -Once a callback has been defined, it can be scheduled using the following API: - -```c -deferred_token my_token = defer_exec(1500, my_callback, NULL); -``` - -The first argument is the number of milliseconds to wait until executing `my_callback` -- in the case above, `1500` milliseconds, or 1.5 seconds. - -The third parameter is the `cb_arg` that gets passed to the callback at the point of execution. This value needs to be valid at the time the callback is invoked -- a local function value will be destroyed before the callback is executed and should not be used. If this is not required, `NULL` should be used. - -The return value is a `deferred_token` that can consequently be used to cancel the deferred executor callback before it's invoked. If a failure occurs, the returned value will be `INVALID_DEFERRED_TOKEN`. Usually this will be as a result of supplying `0` to the delay, or a `NULL` for the callback. The other failure case is if there are too many deferred executions "in flight" -- this can be increased by changing the limit, described below. - -## Extending a deferred execution - -The `deferred_token` returned by `defer_exec()` can be used to extend a the duration a pending execution waits before it gets invoked: -```c -// This will re-delay my_token's future execution such that it is invoked 800ms after the current time -extend_deferred_exec(my_token, 800); -``` - -## Cancelling a deferred execution - -The `deferred_token` returned by `defer_exec()` can be used to cancel a pending execution before it gets invoked: -```c -// This will cancel my_token's future execution -cancel_deferred_exec(my_token); -``` - -Once a token has been canceled, it should be considered invalid. Reusing the same token is not supported. - -## Deferred callback limits - -There are a maximum number of deferred callbacks that can be scheduled, controlled by the value of the define `MAX_DEFERRED_EXECUTORS`. - -If registrations fail, then you can increase this value in your keyboard or keymap `config.h` file, for example to 16 instead of the default 8: - -```c -#define MAX_DEFERRED_EXECUTORS 16 -``` - -# Advanced topics :id=advanced-topics - -This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for. - -## Layer Change Code :id=layer-change-code - -[Layer change code](feature_layers.md#layer-change-code) - -## Persistent Configuration (EEPROM) :id=persistent-configuration-eeprom - -[Persistent Configuration (EEPROM)](feature_eeprom.md) diff --git a/docs/data_driven_config.md b/docs/data_driven_config.md deleted file mode 100644 index ba287f5688e9..000000000000 --- a/docs/data_driven_config.md +++ /dev/null @@ -1,92 +0,0 @@ -# Data Driven Configuration - -This page describes how QMK's data driven JSON configuration system works. It is aimed at developers who want to work on QMK itself. - -## History - -Historically QMK has been configured through a combination of two mechanisms- `rules.mk` and `config.h`. While this worked well when QMK was only a handful of keyboards we've grown to encompass nearly 1500 supported keyboards. That extrapolates out to 6000 configuration files under `keyboards/` alone! The freeform nature of these files and the unique patterns people have used to avoid duplication have made ongoing maintenance a challenge, and a large number of our keyboards follow patterns that are outdated and sometimes harder to understand. - -We have also been working on bringing the power of QMK to people who aren't comformable with a CLI, and other projects such as VIA are working to make using QMK as easy as installing a program. These tools need information about how a keyboard is laid out or what pins and features are available so that users can take full advantage of QMK. We introduced `info.json` as a first step towards this. The QMK API is an effort to combine these 3 sources of information- `config.h`, `rules.mk`, and `info.json`- into a single source of truth that end-user tools can use. - -Now we have support for generating `rules.mk` and `config.h` values from `info.json`, allowing us to have a single source of truth. This will allow us to use automated tooling to maintain keyboards saving a lot of time and maintenance work. - -## Overview - -On the C side of things nothing changes. When you need to create a new rule or define you follow the same process: - -1. Add it to `docs/config_options.md` -1. Set a default in the appropriate core file -1. Add your ifdef statements as needed - -You will then need to add support for your new configuration to `info.json`. The basic process is: - -1. Add it to the schema in `data/schemas/keyboards.jsonschema` -1. Add a mapping in `data/maps` -1. (optional and discouraged) Add code to extract/generate it to: - * `lib/python/qmk/info.py` - * `lib/python/qmk/cli/generate/config_h.py` - * `lib/python/qmk/cli/generate/rules_mk.py` - -## Adding an option to info.json - -This section describes adding support for a `config.h`/`rules.mk` value to info.json. - -### Add it to the schema - -QMK maintains [jsonschema](https://json-schema.org/) files in `data/schemas`. The values that go into keyboard-specific `info.json` files are kept in `keyboard.jsonschema`. Any value you want to make available to end users to edit must go in here. - -In some cases you can simply add a new top-level key. Some examples to follow are `keyboard_name`, `maintainer`, `processor`, and `url`. This is appropriate when your option is self-contained and not directly related to other options. - -In other cases you should group like options together in an `object`. This is particularly true when adding support for a feature. Some examples to follow for this are `indicators`, `matrix_pins`, and `rgblight`. If you are not sure how to integrate your new option(s) [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and start a conversation there. - -### Add a mapping - -In most cases you can add a simple mapping. These are maintained as JSON files in `data/mappings/info_config.hjson` and `data/mappings/info_rules.hjson`, and control mapping for `config.h` and `rules.mk`, respectively. Each mapping is keyed by the `config.h` or `rules.mk` variable, and the value is a hash with the following keys: - -* `info_key`: (required) The location within `info.json` for this value. See below. -* `value_type`: (optional) Default `raw`. The format for this variable's value. See below. -* `to_json`: (optional) Default `true`. Set to `false` to exclude this mapping from info.json -* `to_c`: (optional) Default `true`. Set to `false` to exclude this mapping from config.h -* `warn_duplicate`: (optional) Default `true`. Set to `false` to turn off warning when a value exists in both places - -#### Info Key - -We use JSON dot notation to address variables within info.json. For example, to access `info_json["rgblight"]["split_count"]` I would specify `rgblight.split_count`. This allows you to address deeply nested keys with a simple string. - -Under the hood we use [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/), you can refer to that documentation for how these strings are converted to object access. - -#### Value Types - -By default we treat all values as unquoted "raw" data. If your value is more complex you can use one of these types to intelligently parse the data: - -* `array`: A comma separated array of strings -* `array.int`: A comma separated array of integers -* `int`: An integer -* `hex`: A number formatted as hex -* `list`: A space separate array of strings -* `mapping`: A hash of key/value pairs -* `str`: A quoted string literal - -### Add code to extract it - -Most use cases can be solved by the mapping files described above. If yours can't you can instead write code to extract your config values. - -Whenever QMK generates a complete `info.json` it extracts information from `config.h` and `rules.mk`. You will need to add code for your new config value to `lib/python/qmk/info.py`. Typically this means adding a new `_extract_()` function and then calling your function in either `_extract_config_h()` or `_extract_rules_mk()`. - -If you are not sure how to edit this file or are not comfortable with Python [open an issue](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) or [join #cli on Discord](https://discord.gg/heQPAgy) and someone can help you with this part. - -### Add code to generate it :id=add-code-to-generate-it - -The final piece of the puzzle is providing your new option to the build system. This is done by generating two files: - -* `.build/obj_/src/info_config.h` -* `.build/obj_/src/rules.mk` - -These two files are generated by the code here: - -* `lib/python/qmk/cli/generate/config_h.py` -* `lib/python/qmk/cli/generate/rules_mk.py` - -For `config.h` values you'll need to write a function for your rule(s) and call that function in `generate_config_h()`. - -If you have a new top-level `info.json` key for `rules.mk` you can simply add your keys to `info_to_rules` at the top of `lib/python/qmk/cli/generate/rules_mk.py`. Otherwise you'll need to create a new if block for your feature in `generate_rules_mk()`. diff --git a/docs/documentation_best_practices.md b/docs/documentation_best_practices.md deleted file mode 100644 index c193fed6b86e..000000000000 --- a/docs/documentation_best_practices.md +++ /dev/null @@ -1,64 +0,0 @@ -# Documentation Best Practices - -This page exists to document best practices when writing documentation for QMK. Following these guidelines will help to keep a consistent tone and style, which will in turn help other people more easily understand QMK. - -# Page Opening - -Your documentation page should generally start with an H1 heading, followed by a 1 paragraph description of what the user will find on this page. Keep in mind that this heading and paragraph will sit next to the Table of Contents, so keep the heading short and avoid long strings with no whitespace. - -Example: - -``` -# My Page Title - -This page covers my super cool feature. You can use this feature to make coffee, squeeze fresh oj, and have an egg mcmuffin and hashbrowns delivered from your local macca's by drone. -``` - -# Headings - -Your page should generally have multiple "H1" headings. Only H1 and H2 headings will included in the Table of Contents, so plan them out appropriately. Excess width should be avoided in H1 and H2 headings to prevent the Table of Contents from getting too wide. - -# Styled Hint Blocks - -You can have styled hint blocks drawn around text to draw attention to it. - -### Important - -``` -!> This is important -``` - -Renders as: - -!> This is important - -### General Tips - -``` -?> This is a helpful tip. -``` - -Renders as: - -?> This is a helpful tip. - - -# Documenting Features - -If you create a new feature for QMK, create a documentation page for it. It doesn't have to be very long, a few sentences describing your feature and a table listing any relevant keycodes is enough. Here is a basic template: - -```markdown -# My Cool Feature - -This page describes my cool feature. You can use my cool feature to make coffee and order cream and sugar to be delivered via drone. - -## My Cool Feature Keycodes - -|Long Name|Short Name|Description| -|---------|----------|-----------| -|KC_COFFEE||Make Coffee| -|KC_CREAM||Order Cream| -|KC_SUGAR||Order Sugar| -``` - -Place your documentation into `docs/feature_.md`, and add that file to the appropriate place in `docs/_summary.md`. If you have added any keycodes be sure to add them to `docs/keycodes.md` with a link back to your feature page. diff --git a/docs/documentation_templates.md b/docs/documentation_templates.md deleted file mode 100644 index 0ad4303416f0..000000000000 --- a/docs/documentation_templates.md +++ /dev/null @@ -1,52 +0,0 @@ -# Documentation Templates - -This page documents the templates you should use when submitting new Keymaps and Keyboards to QMK. - -## Keymap `readme.md` Template :id=keyboard-readmemd-template - -Most keymaps have an image depicting the layout. You can use [Keyboard Layout Editor](http://keyboard-layout-editor.com) to create an image. Upload it to [Imgur](https://imgur.com) or another hosting service, please do not include images in your Pull Request. - -Below the image you should write a short description to help people understand your keymap. - -``` -![Clueboard Layout Image](https://i.imgur.com/7Capi8W.png) - -# Default Clueboard Layout - -This is the default layout that comes flashed on every Clueboard. For the most -part it's a straightforward and easy to follow layout. The only unusual key is -the key in the upper left, which sends Escape normally, but Grave when any of -the Ctrl, Alt, or GUI modifiers are held down. -``` - -## Keyboard `readme.md` Template - -``` -# Planck - -![Planck](https://i.imgur.com/q2M3uEU.jpg) - -A compact 40% (12x4) ortholinear keyboard kit made and sold by OLKB and Massdrop. [More info on qmk.fm](https://qmk.fm/planck/) - -* Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert) -* Hardware Supported: Planck PCB rev1, rev2, rev3, rev4, Teensy 2.0 -* Hardware Availability: [OLKB.com](https://olkb.com), [Massdrop](https://www.massdrop.com/buy/planck-mechanical-keyboard?mode=guest_open) - -Make example for this keyboard (after setting up your build environment): - - make planck/rev4:default - -Flashing example for this keyboard: - - make planck/rev4: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 -``` diff --git a/docs/driver_installation_zadig.md b/docs/driver_installation_zadig.md deleted file mode 100644 index 3b2c0b74dc41..000000000000 --- a/docs/driver_installation_zadig.md +++ /dev/null @@ -1,99 +0,0 @@ -# Bootloader Driver Installation with Zadig - -QMK presents itself to the host as a regular HID keyboard device, and as such requires no special drivers. However, in order to flash your keyboard on Windows, the bootloader device that appears when you reset the board often *does*. - -There are two notable exceptions: the Caterina bootloader, usually seen on Pro Micros, and the HalfKay bootloader shipped with PJRC Teensys, appear as a serial port and a generic HID device respectively, and so do not require a driver. - -We recommend the use of the [Zadig](https://zadig.akeo.ie/) utility. If you have set up the development environment with MSYS2, the `qmk_install.sh` script will have already installed the drivers for you. - -## Installation - -Put your keyboard into bootloader mode, either by hitting the `QK_BOOT` keycode (which may be on a different layer), or by pressing the reset switch that's usually located on the underside of the board. If your keyboard has neither, try holding Escape or Space+`B` as you plug it in (see the [Bootmagic Lite](feature_bootmagic.md) docs for more details). Some boards use [Command](feature_command.md) instead of Bootmagic; in this case, you can enter bootloader mode by hitting Left Shift+Right Shift+`B` or Left Shift+Right Shift+Escape at any point while the keyboard is plugged in. -Some keyboards may have specific instructions for entering the bootloader. For example, the [Bootmagic Lite](feature_bootmagic.md) key (default: Escape) might be on a different key, e.g. Left Control; or the magic combination for Command (default: Left Shift+Right Shift) might require you to hold something else, e.g. Left Control+Right Control. Refer to the board's README file if you are unsure. - -To put a device in bootloader mode with USBaspLoader, tap the `RESET` button while holding down the `BOOT` button. -Alternatively, hold `BOOT` while inserting the USB cable. - -Zadig should automatically detect the bootloader device, but you may sometimes need to check **Options → List All Devices** and select the device from the dropdown instead. - -!> If Zadig lists one or more devices with the `HidUsb` driver, your keyboard is probably not in bootloader mode. The arrow will be colored orange and you will be asked to confirm modifying a system driver. **Do not** proceed if this is the case! - -If the arrow appears green, select the driver, and click **Install Driver**. See the [list of known bootloaders](#list-of-known-bootloaders) for the correct driver to install. - -![Zadig with a bootloader driver correctly installed](https://i.imgur.com/b8VgXzx.png) - -Finally, unplug and replug the keyboard to make sure the new driver has been loaded. If you are using the QMK Toolbox to flash, exit and restart it too, as it can sometimes fail to recognize the driver change. - -## Recovering from Installation to Wrong Device - -If you find that you can no longer type with the keyboard, you may have accidentally replaced the driver for the keyboard itself instead of for the bootloader. This can happen when the keyboard is not in the bootloader mode. You can easily confirm this in Zadig - a healthy keyboard has the `HidUsb` driver installed on all of its interfaces: - -![A healthy keyboard as seen by Zadig](https://i.imgur.com/Hx0E5kC.png) - -Open the Device Manager, select **View → Devices by container**, and look for an entry with your keyboard's name. - -![The board with the wrong driver installed, in Device Manager](https://i.imgur.com/o7WLvBl.png) - -Right-click each entry and hit **Uninstall device**. Make sure to tick **Delete the driver software for this device** first if it appears. - -![The Device Uninstall dialog, with the "delete driver" checkbox ticked](https://i.imgur.com/aEs2RuA.png) - -Click **Action → Scan for hardware changes**. At this point, you should be able to type again. Double check in Zadig that the keyboard device(s) are using the `HidUsb` driver. If so, you're all done, and your board should be functional again! Otherwise, repeat this process until Zadig reports the correct driver. - -?> A full reboot of your computer may sometimes be necessary at this point, to get Windows to pick up the new driver. - -## Uninstallation - -Uninstallation of bootloader devices is a little more involved than installation. - -Open the Device Manager, select **View → Devices by container**, and look for the bootloader device. Match up the USB VID and PID in Zadig with one from [the table below](#list-of-known-bootloaders). - -Find the `Inf name` value in the Details tab of the device properties. This should generally be something like `oemXX.inf`: - -![Device properties showing the Inf name value](https://i.imgur.com/Bu4mk9m.png) - -Then, open a new Command Prompt window as an Administrator (type in `cmd` into the Start menu and press Ctrl+Shift+Enter). Run `pnputil /enum-drivers` to verify the `Inf name` matches the `Published Name` field of one of the entries: - -![pnputil output with matching driver highlighted](https://i.imgur.com/3RrSjzW.png) - -Run `pnputil /delete-driver oemXX.inf /uninstall`. This will delete the driver and remove it from any devices using it. Note that this will not uninstall the device itself. - -As with the previous section, this process may need to be repeated multiple times, as multiple drivers can be applicable to the same device. - -!> **WARNING:** Be *extremely careful* when doing this! You could potentially uninstall the driver for some other critical device. If you are unsure, double check the output of `/enum-drivers`, and omit the `/uninstall` flag when running `/delete-driver`. - -## List of Known Bootloaders - -This is a list of known bootloader devices and their USB vendor and product IDs, as well as the correct driver to assign for flashing with QMK. Note that the usbser and HidUsb drivers are built in to Windows, and cannot be assigned with Zadig - if your device has an incorrect driver, you must use the Device Manager to uninstall it as described in the previous section. - -The device name here is the name that appears in Zadig, and may not be what the Device Manager or QMK Toolbox displays. - -|Bootloader |Device Name |VID/PID |Driver | -|--------------|------------------------------|--------------|-------| -|`atmel-dfu` |ATmega16u2 DFU |`03EB:2FEF` |libusb0| -|`atmel-dfu` |ATmega32U2 DFU |`03EB:2FF0` |libusb0| -|`atmel-dfu` |ATm16U4 DFU V1.0.2 |`03EB:2FF3` |libusb0| -|`atmel-dfu` |ATm32U4DFU |`03EB:2FF4` |libusb0| -|`atmel-dfu` |*none* (AT90USB64) |`03EB:2FF9` |libusb0| -|`atmel-dfu` |AT90USB128 DFU |`03EB:2FFB` |libusb0| -|`qmk-dfu` |(keyboard name) Bootloader |As `atmel-dfu`|libusb0| -|`halfkay` |*none* |`16C0:0478` |HidUsb | -|`caterina` |Pro Micro 3.3V |`1B4F:9203` |usbser | -|`caterina` |Pro Micro 5V |`1B4F:9205` |usbser | -|`caterina` |LilyPadUSB |`1B4F:9207` |usbser | -|`caterina` |Pololu A-Star 32U4 Bootloader |`1FFB:0101` |usbser | -|`caterina` |Arduino Leonardo |`2341:0036` |usbser | -|`caterina` |Arduino Micro |`2341:0037` |usbser | -|`caterina` |Adafruit Feather 32u4 |`239A:000C` |usbser | -|`caterina` |Adafruit ItsyBitsy 32u4 3V |`239A:000D` |usbser | -|`caterina` |Adafruit ItsyBitsy 32u4 5V |`239A:000E` |usbser | -|`caterina` |Arduino Leonardo |`2A03:0036` |usbser | -|`caterina` |Arduino Micro |`2A03:0037` |usbser | -|`bootloadhid` |HIDBoot |`16C0:05DF` |HidUsb | -|`usbasploader`|USBasp |`16C0:05DC` |libusbK| -|`apm32-dfu` |APM32 DFU ISP Mode |`314B:0106` |WinUSB | -|`stm32-dfu` |STM32 BOOTLOADER |`0483:DF11` |WinUSB | -|`gd32v-dfu` |GD32V BOOTLOADER |`28E9:0189` |WinUSB | -|`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB | -|`stm32duino` |Maple 003 |`1EAF:0003` |WinUSB | -|`qmk-hid` |(keyboard name) Bootloader |`03EB:2067` |HidUsb | diff --git a/docs/easy_maker.md b/docs/easy_maker.md deleted file mode 100644 index 6af647381579..000000000000 --- a/docs/easy_maker.md +++ /dev/null @@ -1,31 +0,0 @@ -# Easy Maker - Build One-Off Projects In Configurator - -Have you ever needed an easy way to program a controller, such as a Proton C or Teensy 2.0, for a one-off project you're building? QMK has you covered with the Easy Maker. Now you can create a firmware in minutes using QMK Configurator. - -There are different styles of Easy Maker available depending on your needs: - -* [Direct Pin](https://config.qmk.fm/#/?filter=ez_maker/direct) - Connect a single switch to a single pin -* Direct Pin + Backlight (Coming Soon) - Like Direct Pin but dedicates a single pin to [Backlight](feature_backlight.md) control -* Direct Pin + Numlock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Numlock LED -* Direct Pin + Capslock (Coming Soon) - Like Direct Pin but dedicates a single pin to the Capslock LED -* Direct Pin + Encoder (Coming Soon) - Like Direct Pin but uses 2 pins to add a single rotary encoder - -## Quickstart - -The easiest way to get started is with the Direct Pin boards. This will assign a single key to each pin and you can short that pin to ground to activate it. Select your MCU from the Keyboard dropdown here: - -* - -For more details see the [Direct Pin](#direct-pin) section. - -# Direct Pin - -As its name implies Direct Pin works by connecting one switch per pin. The other side of the switch should be connected to ground (VSS or GND.) You don't need any other components, your MCU has internal pull-up resistors so that the switch sensing can work. - -Here is a schematic showing how we connect a single button to pin A3 on a ProMicro: - -![Schematic diagram showing a ProMicro with a wire coming out of A3, connecting to the left side of a switch. Another wire comes out of the right side of the switch to connect to the Ground Plane.](https://i.imgur.com/JcDhZll.png) - -Once you have wired your switches you can assign keycodes to each pin and build a firmware by selecting the MCU you are using from the Keyboard dropdown. Use this link to show only Easy Maker Direct Pin: - -* diff --git a/docs/eeprom_driver.md b/docs/eeprom_driver.md deleted file mode 100644 index 50d8bcb7b328..000000000000 --- a/docs/eeprom_driver.md +++ /dev/null @@ -1,160 +0,0 @@ -# EEPROM Driver Configuration :id=eeprom-driver-configuration - -The EEPROM driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present. - -Selecting the EEPROM driver is done in your keyboard's `rules.mk`: - -Driver | Description ------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -`EEPROM_DRIVER = vendor` (default) | Uses the on-chip driver provided by the chip manufacturer. For AVR, this is provided by avr-libc. This is supported on ARM for a subset of chips -- STM32F3xx, STM32F1xx, and STM32F072xB will be emulated by writing to flash. STM32L0xx and STM32L1xx will use the onboard dedicated true EEPROM. Other chips will generally act as "transient" below. -`EEPROM_DRIVER = i2c` | Supports writing to I2C-based 24xx EEPROM chips. See the driver section below. -`EEPROM_DRIVER = spi` | Supports writing to SPI-based 25xx EEPROM chips. See the driver section below. -`EEPROM_DRIVER = transient` | Fake EEPROM driver -- supports reading/writing to RAM, and will be discarded when power is lost. -`EEPROM_DRIVER = wear_leveling` | Frontend driver for the wear_leveling system, allowing for EEPROM emulation on top of flash -- both in-MCU and external SPI NOR flash. - -## Vendor Driver Configuration :id=vendor-eeprom-driver-configuration - -#### STM32 L0/L1 Configuration :id=stm32l0l1-eeprom-driver-configuration - -!> Resetting EEPROM using an STM32L0/L1 device takes up to 1 second for every 1kB of internal EEPROM used. - -`config.h` override | Description | Default Value -------------------------------------|--------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------- -`#define STM32_ONBOARD_EEPROM_SIZE` | The size of the EEPROM to use, in bytes. Erase times can be high, so it's configurable here, if not using the default value. | Minimum required to cover base _eeconfig_ data, or `1024` if VIA is enabled. - -## I2C Driver Configuration :id=i2c-eeprom-driver-configuration - -Currently QMK supports 24xx-series chips over I2C. As such, requires a working i2c_master driver configuration. You can override the driver configuration via your config.h: - -`config.h` override | Description | Default Value -------------------------------------------- | ----------------------------------------------------------------------------------- | ------------------------------------ -`#define EXTERNAL_EEPROM_I2C_BASE_ADDRESS` | Base I2C address for the EEPROM -- shifted left by 1 as per i2c_master requirements | 0b10100000 -`#define EXTERNAL_EEPROM_I2C_ADDRESS(addr)` | Calculated I2C address for the EEPROM | `(EXTERNAL_EEPROM_I2C_BASE_ADDRESS)` -`#define EXTERNAL_EEPROM_BYTE_COUNT` | Total size of the EEPROM in bytes | 8192 -`#define EXTERNAL_EEPROM_PAGE_SIZE` | Page size of the EEPROM in bytes, as specified in the datasheet | 32 -`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | The number of bytes to transmit for the memory location within the EEPROM | 2 -`#define EXTERNAL_EEPROM_WRITE_TIME` | Write cycle time of the EEPROM, as specified in the datasheet | 5 -`#define EXTERNAL_EEPROM_WP_PIN` | If defined the WP pin will be toggled appropriately when writing to the EEPROM. | _none_ - -Some I2C EEPROM manufacturers explicitly recommend against hardcoding the WP pin to ground. This is in order to protect the eeprom memory content during power-up/power-down/brown-out conditions at low voltage where the eeprom is still operational, but the i2c master output might be unpredictable. If a WP pin is configured, then having an external pull-up on the WP pin is recommended. - -Default values and extended descriptions can be found in `drivers/eeprom/eeprom_i2c.h`. - -Alternatively, there are pre-defined hardware configurations for available chips/modules: - -Module | Equivalent `#define` | Source ------------------|---------------------------------|------------------------------------------ -CAT24C512 EEPROM | `#define EEPROM_I2C_CAT24C512` | -RM24C512C EEPROM | `#define EEPROM_I2C_RM24C512C` | -24LC32A EEPROM | `#define EEPROM_I2C_24LC32A` | -24LC64 EEPROM | `#define EEPROM_I2C_24LC64` | -24LC128 EEPROM | `#define EEPROM_I2C_24LC128` | -24LC256 EEPROM | `#define EEPROM_I2C_24LC256` | -MB85RC256V FRAM | `#define EEPROM_I2C_MB85RC256V` | - -?> If you find that the EEPROM is not cooperating, ensure you've correctly shifted up your EEPROM address by 1. For example, the datasheet might state the address as `0b01010000` -- the correct value of `EXTERNAL_EEPROM_I2C_BASE_ADDRESS` needs to be `0b10100000`. - -## SPI Driver Configuration :id=spi-eeprom-driver-configuration - -Currently QMK supports 25xx-series chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h: - -`config.h` override | Default Value | Description ------------------------------------------------|---------------|------------------------------------------------------------------------------------- -`#define EXTERNAL_EEPROM_SPI_SLAVE_SELECT_PIN` | _none_ | SPI Slave select pin in order to inform that the EEPROM is currently being addressed -`#define EXTERNAL_EEPROM_SPI_CLOCK_DIVISOR` | `64` | Clock divisor used to divide the peripheral clock to derive the SPI frequency -`#define EXTERNAL_EEPROM_BYTE_COUNT` | `8192` | Total size of the EEPROM in bytes -`#define EXTERNAL_EEPROM_PAGE_SIZE` | `32` | Page size of the EEPROM in bytes, as specified in the datasheet -`#define EXTERNAL_EEPROM_ADDRESS_SIZE` | `2` | The number of bytes to transmit for the memory location within the EEPROM - -!> There's no way to determine if there is an SPI EEPROM actually responding. Generally, this will result in reads of nothing but zero. - -## Transient Driver configuration :id=transient-eeprom-driver-configuration - -The only configurable item for the transient EEPROM driver is its size: - -`config.h` override | Description | Default Value -------------------------------- | ----------------------------------------- | ------------- -`#define TRANSIENT_EEPROM_SIZE` | Total size of the EEPROM storage in bytes | 64 - -Default values and extended descriptions can be found in `drivers/eeprom/eeprom_transient.h`. - -## Wear-leveling Driver Configuration :id=wear_leveling-eeprom-driver-configuration - -The wear-leveling driver uses an algorithm to minimise the number of erase cycles on the underlying MCU flash memory. - -There is no specific configuration for this driver, but the wear-leveling system used by this driver may need configuration. See the [wear-leveling configuration](#wear_leveling-configuration) section for more information. - -# Wear-leveling Configuration :id=wear_leveling-configuration - -The wear-leveling driver has a few possible _backing stores_ that may be used by adding to your keyboard's `rules.mk` file: - -Driver | Description -----------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ -`WEAR_LEVELING_DRIVER = embedded_flash` | This driver is used for emulating EEPROM by writing to embedded flash on the MCU. -`WEAR_LEVELING_DRIVER = spi_flash` | This driver is used to address external SPI NOR Flash peripherals. -`WEAR_LEVELING_DRIVER = rp2040_flash` | This driver is used to write to the same storage the RP2040 executes code from. -`WEAR_LEVELING_DRIVER = legacy` | This driver is the "legacy" emulated EEPROM provided in historical revisions of QMK. Currently used for STM32F0xx and STM32F4x1, but slated for deprecation and removal once `embedded_flash` support for those MCU families is complete. - -!> All wear-leveling drivers require an amount of RAM equivalent to the selected logical EEPROM size. Increasing the size to 32kB of EEPROM requires 32kB of RAM, which a significant number of MCUs simply do not have. - -## Wear-leveling Embedded Flash Driver Configuration :id=wear_leveling-efl-driver-configuration - -This driver performs writes to the embedded flash storage embedded in the MCU. In most circumstances, the last few of sectors of flash are used in order to minimise the likelihood of collision with program code. - -Configurable options in your keyboard's `config.h`: - -`config.h` override | Default | Description ------------------------------------------|-------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -`#define WEAR_LEVELING_EFL_FIRST_SECTOR` | _unset_ | The first sector on the MCU to use. By default this is not defined and calculated at runtime based on the MCU. However, different flash sizes on MCUs may require custom configuration. -`#define WEAR_LEVELING_EFL_FLASH_SIZE` | _unset_ | Allows overriding the flash size available for use for wear-leveling. Under normal circumstances this is automatically calculated and should not need to be overridden. Specifying a size larger than the amount actually available in flash will usually prevent the MCU from booting. -`#define WEAR_LEVELING_LOGICAL_SIZE` | `1024` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. -`#define WEAR_LEVELING_BACKING_SIZE` | `2048` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size. -`#define BACKING_STORE_WRITE_SIZE` | _automatic_ | The byte width of the underlying write used on the MCU, and is usually automatically determined from the selected MCU family. If an error occurs in the auto-detection, you'll need to consult the MCU's datasheet and determine this value, specifying it directly. - -!> If your MCU does not boot after swapping to the EFL wear-leveling driver, it's likely that the flash size is incorrectly detected, usually as an MCU with larger flash and may require overriding. - -## Wear-leveling SPI Flash Driver Configuration :id=wear_leveling-flash_spi-driver-configuration - -This driver performs writes to an external SPI NOR Flash peripheral. It also requires a working configuration for the SPI NOR Flash peripheral -- see the [flash driver](flash_driver.md) documentation for more information. - -Configurable options in your keyboard's `config.h`: - -`config.h` override | Default | Description -----------------------------------------------------|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------- -`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_COUNT` | `1` | Number of blocks in the external flash used by the wear-leveling algorithm. -`#define WEAR_LEVELING_EXTERNAL_FLASH_BLOCK_OFFSET` | `0` | The index first block in the external flash used by the wear-leveling algorithm. -`#define WEAR_LEVELING_LOGICAL_SIZE` | `((block_count*block_size)/2)` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. Result must be <= 64kB. -`#define WEAR_LEVELING_BACKING_SIZE` | `(block_count*block_size)` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size. -`#define BACKING_STORE_WRITE_SIZE` | `8` | The write width used whenever a write is performed on the external flash peripheral. - -!> There is currently a limit of 64kB for the EEPROM subsystem within QMK, so using a larger flash is not going to be beneficial as the logical size cannot be increased beyond 65536. The backing size may be increased to a larger value, but erase timing may suffer as a result. - -## Wear-leveling RP2040 Driver Configuration :id=wear_leveling-rp2040-driver-configuration - -This driver performs writes to the same underlying storage that the RP2040 executes its code. - -Configurable options in your keyboard's `config.h`: - -`config.h` override | Default | Description -------------------------------------------|----------------------------|-------------------------------------------------------------------------------------------------------------------------------- -`#define WEAR_LEVELING_RP2040_FLASH_SIZE` | `PICO_FLASH_SIZE_BYTES` | Number of bytes of flash on the board. -`#define WEAR_LEVELING_RP2040_FLASH_BASE` | `(flash_size-sector_size)` | The byte-wise location that the backing storage should be located. -`#define WEAR_LEVELING_LOGICAL_SIZE` | `4096` | Number of bytes "exposed" to the rest of QMK and denotes the size of the usable EEPROM. -`#define WEAR_LEVELING_BACKING_SIZE` | `8192` | Number of bytes used by the wear-leveling algorithm for its underlying storage, and needs to be a multiple of the logical size as well as the sector size. -`#define BACKING_STORE_WRITE_SIZE` | `2` | The write width used whenever a write is performed on the external flash peripheral. - -## Wear-leveling Legacy EEPROM Emulation Driver Configuration :id=wear_leveling-legacy-driver-configuration - -This driver performs writes to the embedded flash storage embedded in the MCU much like the normal Embedded Flash Driver, and is only for use with STM32F0xx and STM32F4x1 devices. This flash implementation is still currently provided as the EFL driver is currently non-functional for the previously mentioned families. - -By default, `1024` bytes of emulated EEPROM is provided: - -MCU | EEPROM Provided | Flash Used -----------|-----------------|-------------- -STM32F042 | `1024` bytes | `2048` bytes -STM32F070 | `1024` bytes | `2048` bytes -STM32F072 | `1024` bytes | `2048` bytes -STM32F401 | `1024` bytes | `16384` bytes -STM32F411 | `1024` bytes | `16384` bytes - -Under normal circumstances configuration of this driver requires intimate knowledge of the MCU's flash structure -- reconfiguration is at your own risk and will require referring to the code. diff --git a/docs/faq_build.md b/docs/faq_build.md deleted file mode 100644 index b86f2177a041..000000000000 --- a/docs/faq_build.md +++ /dev/null @@ -1,69 +0,0 @@ -# Frequently Asked Build Questions - -This page covers questions about building QMK. If you haven't yet done so, you should read the [Build Environment Setup](getting_started_build_tools.md) and [Make Instructions](getting_started_make_guide.md) guides. - -## Can't Program on Linux -You will need proper permissions to operate a device. For Linux users, see the instructions regarding `udev` rules, below. If you have issues with `udev`, a work-around is to use the `sudo` command. If you are not familiar with this command, check its manual with `man sudo` or [see this webpage](https://linux.die.net/man/8/sudo). - -An example of using `sudo`, when your controller is ATMega32u4: - - $ sudo dfu-programmer atmega32u4 erase --force - $ sudo dfu-programmer atmega32u4 flash your.hex - $ sudo dfu-programmer atmega32u4 reset - -or just: - - $ sudo make ::flash - -Note that running `make` with `sudo` is generally ***not*** a good idea, and you should use one of the former methods, if possible. - -### Linux `udev` Rules :id=linux-udev-rules - -On Linux, you'll need proper privileges to communicate with the bootloader device. You can either use `sudo` when flashing firmware (not recommended), or place [this file](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) into `/etc/udev/rules.d/`. - -Once added, run the following: - -``` -sudo udevadm control --reload-rules -sudo udevadm trigger -``` - -**Note:** With older versions of ModemManager (< 1.12), filtering only works when not in strict mode. The following commands can update that setting: - -``` -printf '[Service]\nExecStart=\nExecStart=/usr/sbin/ModemManager --filter-policy=default' | sudo tee /etc/systemd/system/ModemManager.service.d/policy.conf -sudo systemctl daemon-reload -sudo systemctl restart ModemManager -``` - -### Serial device is not detected in bootloader mode on Linux -Make sure your kernel has appropriate support for your device. If your device uses USB ACM, such as -Pro Micro (Atmega32u4), make sure to include `CONFIG_USB_ACM=y`. Other devices may require `USB_SERIAL` and any of its sub options. - -## Unknown Device for DFU Bootloader - -Issues encountered when flashing keyboards on Windows are most often due to having the wrong drivers installed for the bootloader, or none at all. - -Re-running the QMK installation script (`./util/qmk_install.sh` from the `qmk_firmware` directory in MSYS2 or WSL) or reinstalling the QMK Toolbox may fix the issue. Alternatively, you can download and run the [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) package manually. - -If that doesn't work, then you may need to download and run Zadig. See [Bootloader Driver Installation with Zadig](driver_installation_zadig.md) for more detailed information. - -## USB VID and PID -You can use any ID you want with editing `config.h`. Using any presumably unused ID will be no problem in fact except for very low chance of collision with other product. - -Most boards in QMK use `0xFEED` as the vendor ID. You should look through other keyboards to make sure you pick a unique Product ID. - -Also see this. -https://github.com/tmk/tmk_keyboard/issues/150 - -You can buy a really unique VID:PID here. I don't think you need this for personal use. -- https://www.obdev.at/products/vusb/license.html -- https://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 - -### I just flashed my keyboard and it does nothing/keypresses don't register - it's also ARM (rev6 planck, clueboard 60, hs60v2, etc...) (Feb 2019) -Due to how EEPROM works on ARM based chips, saved settings may no longer be valid. This affects the default layers, and *may*, under certain circumstances we are still figuring out, make the keyboard unusable. Resetting the EEPROM will correct this. - -[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) can be used to force an eeprom reset. After flashing this image, flash your normal firmware again which should restore your keyboard to _normal_ working order. -[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) - -If bootmagic is enabled in any form, you should be able to do this too (see [Bootmagic docs](feature_bootmagic.md) and keyboard info for specifics on how to do this). diff --git a/docs/faq_debug.md b/docs/faq_debug.md deleted file mode 100644 index cad98bc33171..000000000000 --- a/docs/faq_debug.md +++ /dev/null @@ -1,136 +0,0 @@ -# Debugging FAQ - -This page details various common questions people have about troubleshooting their keyboards. - -## Debugging :id=debugging - -Your keyboard will output debug information if you have `CONSOLE_ENABLE = yes` in your `rules.mk`. By default the output is very limited, but you can turn on debug mode to increase the amount of debug output. Use the `DB_TOGG` keycode in your keymap, use the [Command](feature_command.md) feature to enable debug mode, or add the following code to your keymap. - -```c -void keyboard_post_init_user(void) { - // Customise these values to desired behaviour - debug_enable=true; - debug_matrix=true; - //debug_keyboard=true; - //debug_mouse=true; -} -``` - -## Debugging Tools - -Various tools are available to debug your keyboard. - -### Debugging With QMK Toolbox - -For compatible platforms, [QMK Toolbox](https://github.com/qmk/qmk_toolbox) can be used to display debug messages from your keyboard. - -### Debugging with QMK CLI - -Prefer a terminal based solution? The [QMK CLI console command](cli_commands.md#qmk-console) can be used to display debug messages from your keyboard. - -### Debugging With hid_listen - -Something stand-alone? [hid_listen](https://www.pjrc.com/teensy/hid_listen.html), provided by PJRC, can also be used to display debug messages. Prebuilt binaries for Windows,Linux,and MacOS are available. - -## Sending Your Own Debug Messages :id=debug-api - -Sometimes it's useful to print debug messages from within your [custom code](custom_quantum_functions.md). Doing so is pretty simple. Start by including `print.h` at the top of your file: - -```c -#include "print.h" -``` - -After that you can use a few different print functions: - -* `print("string")`: Print a simple string. -* `uprintf("%s string", var)`: Print a formatted string -* `dprint("string")` Print a simple string, but only when debug mode is enabled -* `dprintf("%s string", var)`: Print a formatted string, but only when debug mode is enabled - -## Debug Examples - -Below is a collection of real world debugging examples. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md). - -### Which matrix position is this keypress? - -When porting, or when attempting to diagnose pcb issues, it can be useful to know if a keypress is scanned correctly. To enable logging for this scenario, add the following code to your keymaps `keymap.c` - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - // If console is enabled, it will print the matrix position and status of each key pressed -#ifdef CONSOLE_ENABLE - uprintf("KL: kc: 0x%04X, col: %2u, row: %2u, pressed: %u, time: %5u, int: %u, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count); -#endif - return true; -} -``` - -Example output -``` -Waiting for device:....... -Listening: -KL: kc: 169, col: 0, row: 0, pressed: 1, time: 15505, int: 0, count: 0 -KL: kc: 169, col: 0, row: 0, pressed: 0, time: 15510, int: 0, count: 0 -KL: kc: 174, col: 1, row: 0, pressed: 1, time: 15703, int: 0, count: 0 -KL: kc: 174, col: 1, row: 0, pressed: 0, time: 15843, int: 0, count: 0 -KL: kc: 172, col: 2, row: 0, pressed: 1, time: 16303, int: 0, count: 0 -KL: kc: 172, col: 2, row: 0, pressed: 0, time: 16411, int: 0, count: 0 -``` - -### How long did it take to scan for a keypress? - -When testing performance issues, it can be useful to know the frequency at which the switch matrix is being scanned. To enable logging for this scenario, add the following code to your keymaps `config.h` - -```c -#define DEBUG_MATRIX_SCAN_RATE -``` - -Example output -``` - > matrix scan frequency: 315 - > matrix scan frequency: 313 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 -``` - -## `hid_listen` Can't Recognize Device -When debug console of your device is not ready you will see like this: - -``` -Waiting for device:......... -``` - -Once the device is plugged in then *hid_listen* finds it you will get this message: - -``` -Waiting for new device:......................... -Listening: -``` - -If you can't get this 'Listening:' message try building with `CONSOLE_ENABLE=yes` in [Makefile] - -You may need privileges to access the device an OS like Linux. Try `sudo hid_listen`. - -On many Linux distros you can avoid having to run hid_listen as root -by creating a file called `/etc/udev/rules.d/70-hid-listen.rules` with -the following content: - -``` -SUBSYSTEM=="hidraw", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="def1", TAG+="uaccess", RUN{builtin}+="uaccess" -``` - -Replace abcd and def1 with your keyboard's vendor and product id, -letters must be lowercase. The `RUN{builtin}+="uaccess"` part is only -needed for older distros. - - -## Can't Get Message on Console -Check: -- *hid_listen* finds your device. See above. -- Enable debug by pressing **Magic**+d. See [Magic Commands](https://github.com/tmk/tmk_keyboard#magic-commands). -- Set `debug_enable=true`. See [Debugging](#debugging) -- Try using `print` function instead of debug print. See **common/print.h**. -- Disconnect other devices with console function. See [Issue #97](https://github.com/tmk/tmk_keyboard/issues/97). -- Ensure all strings end with a newline character (`\n`). QMK Toolbox prints console output on a per-line basis. diff --git a/docs/faq_general.md b/docs/faq_general.md deleted file mode 100644 index 56b150da29b0..000000000000 --- a/docs/faq_general.md +++ /dev/null @@ -1,53 +0,0 @@ -# Frequently Asked Questions - -## What is QMK? - -[QMK](https://github.com/qmk), short for Quantum Mechanical Keyboard, is a group of people building tools for custom keyboards. We started with the [QMK firmware](https://github.com/qmk/qmk_firmware), a heavily modified fork of [TMK](https://github.com/tmk/tmk_keyboard). - -## I don't know where to start! - -If this is the case, then you should start with our [Newbs Guide](newbs.md). There is a lot of great info there, and that should cover everything you need to get started. - -If that's an issue, hop onto the [QMK Configurator](https://config.qmk.fm), as that will handle a majority of what you need there. - -## How can I flash the firmware I built? - -First, head to the [Compiling/Flashing FAQ Page](faq_build.md). There is a good deal of info there, and you'll find a bunch of solutions to common issues there. - -## What if I have an issue that isn't covered here? - -Okay, that's fine. Then please check the [open issues in our GitHub](https://github.com/qmk/qmk_firmware/issues) to see if somebody is experiencing the same thing (make sure it's not just similar, but actually the same). - -If you can't find anything, then please open a [new issue](https://github.com/qmk/qmk_firmware/issues/new)! - -## What if I found a bug? - -Then please open an [issue](https://github.com/qmk/qmk_firmware/issues/new), and if you know how to fix it, open up a Pull Request on GitHub with the fix. - -## But `git` and `GitHub` are intimidating! - -Don't worry, we have some pretty nice [Guidelines](newbs_git_best_practices.md) on how to start using `git` and GitHub to make things easier to develop. - -Additionally, you can find additional `git` and GitHub related links [here](newbs_learn_more_resources.md). - -## I have a Keyboard that I want to add support for - -Awesome! Open up a Pull Request for it. We'll review the code, and merge it! - -### What if I want to brand it with `QMK`? - -That's amazing! We would love to assist you with that! - -In fact, we have a [whole page](https://qmk.fm/powered/) dedicated to adding QMK Branding to your page and keyboard. This covers pretty much everything you need (knowledge and images) to officially support QMK. - -If you have any questions about this, open an issue or head to [Discord](https://discord.gg/Uq7gcHh). - -## What Differences Are There Between QMK and TMK? - -TMK was originally designed and implemented by [Jun Wako](https://github.com/tmk). QMK started as [Jack Humbert](https://github.com/jackhumbert)'s fork of TMK for the Planck. After a while Jack's fork had diverged quite a bit from TMK, and in 2015 Jack decided to rename his fork to QMK. - -From a technical standpoint QMK builds upon TMK by adding several new features. Most notably QMK has expanded the number of available keycodes and uses these to implement advanced features like `S()`, `LCTL()`, and `MO()`. You can see a complete list of these keycodes in [Keycodes](keycodes.md). - -From a project and community management standpoint TMK maintains all the officially supported keyboards by himself, with a bit of community support. Separate community maintained forks exist or can be created for other keyboards. Only a few keymaps are provided by default, so users typically don't share keymaps with each other. QMK encourages sharing of both keyboards and keymaps through a centrally managed repository, accepting all pull requests that follow the quality standards. These are mostly community maintained, but the QMK team also helps when necessary. - -Both approaches have their merits and their drawbacks, and code flows freely between TMK and QMK when it makes sense. diff --git a/docs/faq_keymap.md b/docs/faq_keymap.md deleted file mode 100644 index 864128183508..000000000000 --- a/docs/faq_keymap.md +++ /dev/null @@ -1,151 +0,0 @@ -# Keymap FAQ - -This page covers questions people often have about keymaps. If you haven't you should read [Keymap Overview](keymap.md) first. - -## What Keycodes Can I Use? - -See [Keycodes](keycodes.md) for an index of keycodes available to you. These link to more extensive documentation when available. - -Keycodes are actually defined in [quantum/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h). - -## What Are the Default Keycodes? - -There are 3 standard keyboard layouts in use around the world- ANSI, ISO, and JIS. North America primarily uses ANSI, Europe and Africa primarily use ISO, and Japan uses JIS. Regions not mentioned typically use either ANSI or ISO. The keycodes corresponding to these layouts are shown here: - - -![Keyboard Layout Image](https://i.imgur.com/5wsh5wM.png) - -## How Can I Make Custom Names For Complex Keycodes? - -Sometimes, for readability's sake, it's useful to define custom names for some keycodes. People often define custom names using `#define`. For example: - -```c -#define FN_CAPS LT(_FL, KC_CAPS) -#define ALT_TAB LALT(KC_TAB) -``` - -This will allow you to use `FN_CAPS` and `ALT_TAB` in your keymap, keeping it more readable. - -## My Keymap Doesn't Update When I Flash It - -This is usually due to VIA, and has to do with how it deals with keymaps. - -On first run, the VIA code in the firmware will copy the keymap from flash memory into EEPROM so that it can be rewritten at runtime by the VIA app. From this point QMK will use the keymap stored in EEPROM instead of flash, and so updates to your `keymap.c` will not be reflected. - -The simple fix for this is to clear the EEPROM. You can do this in several ways: - -* Hold the Bootmagic Lite key (usually top left/Escape) while plugging the board in, which will also place the board into bootloader mode; then unplug and replug the board. -* Press the `QK_CLEAR_EEPROM`/`EE_CLR` keycode if it is accessible on your keymap. -* Place the board into bootloader mode and hit the "Clear EEPROM" button. This may not be available for all bootloaders, and you may need to reflash the board afterwards. - -## Some Of My Keys Are Swapped Or Not Working - -QMK has a couple of features which allow you to change the behavior of your keyboard on the fly. This includes, but is not limited to, swapping Ctrl/Caps, disabling GUI, swapping Alt/GUI, swapping Backspace/Backslash, disabling all keys, and other behavioral modifications. - -Refer to the EEPROM clearing methods above, which should return those keys to normal operation. If that doesn't work, look here: - -* [Magic Keycodes](keycodes_magic.md) -* [Command](feature_command.md) - -## The Menu Key Isn't Working - -The key found on most modern keyboards that is located between `KC_RGUI` and `KC_RCTL` is actually called `KC_APP`. This is because when the key was invented, there was already a key named "Menu" in the HID specification, so for whatever reason, Microsoft chose to create a new key and call it "Application". - -## Power Keys Aren't Working - -Somewhat confusingly, there are two "Power" keycodes in QMK: `KC_KB_POWER` in the Keyboard/Keypad HID usage page, and `KC_SYSTEM_POWER` (or `KC_PWR`) in the Consumer page. - -The former is only recognized on macOS, while the latter, `KC_SLEP` and `KC_WAKE` are supported by all three major operating systems, so it is recommended to use those instead. Under Windows, these keys take effect immediately, however on macOS they must be held down until a dialog appears. - -## One Shot Modifier - -Solves my personal 'the' problem. I often got 'the' or 'THe' wrongly instead of 'The'. One Shot Shift mitigates this for me. -https://github.com/tmk/tmk_keyboard/issues/67 - -## Modifier/Layer Stuck - -Modifier keys or layers can be stuck unless layer switching is configured properly. -For Modifier keys and layer actions you have to place `KC_TRNS` on same position of destination layer to unregister the modifier key or return to previous layer on release event. - -* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching -* https://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 -* https://github.com/tmk/tmk_keyboard/issues/248 - -## Mechanical Lock Switch Support - -This feature is for *mechanical lock switch* like [this Alps one](https://deskthority.net/wiki/Alps_SKCL_Lock). You can enable it by adding this to your `config.h`: - -```c -#define LOCKING_SUPPORT_ENABLE -#define LOCKING_RESYNC_ENABLE -``` - -After enabling this feature use keycodes `KC_LCAP`, `KC_LNUM` and `KC_LSCR` in your keymap instead. - -Old vintage mechanical keyboards occasionally have lock switches but modern ones don't have. ***You don't need this feature in most case and just use keycodes `KC_CAPS`, `KC_NUM` and `KC_SCRL`.*** - -## Input Special Characters Other Than ASCII like Cédille 'Ç' - -See the [Unicode](feature_unicode.md) feature. - -## `Fn` Key on macOS - -Unlike most Fn keys, the one on Apple keyboards actually has its own keycode... sort of. It takes the place of the sixth keycode in a basic 6KRO HID report -- so an Apple keyboard is in fact only 5KRO. - -It is technically possible to get QMK to send this key. However, doing so requires modification of the report format to add the state of the Fn key. -Even worse, it is not recognized unless the keyboard's VID and PID match that of a real Apple keyboard. The legal issues that official QMK support for this feature may create mean it is unlikely to happen. - -See [this issue](https://github.com/qmk/qmk_firmware/issues/2179) for detailed information. - -## Keys Supported in Mac OSX? - -You can know which keycodes are supported in OSX from this source code. - -`usb_2_adb_keymap` array maps Keyboard/Keypad Page usages to ADB scancodes(OSX internal keycodes). - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c - -And `IOHIDConsumer::dispatchConsumerEvent` handles Consumer page usages. - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp - -## JIS Keys in Mac OSX - -Japanese JIS keyboard specific keys like `無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` are not recognized on OSX. You can use **Seil** to enable those keys, try following options. - -* Enable NFER Key on PC keyboard -* Enable XFER Key on PC keyboard -* Enable KATAKANA Key on PC keyboard - -https://pqrs.org/osx/karabiner/seil.html - -## RN-42 Bluetooth Doesn't Work with Karabiner - -Karabiner - Keymapping tool on Mac OSX - ignores inputs from RN-42 module by default. You have to enable this option to make Karabiner working with your keyboard. -https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 - -See these for the detail of this problem. -https://github.com/tmk/tmk_keyboard/issues/213 -https://github.com/tekezo/Karabiner/issues/403 - -## Esc and ` on a Single Key - -See the [Grave Escape](feature_grave_esc.md) feature. - -## Eject on Mac OSX - -`KC_EJCT` keycode works on OSX. https://github.com/tmk/tmk_keyboard/issues/250 -It seems Windows 10 ignores the code and Linux/Xorg recognizes but has no mapping by default. - -Not sure what keycode Eject is on genuine Apple keyboard actually. HHKB uses `F20` for Eject key(`Fn+F`) on Mac mode but this is not same as Apple Eject keycode probably. - -## What are "Real" and "Weak" modifiers? - -Real modifiers refer to the state of the real/physical modifier keys, while weak modifiers are the state of "virtual" or temporary modifiers which should not interfere with the internal state of the real modifier keys. - -The real and weak modifier states are ORed together when the keyboard report is sent, so if you release a weak modifier while the same real modifier is still held, the report does not change: - - 1. **Hold down physical Left Shift:** Real mods now contains Left Shift, final state is Left Shift - 2. **Add weak Left Shift:** Weak mods now contains Left Shift, final state is Left Shift - 3. **Remove weak Left Shift:** Weak mods now contains nothing, final state is Left Shift - 4. **Release physical Left Shift:** Real mods now contains nothing, final state is nothing diff --git a/docs/faq_misc.md b/docs/faq_misc.md deleted file mode 100644 index 287ca7711d13..000000000000 --- a/docs/faq_misc.md +++ /dev/null @@ -1,113 +0,0 @@ -# Miscellaneous FAQ - -## How do I test my keyboard? :id=testing - -Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK. - -## Safety Considerations - -You probably don't want to "brick" your keyboard, making it impossible -to rewrite firmware onto it. Here are some of the parameters to show -what things are (and likely aren't) too risky. - -- If your keyboard map does not include QK_BOOT, then, to get into DFU - mode, you will need to press the reset button on the PCB, which - requires unscrewing the bottom. -- Messing with tmk_core / common files might make the keyboard - inoperable -- Too large a .hex file is trouble; `make dfu` will erase the block, - test the size (oops, wrong order!), which errors out, failing to - flash the keyboard, leaving it in DFU mode. - - To this end, note that the maximum .hex file size on e.g. Planck - is 7000h (28672 decimal) - -``` -Linking: .build/planck_rev4_cbbrowne.elf [OK] -Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] - -Size after: - text data bss dec hex filename - 0 22396 0 22396 577c planck_rev4_cbbrowne.hex -``` - - - The above file is of size 22396/577ch, which is less than - 28672/7000h - - As long as you have a suitable alternative .hex file around, you - can retry, loading that one - - Some of the options you might specify in your keyboard's Makefile - consume extra memory; watch out for BOOTMAGIC_ENABLE, - MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE -- DFU tools do /not/ allow you to write into the bootloader (unless - you throw in an extra fruit salad of options), so there is little risk - there. -- EEPROM has around a 100000 (100k) write cycle. You shouldn't rewrite - the firmware repeatedly and continually; that'll burn the EEPROM - eventually. - -## NKRO Doesn't work -First you have to compile firmware with the build option `NKRO_ENABLE` in **Makefile**. - -Try `Magic` **N** command(`LShift+RShift+N` by default) when **NKRO** still doesn't work. You can use this command to toggle between **NKRO** and **6KRO** mode temporarily. In some situations **NKRO** doesn't work and you will need to switch to **6KRO** mode, in particular when you are in BIOS. - - -## TrackPoint Needs Reset Circuit (PS/2 Mouse Support) -Without reset circuit you will have inconsistent result due to improper initialization of the hardware. See circuit schematic of TPM754: - -- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 -- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf - - -## Can't Read Column of Matrix Beyond 16 -Use `1UL<<16` instead of `1<<16` in `read_cols()` in [matrix.h] when your columns goes beyond 16. - -In C `1` means one of [int] type which is [16 bit] in case of AVR, so you can't shift left more than 15. Thus, calculating `1<<16` will unexpectedly equal zero. To work around this, you have to use [unsigned long] type with `1UL`. - -https://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 - -## Special Extra Key Doesn't Work (System, Audio Control Keys) -You need to define `EXTRAKEY_ENABLE` in `rules.mk` to use them in QMK. - -``` -EXTRAKEY_ENABLE = yes # Audio control and System control -``` - -## Wake from Sleep Doesn't Work - -In Windows check `Allow this device to wake the computer` setting in **Power Management** property tab of **Device Manager**. Also check your BIOS settings. Pressing any key during sleep should wake host. - -## Using Arduino? - -**Note that Arduino pin naming is different from actual chip.** For example, Arduino pin `D0` is not `PD0`. Check circuit with its schematics yourself. - -- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf -- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf - -Arduino Leonardo and micro have **ATMega32U4** and can be used for TMK, though Arduino bootloader may be a problem. - -## Enabling JTAG - -By default, the JTAG debugging interface is disabled as soon as the keyboard starts up. JTAG-capable MCUs come from the factory with the `JTAGEN` fuse set, and it takes over certain pins of the MCU that the board may be using for the switch matrix, LEDs, etc. - -If you would like to keep JTAG enabled, just add the following to your `config.h`: - -```c -#define NO_JTAG_DISABLE -``` - -## USB 3 Compatibility -Some problems can be fixed by switching from a USB 3.x port to a USB 2.0 port. - - -## Mac Compatibility -### OS X 10.11 and Hub -See here: https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 - - -## Problem in BIOS (UEFI) Setup/Resume (Sleep & Wake)/Power Cycles -Some people reported their keyboard stops working in BIOS and/or after resume(power cycles). - -As of now the root cause is not clear, but some build options seem to be related. In Makefile, try to disable options like `CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE` and/or others. - -More info: -- https://github.com/tmk/tmk_keyboard/issues/266 -- https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/docs/feature_advanced_keycodes.md b/docs/feature_advanced_keycodes.md deleted file mode 100644 index 171243301d39..000000000000 --- a/docs/feature_advanced_keycodes.md +++ /dev/null @@ -1,187 +0,0 @@ -# Modifier Keys :id=modifier-keys - -These allow you to combine a modifier with a keycode. When pressed, the keydown event for the modifier, then `kc` will be sent. On release, the keyup event for `kc`, then the modifier will be sent. - -|Key |Aliases |Description | -|----------|----------------------------------|------------------------------------------------------| -|`LCTL(kc)`|`C(kc)` |Hold Left Control and press `kc` | -|`LSFT(kc)`|`S(kc)` |Hold Left Shift and press `kc` | -|`LALT(kc)`|`A(kc)`, `LOPT(kc)` |Hold Left Alt and press `kc` | -|`LGUI(kc)`|`G(kc)`, `LCMD(kc)`, `LWIN(kc)` |Hold Left GUI and press `kc` | -|`RCTL(kc)`| |Hold Right Control and press `kc` | -|`RSFT(kc)`| |Hold Right Shift and press `kc` | -|`RALT(kc)`|`ROPT(kc)`, `ALGR(kc)` |Hold Right Alt and press `kc` | -|`RGUI(kc)`|`RCMD(kc)`, `LWIN(kc)` |Hold Right GUI and press `kc` | -|`LSG(kc)` |`SGUI(kc)`, `SCMD(kc)`, `SWIN(kc)`|Hold Left Shift and GUI and press `kc` | -|`LAG(kc)` | |Hold Left Alt and Left GUI and press `kc` | -|`RSG(kc)` | |Hold Right Shift and Right GUI and press `kc` | -|`RAG(kc)` | |Hold Right Alt and Right GUI and press `kc` | -|`LCA(kc)` | |Hold Left Control and Alt and press `kc` | -|`LSA(kc)` | |Hold Left Shift and Left Alt and press `kc` | -|`RSA(kc)` |`SAGR(kc)` |Hold Right Shift and Right Alt (AltGr) and press `kc` | -|`RCS(kc)` | |Hold Right Control and Right Shift and press `kc` | -|`LCAG(kc)`| |Hold Left Control, Alt and GUI and press `kc` | -|`MEH(kc)` | |Hold Left Control, Shift and Alt and press `kc` | -|`HYPR(kc)`| |Hold Left Control, Shift, Alt and GUI and press `kc` | - -You can also chain them, for example `LCTL(LALT(KC_DEL))` or `C(A(KC_DEL))` makes a key that sends Control+Alt+Delete with a single keypress. - -# Checking Modifier State :id=checking-modifier-state - -The current modifier state can mainly be accessed with two functions: `get_mods()` for normal modifiers and modtaps and `get_oneshot_mods()` for one-shot modifiers (unless they're held, in which case they act like normal modifier keys). - -The presence of one or more specific modifiers in the current modifier state can be detected by ANDing the modifier state with a mod mask corresponding to the set of modifiers you want to match for. The reason why bitwise operators are used is that the modifier state is stored as a single byte in the format (GASC)R(GASC)L. - -Thus, to give an example, `01000010` would be the internal representation of LShift+RAlt. -For more information on bitwise operators in C, click [here](https://en.wikipedia.org/wiki/Bitwise_operations_in_C) to open the Wikipedia page on the topic. - -In practice, this means that you can check whether a given modifier is active with `get_mods() & MOD_BIT(KC_)` (see the [list of modifier keycodes](keycodes_basic.md#modifiers)) or with `get_mods() & MOD_MASK_` if the difference between left and right hand modifiers is not important and you want to match both. Same thing can be done for one-shot modifiers if you replace `get_mods()` with `get_oneshot_mods()`. - -To check that *only* a specific set of mods is active at a time, use a simple equality operator: `get_mods() == `. - -For example, let's say you want to trigger a piece of custom code if one-shot left control and one-shot left shift are on but every other one-shot mods are off. To do so, you can compose the desired mod mask by combining the mod bits for left control and shift with `(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` and then plug it in: `get_oneshot_mods() == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`. Using `MOD_MASK_CS` instead for the mod bitmask would have forced you to press four modifier keys (both versions of control and shift) to fulfill the condition. - -The full list of mod masks is as follows: - -| Mod Mask Name | Matching Modifiers | -|--------------------|------------------------------------------------| -| `MOD_MASK_CTRL` | LCTRL , RCTRL | -| `MOD_MASK_SHIFT` | LSHIFT , RSHIFT | -| `MOD_MASK_ALT` | LALT , RALT | -| `MOD_MASK_GUI` | LGUI , RGUI | -| `MOD_MASK_CS` | CTRL , SHIFT | -| `MOD_MASK_CA` | (L/R)CTRL , (L/R)ALT | -| `MOD_MASK_CG` | (L/R)CTRL , (L/R)GUI | -| `MOD_MASK_SA` | (L/R)SHIFT , (L/R)ALT | -| `MOD_MASK_SG` | (L/R)SHIFT , (L/R)GUI | -| `MOD_MASK_AG` | (L/R)ALT , (L/R)GUI | -| `MOD_MASK_CSA` | (L/R)CTRL , (L/R)SHIFT , (L/R)ALT | -| `MOD_MASK_CSG` | (L/R)CTRL , (L/R)SHIFT , (L/R)GUI | -| `MOD_MASK_CAG` | (L/R)CTRL , (L/R)ALT , (L/R)GUI | -| `MOD_MASK_SAG` | (L/R)SHIFT , (L/R)ALT , (L/R)GUI | -| `MOD_MASK_CSAG` | (L/R)CTRL , (L/R)SHIFT , (L/R)ALT , (L/R)GUI | - -Aside from accessing the currently active modifiers using `get_mods()`, there exists some other functions you can use to modify the modifier state, where the `mods` argument refers to the modifiers bitmask. - -* `add_mods(mods)`: Enable `mods` without affecting any other modifiers -* `register_mods(mods)`: Like `add_mods` but send a keyboard report immediately. -* `del_mods(mods)`: Disable `mods` without affecting any other modifiers -* `unregister_mods(mods)`: Like `del_mods` but send a keyboard report immediately. -* `set_mods(mods)`: Overwrite current modifier state with `mods` -* `clear_mods()`: Reset the modifier state by disabling all modifiers - -Similarly, in addition to `get_oneshot_mods()`, there also exists these functions for one-shot mods: - -* `add_oneshot_mods(mods)`: Enable `mods` without affecting any other one-shot modifiers -* `del_oneshot_mods(mods)`: Disable `mods` without affecting any other one-shot modifiers -* `set_oneshot_mods(mods)`: Overwrite current one-shot modifier state with `mods` -* `clear_oneshot_mods()`: Reset the one-shot modifier state by disabling all one-shot modifiers - -## Examples :id=examples - -The following examples use [advanced macro functions](feature_macros.md#advanced-macro-functions) which you can read more about in the [documentation page on macros](feature_macros.md). - -### Alt + Escape for Alt + Tab :id=alt-escape-for-alt-tab - -Simple example where chording Left Alt with `KC_ESC` makes it behave like `KC_TAB` for alt-tabbing between applications. This example strictly checks if only Left Alt is active, meaning you can't do Alt+Shift+Esc to switch between applications in reverse order. Also keep in mind that this removes the ability to trigger the actual Alt+Escape keyboard shortcut, though it keeps the ability to do AltGr+Escape. - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - - case KC_ESC: - // Detect the activation of only Left Alt - if (get_mods() == MOD_BIT(KC_LALT)) { - if (record->event.pressed) { - // No need to register KC_LALT because it's already active. - // The Alt modifier will apply on this KC_TAB. - register_code(KC_TAB); - } else { - unregister_code(KC_TAB); - } - // Do not let QMK process the keycode further - return false; - } - // Else, let QMK process the KC_ESC keycode as usual - return true; - - } - return true; -}; -``` - -### Shift + Backspace for Delete :id=shift-backspace-for-delete - -Advanced example where the original behaviour of shift is cancelled when chorded with `KC_BSPC` and is instead fully replaced by `KC_DEL`. Two main variables are created to make this work well: `mod_state` and `delkey_registered`. The first one stores the modifier state and is used to restore it after registering `KC_DEL`. The second variable is a boolean variable (true or false) which keeps track of the status of `KC_DEL` to manage the release of the whole Backspace/Delete key correctly. - -As opposed to the previous example, this doesn't use strict modifier checking. Pressing `KC_BSPC` while one or two shifts are active is enough to trigger this custom code, regardless of the state of other modifiers. That approach offers some perks: Ctrl+Shift+Backspace lets us delete the next word (Ctrl+Delete) and Ctrl+Alt+Shift+Backspace lets us execute the Ctrl+Alt+Del keyboard shortcut. - -```c -// Initialize variable holding the binary -// representation of active modifiers. -uint8_t mod_state; -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - // Store the current modifier state in the variable for later reference - mod_state = get_mods(); - switch (keycode) { - - case KC_BSPC: - { - // Initialize a boolean variable that keeps track - // of the delete key status: registered or not? - static bool delkey_registered; - if (record->event.pressed) { - // Detect the activation of either shift keys - if (mod_state & MOD_MASK_SHIFT) { - // First temporarily canceling both shifts so that - // shift isn't applied to the KC_DEL keycode - del_mods(MOD_MASK_SHIFT); - register_code(KC_DEL); - // Update the boolean variable to reflect the status of KC_DEL - delkey_registered = true; - // Reapplying modifier state so that the held shift key(s) - // still work even after having tapped the Backspace/Delete key. - set_mods(mod_state); - return false; - } - } else { // on release of KC_BSPC - // In case KC_DEL is still being sent even after the release of KC_BSPC - if (delkey_registered) { - unregister_code(KC_DEL); - delkey_registered = false; - return false; - } - } - // Let QMK process the KC_BSPC keycode as usual outside of shift - return true; - } - - } - return true; -}; -``` -Alternatively, this can be done with [Key Overrides](feature_key_overrides?id=simple-example). - -# Advanced topics :id=advanced-topics - -This page used to encompass a large set of features. We have moved many sections that used to be part of this page to their own pages. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for. - -## Layers :id=switching-and-toggling-layers - -* [Layers](feature_layers.md) - -## Mod-Tap :id=mod-tap - -* [Mod-Tap](mod_tap.md) - -## One Shot Keys :id=one-shot-keys - -* [One Shot Keys](one_shot_keys.md) - -## Tap-Hold Configuration Options :id=tap-hold-configuration-options - -* [Tap-Hold Configuration Options](tap_hold.md) - -## Key Overrides :id=key-overrides - -* [Key Overrides](feature_key_overrides.md) diff --git a/docs/feature_audio.md b/docs/feature_audio.md deleted file mode 100644 index 5227d063c3a5..000000000000 --- a/docs/feature_audio.md +++ /dev/null @@ -1,367 +0,0 @@ -# Audio - -Your keyboard can make sounds! If you've got a spare pin you can hook up a simple speaker and make it beep. You can use those beeps to indicate layer transitions, modifiers, special keys, or just to play some funky 8bit tunes. - -To activate this feature, add `AUDIO_ENABLE = yes` to your `rules.mk`. - -## AVR based boards -On Atmega32U4 based boards, up to two simultaneous tones can be rendered. -With one speaker connected to a PWM capable pin on PORTC driven by timer 3 and the other on one of the PWM pins on PORTB driven by timer 1. - -The following pins can be configured as audio outputs in `config.h` - for one speaker set either one out of: - -* `#define AUDIO_PIN C4` -* `#define AUDIO_PIN C5` -* `#define AUDIO_PIN C6` -* `#define AUDIO_PIN B5` -* `#define AUDIO_PIN B6` -* `#define AUDIO_PIN B7` - -and *optionally*, for a second speaker, one of: -* `#define AUDIO_PIN_ALT B5` -* `#define AUDIO_PIN_ALT B6` -* `#define AUDIO_PIN_ALT B7` - -### Wiring -per speaker is - for example with a piezo buzzer - the black lead to Ground, and the red lead connected to the selected AUDIO_PIN for the primary; and similarly with AUDIO_PIN_ALT for the secondary. - - -## ARM based boards -for more technical details, see the notes on [Audio driver](audio_driver.md). - - -### DAC (basic) -Most STM32 MCUs have DAC peripherals, with a notable exception of the STM32F1xx series. Generally, the DAC peripheral drives pins A4 or A5. To enable DAC-based audio output on STM32 devices, add `AUDIO_DRIVER = dac_basic` to `rules.mk` and set in `config.h` either: - -`#define AUDIO_PIN A4` or `#define AUDIO_PIN A5` - -the other DAC channel can optionally be used with a secondary speaker, just set: - -`#define AUDIO_PIN_ALT A4` or `#define AUDIO_PIN_ALT A5` - -Do note though that the dac_basic driver is only capable of reproducing one tone per speaker/channel at a time, for more tones simultaneously, try the dac_additive driver. - -#### Wiring: -for two piezos, for example configured as `AUDIO_PIN A4` and `AUDIO_PIN_ALT A5` would be: red lead to A4 and black to Ground, and similarly with the second one: A5 = red, and Ground = black - -another alternative is to drive *one* piezo with both DAC pins - for an extra "push". -wiring red to A4 and black to A5 (or the other way round) and add `#define AUDIO_PIN_ALT_AS_NEGATIVE` to `config.h` - -##### Proton-C Example: -The Proton-C comes (optionally) with one 'builtin' piezo, which is wired to A4+A5. -For this board `config.h` would include these defines: - -```c -#define AUDIO_PIN A5 -#define AUDIO_PIN_ALT A4 -#define AUDIO_PIN_ALT_AS_NEGATIVE -``` - -### DAC (additive) -Another option, besides dac_basic (which produces sound through a square-wave), is to use the DAC to do additive wave synthesis. -With a number of predefined wave-forms or by providing your own implementation to generate samples on the fly. -To use this feature set `AUDIO_DRIVER = dac_additive` in your `rules.mk`, and select in `config.h` EITHER `#define AUDIO_PIN A4` or `#define AUDIO_PIN A5`. - -The used waveform *defaults* to sine, but others can be selected by adding one of the following defines to `config.h`: - -* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SINE` -* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRIANGLE` -* `#define AUDIO_DAC_SAMPLE_WAVEFORM_TRAPEZOID` -* `#define AUDIO_DAC_SAMPLE_WAVEFORM_SQUARE` - -Should you rather choose to generate and use your own sample-table with the DAC unit, implement `uint16_t dac_value_generate(void)` with your keyboard - for an example implementation see keyboards/planck/keymaps/synth_sample or keyboards/planck/keymaps/synth_wavetable - - -### PWM (software) -if the DAC pins are unavailable (or the MCU has no usable DAC at all, like STM32F1xx); PWM can be an alternative. -Note that there is currently only one speaker/pin supported. - -set in `rules.mk`: - -`AUDIO_DRIVER = pwm_software` and in `config.h`: -`#define AUDIO_PIN C13` (can be any pin) to have the selected pin output a pwm signal, generated from a timer callback which toggles the pin in software. - -#### Wiring -the usual piezo wiring: red goes to the selected AUDIO_PIN, black goes to ground. - -OR if you can chose to drive one piezo with two pins, for example `#define AUDIO_PIN B1`, `#define AUDIO_PIN_ALT B2` in `config.h`, with `#define AUDIO_PIN_ALT_AS_NEGATIVE` - then the red lead could go to B1, the black to B2. - -### PWM (hardware) -STM32F1xx have to fall back to using PWM, but can do so in hardware; but again on currently only one speaker/pin. - -`AUDIO_DRIVER = pwm_hardware` in `rules.mk`, and in `config.h`: -`#define AUDIO_PIN A8` -`#define AUDIO_PWM_DRIVER PWMD1` -`#define AUDIO_PWM_CHANNEL 1` -(as well as `#define AUDIO_PWM_PAL_MODE 42` if you are on STM32F2 or larger) -which will use Timer 1 to directly drive pin PA8 through the PWM hardware (TIM1_CH1 = PA8). -Should you want to use the pwm-hardware on another pin and timer - be ready to dig into the STM32 data-sheet to pick the right TIMx_CHy and pin-alternate function. - - -## Tone Multiplexing -Since most drivers can only render one tone per speaker at a time (with the one exception: arm dac-additive) there also exists a "workaround-feature" that does time-slicing/multiplexing - which does what the name implies: cycle through a set of active tones (e.g. when playing chords in Music Mode) at a given rate, and put one tone at a time out through the one/few speakers that are available. - -To enable this feature, and configure a starting-rate, add the following defines to `config.h`: -```c -#define AUDIO_ENABLE_TONE_MULTIPLEXING -#define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 10 -``` - -The audio core offers interface functions to get/set/change the tone multiplexing rate from within `keymap.c`. - - -## Songs -There's a couple of different sounds that will automatically be enabled without any other configuration: -``` -STARTUP_SONG // plays when the keyboard starts up (audio.c) -GOODBYE_SONG // plays when you press the QK_BOOT key (quantum.c) -AG_NORM_SONG // plays when you press AG_NORM (quantum.c) -AG_SWAP_SONG // plays when you press AG_SWAP (quantum.c) -CG_NORM_SONG // plays when you press CG_NORM (quantum.c) -CG_SWAP_SONG // plays when you press CG_SWAP (quantum.c) -MUSIC_ON_SONG // plays when music mode is activated (process_music.c) -MUSIC_OFF_SONG // plays when music mode is deactivated (process_music.c) -CHROMATIC_SONG // plays when the chromatic music mode is selected (process_music.c) -GUITAR_SONG // plays when the guitar music mode is selected (process_music.c) -VIOLIN_SONG // plays when the violin music mode is selected (process_music.c) -MAJOR_SONG // plays when the major music mode is selected (process_music.c) -``` - -You can override the default songs by doing something like this in your `config.h`: - -```c -#ifdef AUDIO_ENABLE -# define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -``` - -A full list of sounds can be found in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) - feel free to add your own to this list! All available notes can be seen in [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h). - -Additionally, if you with to maintain your own list of songs (such as ones that may be copyrighted) and not have them added to the repo, you can create a `user_song_list.h` file and place it in your keymap (or userspace) folder. This file will be automatically included, it just needs to exist. - -To play a custom sound at a particular time, you can define a song like this (near the top of the file): - -```c -float my_song[][2] = SONG(QWERTY_SOUND); -``` - -And then play your song like this: - -```c -PLAY_SONG(my_song); -``` - -Alternatively, you can play it in a loop like this: - -```c -PLAY_LOOP(my_song); -``` - -It's advised that you wrap all audio features in `#ifdef AUDIO_ENABLE` / `#endif` to avoid causing problems when audio isn't built into the keyboard. - -The available keycodes for audio are: - -|Key |Aliases |Description | -|-------------------------|---------|-------------------------------------------| -|`QK_AUDIO_ON` |`AU_ON` |Turns on Audio Feature | -|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature | -|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state | - -!> These keycodes turn all of the audio functionality on and off. Turning it off means that audio feedback, audio clicky, music mode, etc. are disabled, completely. - -## Audio Config - -| Settings | Default | Description | -|---------------------------------|----------------------|-------------------------------------------------------------------------------| -|`AUDIO_PIN` | *Not defined* |Configures the pin that the speaker is connected to. | -|`AUDIO_PIN_ALT` | *Not defined* |Configures the pin for a second speaker or second pin connected to one speaker.| -|`AUDIO_PIN_ALT_AS_NEGATIVE` | *Not defined* |Enables support for one speaker connected to two pins. | -|`AUDIO_INIT_DELAY` | *Not defined* |Enables delay during startup song to accomidate for USB startup issues. | -|`AUDIO_ENABLE_TONE_MULTIPLEXING` | *Not defined* |Enables time splicing/multiplexing to create multiple tones simutaneously. | -|`STARTUP_SONG` | `STARTUP_SOUND` |Plays when the keyboard starts up (audio.c) | -|`GOODBYE_SONG` | `GOODBYE_SOUND` |Plays when you press the QK_BOOT key (quantum.c) | -|`AG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press AG_NORM (process_magic.c) | -|`AG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press AG_SWAP (process_magic.c) | -|`CG_NORM_SONG` | `AG_NORM_SOUND` |Plays when you press CG_NORM (process_magic.c) | -|`CG_SWAP_SONG` | `AG_SWAP_SOUND` |Plays when you press CG_SWAP (process_magic.c) | -|`MUSIC_ON_SONG` | `MUSIC_ON_SOUND` |Plays when music mode is activated (process_music.c) | -|`MUSIC_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when music mode is deactivated (process_music.c) | -|`MIDI_ON_SONG` | `MUSIC_ON_SOUND` |Plays when midi mode is activated (process_music.c) | -|`MIDI_OFF_SONG` | `MUSIC_OFF_SOUND` |Plays when midi mode is deactivated (process_music.c) | -|`CHROMATIC_SONG` | `CHROMATIC_SOUND` |Plays when the chromatic music mode is selected (process_music.c) | -|`GUITAR_SONG` | `GUITAR_SOUND` |Plays when the guitar music mode is selected (process_music.c) | -|`VIOLIN_SONG` | `VIOLIN_SOUND` |Plays when the violin music mode is selected (process_music.c) | -|`MAJOR_SONG` | `MAJOR_SOUND` |Plays when the major music mode is selected (process_music.c) | -|`DEFAULT_LAYER_SONGS` | *Not defined* |Plays song when switched default layers with [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer)(quantum.c) | -|`SENDSTRING_BELL` | *Not defined* |Plays chime when the "enter" ("\a") character is sent (send_string.c) | - -## Tempo -the 'speed' at which SONGs are played is dictated by the set Tempo, which is measured in beats-per-minute. Note lengths are defined relative to that. -The initial/default tempo is set to 120 bpm, but can be configured by setting `TEMPO_DEFAULT` in `config.c`. -There is also a set of functions to modify the tempo from within the user/keymap code: -```c -void audio_set_tempo(uint8_t tempo); -void audio_increase_tempo(uint8_t tempo_change); -void audio_decrease_tempo(uint8_t tempo_change); -``` - -## ARM Audio Volume - -For ARM devices, you can adjust the DAC sample values. If your board is too loud for you or your coworkers, you can set the max using `AUDIO_DAC_SAMPLE_MAX` in your `config.h`: - -```c -#define AUDIO_DAC_SAMPLE_MAX 4095U -``` -the DAC usually runs in 12Bit mode, hence a volume of 100% = 4095U - -Note: this only adjusts the volume aka 'works' if you stick to WAVEFORM_SQUARE, since its samples are generated on the fly - any other waveform uses a hardcoded/precomputed sample-buffer. - -## Voices -Aka "audio effects", different ones can be enabled by setting in `config.h` these defines: -`#define AUDIO_VOICES` to enable the feature, and `#define AUDIO_VOICE_DEFAULT something` to select a specific effect -for details see quantum/audio/voices.h and .c - -Keycodes available: - -|Key |Aliases |Description | -|-------------------------|---------|-------------------------------------------| -|`QK_AUDIO_VOICE_NEXT` |`AU_NEXT`|Cycles through the audio voices | -|`QK_AUDIO_VOICE_PREVIOUS`|`AU_PREV`|Cycles through the audio voices in reverse | - -## Music Mode - -The music mode maps your columns to a chromatic scale, and your rows to octaves. This works best with ortholinear keyboards, but can be made to work with others. All keycodes less than `0xFF` get blocked, so you won't type while playing notes - if you have special keys/mods, those will still work. A work-around for this is to jump to a different layer with KC_NOs before (or after) enabling music mode. - -Recording is experimental due to some memory issues - if you experience some weird behavior, unplugging/replugging your keyboard will fix things. - -Keycodes available: - -|Key |Aliases |Description | -|-------------------------|---------|-------------------------------------------| -|`QK_MUSIC_ON` |`MU_ON` |Turns on Music Mode | -|`QK_MUSIC_OFF` |`MU_OFF` |Turns off Music Mode | -|`QK_MUSIC_TOGGLE` |`MU_TOGG`|Toggles Music Mode | -|`QK_MUSIC_MODE_NEXT` |`MU_NEXT`|Cycles through the music modes | - -Available Modes: - * `CHROMATIC_MODE` - Chromatic scale, row changes the octave - * `GUITAR_MODE` - Chromatic scale, but the row changes the string (+5 st) - * `VIOLIN_MODE` - Chromatic scale, but the row changes the string (+7 st) - * `MAJOR_MODE` - Major scale - -In music mode, the following keycodes work differently, and don't pass through: - -* `LCTL` - start a recording -* `LALT` - stop recording/stop playing -* `LGUI` - play recording -* `KC_UP` - speed-up playback -* `KC_DOWN` - slow-down playback - -The pitch standard (`PITCH_STANDARD_A`) is 440.0f by default - to change this, add something like this to your `config.h`: - - #define PITCH_STANDARD_A 432.0f - -You can completely disable Music Mode as well. This is useful, if you're pressed for space on your controller. To disable it, add this to your `config.h`: - - #define NO_MUSIC_MODE - -### Music Mask - -By default, `MUSIC_MASK` is set to `keycode < 0xFF` which means keycodes less than `0xFF` are turned into notes, and don't output anything. You can change this by defining this in your `config.h` like this: - - #define MUSIC_MASK keycode != KC_NO - -Which will capture all keycodes - be careful, this will get you stuck in music mode until you restart your keyboard! - -For a more advanced way to control which keycodes should still be processed, you can use `music_mask_kb(keycode)` in `.c` and `music_mask_user(keycode)` in your `keymap.c`: - - bool music_mask_user(uint16_t keycode) { - switch (keycode) { - case RAISE: - case LOWER: - return false; - default: - return true; - } - } - -Things that return false are not part of the mask, and are always processed. - -### Music Map - -By default, the Music Mode uses the columns and row to determine the scale for the keys. For a board that uses a rectangular matrix that matches the keyboard layout, this is just fine. However, for boards that use a more complicated matrix (such as the Planck Rev6, or many split keyboards) this would result in a very skewed experience. - -However, the Music Map option allows you to remap the scaling for the music mode, so it fits the layout, and is more natural. - -To enable this feature, add `#define MUSIC_MAP` to your `config.h` file, and then you will want to add a `uint8_t music_map` to your keyboard's `c` file, or your `keymap.c`. - -```c -const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x12( - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -); -``` - -You will want to use whichever `LAYOUT` macro that your keyboard uses here. This maps it to the correct key location. Start in the bottom left of the keyboard layout, and move to the right, and then upwards. Fill in all the entries until you have a complete matrix. - -You can look at the [Planck Keyboard](https://github.com/qmk/qmk_firmware/blob/e9ace1487887c1f8b4a7e8e6d87c322988bec9ce/keyboards/planck/planck.c#L24-L29) as an example of how to implement this. - -## Audio Click - -This adds a click sound each time you hit a button, to simulate click sounds from the keyboard. And the sounds are slightly different for each keypress, so it doesn't sound like a single long note, if you type rapidly. - -Keycodes available: - -|Key |Aliases |Description | -|-------------------------|---------|-------------------------------------------| -|`QK_AUDIO_CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode | -|`QK_AUDIO_CLICKY_ON` |`CK_ON` |Turns on Audio clicky mode | -|`QK_AUDIO_CLICKY_OFF` |`CK_OFF` |Turns on Audio clicky mode | -|`QK_AUDIO_CLICKY_UP` |`CK_UP` |Increases frequency of the clicks | -|`QK_AUDIO_CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks | -|`QK_AUDIO_CLICKY_RESET` |`CK_RST` |Resets frequency to default | - -The feature is disabled by default, to save space. To enable it, add this to your `config.h`: - - #define AUDIO_CLICKY - - -You can configure the default, min and max frequencies, the stepping and built in randomness by defining these values: - -| Option | Default Value | Description | -|--------|---------------|-------------| -| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | Sets the default/starting audio frequency for the clicky sounds. | -| `AUDIO_CLICKY_FREQ_MIN` | 65.0f | Sets the lowest frequency (under 60f are a bit buggy). | -| `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | Sets the highest frequency. Too high may result in coworkers attacking you. | -| `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f| Sets the stepping of UP/DOWN key codes. This is a multiplicative factor. The default steps the frequency up/down by a musical minor third. | -| `AUDIO_CLICKY_FREQ_RANDOMNESS` | 0.05f | Sets a factor of randomness for the clicks, Setting this to `0f` will make each click identical, and `1.0f` will make this sound much like the 90's computer screen scrolling/typing effect. | -| `AUDIO_CLICKY_DELAY_DURATION` | 1 | An integer note duration where 1 is 1/16th of the tempo, or a sixty-fourth note (see `quantum/audio/musical_notes.h` for implementation details). The main clicky effect will be delayed by this duration. Adjusting this to values around 6-12 will help compensate for loud switches. | - - - - -## MIDI Functionality - -See [MIDI](feature_midi.md) - -## Audio Keycodes - -|Key |Aliases |Description | -|-------------------------|---------|-------------------------------------------| -|`QK_AUDIO_ON` |`AU_ON` |Turns on Audio Feature | -|`QK_AUDIO_OFF` |`AU_OFF` |Turns off Audio Feature | -|`QK_AUDIO_TOGGLE` |`AU_TOGG`|Toggles Audio state | -|`QK_AUDIO_CLICKY_TOGGLE` |`CK_TOGG`|Toggles Audio clicky mode | -|`QK_AUDIO_CLICKY_ON` |`CK_ON` |Turns on Audio clicky mode | -|`QK_AUDIO_CLICKY_OFF` |`CK_OFF` |Turns on Audio clicky mode | -|`QK_AUDIO_CLICKY_UP` |`CK_UP` |Increases frequency of the clicks | -|`QK_AUDIO_CLICKY_DOWN` |`CK_DOWN`|Decreases frequency of the clicks | -|`QK_AUDIO_CLICKY_RESET` |`CK_RST` |Resets frequency to default | -|`QK_MUSIC_ON` |`MU_ON` |Turns on Music Mode | -|`QK_MUSIC_OFF` |`MU_OFF` |Turns off Music Mode | -|`QK_MUSIC_TOGGLE` |`MU_TOGG`|Toggles Music Mode | -|`QK_MUSIC_MODE_NEXT` |`MU_NEXT`|Cycles through the music modes | -|`QK_AUDIO_VOICE_NEXT` |`AU_NEXT`|Cycles through the audio voices | -|`QK_AUDIO_VOICE_PREVIOUS`|`AU_PREV`|Cycles through the audio voices in reverse | diff --git a/docs/feature_auto_shift.md b/docs/feature_auto_shift.md deleted file mode 100644 index 1719807e2688..000000000000 --- a/docs/feature_auto_shift.md +++ /dev/null @@ -1,347 +0,0 @@ -# Auto Shift: Why Do We Need a Shift Key? - -Tap a key and you get its character. Tap a key, but hold it *slightly* longer -and you get its shifted state. Voilà! No shift key needed! - -## Why Auto Shift? - -Many people suffer from various forms of RSI. A common cause is stretching your -fingers repetitively long distances. For us on the keyboard, the pinky does that -all too often when reaching for the shift key. Auto Shift looks to alleviate that -problem. - -## How Does It Work? - -When you tap a key, it stays depressed for a short period of time before it is -then released. This depressed time is a different length for everyone. Auto Shift -defines a constant `AUTO_SHIFT_TIMEOUT` which is typically set to twice your -normal pressed state time. When you press a key, a timer starts, and if you -have not released the key after the `AUTO_SHIFT_TIMEOUT` period, then a shifted -version of the key is emitted. If the time is less than the `AUTO_SHIFT_TIMEOUT` -time, or you press another key, then the normal state is emitted. - -If `AUTO_SHIFT_REPEAT` is defined, there is keyrepeat support. Holding the key -down will repeat the shifted key, though this can be disabled with -`AUTO_SHIFT_NO_AUTO_REPEAT`. If you want to repeat the normal key, then tap it -once then immediately (within `TAPPING_TERM`) hold it down again (this works -with the shifted value as well if auto-repeat is disabled). - -There are also the `get_auto_shift_repeat` and `get_auto_shift_no_auto_repeat` -functions for more granular control. Neither will have an effect unless -`AUTO_SHIFT_REPEAT_PER_KEY` or `AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY` respectively -are defined. - -## Are There Limitations to Auto Shift? - -Yes, unfortunately. - -1. You will have characters that are shifted when you did not intend on shifting, and - other characters you wanted shifted, but were not. This simply comes down to - practice. As we get in a hurry, we think we have hit the key long enough for a - shifted version, but we did not. On the other hand, we may think we are tapping - the keys, but really we have held it for a little longer than anticipated. -2. Additionally, with keyrepeat the desired shift state can get mixed up. It will - always 'belong' to the last key pressed. For example, keyrepeating a capital - and then tapping something lowercase (whether or not it's an Auto Shift key) - will result in the capital's *key* still being held, but shift not. -3. Auto Shift does not apply to Tap Hold keys. For automatic shifting of Tap Hold - keys see [Retro Shift](#retro-shift). - -## How Do I Enable Auto Shift? - -Add to your `rules.mk` in the keymap folder: - - AUTO_SHIFT_ENABLE = yes - -If no `rules.mk` exists, you can create one. - -Then compile and install your new firmware with Auto Key enabled! That's it! - -## Modifiers - -By default, Auto Shift is disabled for any key press that is accompanied by one or more -modifiers. Thus, Ctrl+A that you hold for a really long time is not the same -as Ctrl+Shift+A. - -You can re-enable Auto Shift for modifiers by adding a define to your `config.h` - -```c -#define AUTO_SHIFT_MODIFIERS -``` - -In which case, Ctrl+A held past the `AUTO_SHIFT_TIMEOUT` will be sent as Ctrl+Shift+A - - -## Configuring Auto Shift - -If desired, there is some configuration that can be done to change the -behavior of Auto Shift. This is done by setting various variables the -`config.h` file located in your keymap folder. If no `config.h` file exists, you can create one. - -A sample is - -```c -#pragma once - -#define AUTO_SHIFT_TIMEOUT 150 -#define NO_AUTO_SHIFT_SPECIAL -``` - -### AUTO_SHIFT_TIMEOUT (Value in ms) - -This controls how long you have to hold a key before you get the shifted state. -Obviously, this is different for everyone. For the common person, a setting of -135 to 150 works great. However, one should start with a value of at least 175, which -is the default value. Then work down from there. The idea is to have the shortest time required to get the shifted state without having false positives. - -Play with this value until things are perfect. Many find that all will work well -at a given value, but one or two keys will still emit the shifted state on -occasion. This is simply due to habit and holding some keys a little longer -than others. Once you find this value, work on tapping your problem keys a little -quicker than normal and you will be set. - -?> Auto Shift has three special keys that can help you get this value right very quick. See "Auto Shift Setup" for more details! - -For more granular control of this feature, you can add the following to your `config.h`: - -```c -#define AUTO_SHIFT_TIMEOUT_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -uint16_t get_autoshift_timeout(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case AUTO_SHIFT_NUMERIC: - return 2 * get_generic_autoshift_timeout(); - case AUTO_SHIFT_SPECIAL: - return get_generic_autoshift_timeout() + 50; - case AUTO_SHIFT_ALPHA: - default: - return get_generic_autoshift_timeout(); - } -} -``` - -Note that you cannot override individual keys that are in one of those groups -if you are using them; trying to add a case for `KC_A` in the above example will -not compile as `AUTO_SHIFT_ALPHA` is there. A possible solution is a second switch -above to handle individual keys with no default case and only referencing the -groups in the below fallback switch. - -### NO_AUTO_SHIFT_SPECIAL (simple define) - -Do not Auto Shift special keys, which include -\_, =+, [{, ]}, ;:, '", ,<, .>, -and /? - -### NO_AUTO_SHIFT_NUMERIC (simple define) - -Do not Auto Shift numeric keys, zero through nine. - -### NO_AUTO_SHIFT_ALPHA (simple define) - -Do not Auto Shift alpha characters, which include A through Z. - -### Auto Shift Per Key - -There are functions that allows you to determine which keys shold be autoshifted, much like the tap-hold keys. - -The first of these, used to simply add a key to Auto Shift, is `get_custom_auto_shifted_key`: - -```c -bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case KC_DOT: - return true; - default: - return false; - } -} -``` - -For more granular control, there is `get_auto_shifted_key`. The default function looks like this: - -```c -bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { -# ifndef NO_AUTO_SHIFT_ALPHA - case KC_A ... KC_Z: -# endif -# ifndef NO_AUTO_SHIFT_NUMERIC - case KC_1 ... KC_0: -# endif -# ifndef NO_AUTO_SHIFT_SPECIAL - case KC_TAB: - case KC_MINUS ... KC_SLASH: - case KC_NONUS_BACKSLASH: -# endif - return true; - } - return get_custom_auto_shifted_key(keycode, record); -} -``` - -This functionality is enabled by default, and does not need a define. - -### AUTO_SHIFT_REPEAT (simple define) - -Enables keyrepeat. - -### AUTO_SHIFT_NO_AUTO_REPEAT (simple define) - -Disables automatically keyrepeating when `AUTO_SHIFT_TIMEOUT` is exceeded. - -## Custom Shifted Values - -Especially on small keyboards, the default shifted value for many keys is not -optimal. To provide more customizability, there are two user-definable -functions, `autoshift_press/release_user`. These register or unregister the -correct value for the passed key. Below is an example adding period to Auto -Shift and making its shifted value exclamation point. Make sure to use weak -mods - setting real would make any keys following it use their shifted values -as if you were holding the key. Clearing of modifiers is handled by Auto Shift, -and the OS-sent shift value if keyrepeating multiple keys is always that of -the last key pressed (whether or not it's an Auto Shift key). - -You can also have non-shifted keys for the shifted values (or even no shifted -value), just don't set a shift modifier! - -```c -bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case KC_DOT: - return true; - default: - return false; - } -} - -void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) { - switch(keycode) { - case KC_DOT: - register_code16((!shifted) ? KC_DOT : KC_EXLM); - break; - default: - if (shifted) { - add_weak_mods(MOD_BIT(KC_LSFT)); - } - // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift - register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); - } -} - -void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) { - switch(keycode) { - case KC_DOT: - unregister_code16((!shifted) ? KC_DOT : KC_EXLM); - break; - default: - // & 0xFF gets the Tap key for Tap Holds, required when using Retro Shift - // The IS_RETRO check isn't really necessary here, always using - // keycode & 0xFF would be fine. - unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); - } -} -``` - -## Retro Shift - -Holding and releasing a Tap Hold key without pressing another key will ordinarily -result in only the hold. With `retro shift` enabled this action will instead -produce a shifted version of the tap keycode on release. - -It does not require [Retro Tapping](tap_hold.md#retro-tapping) to be enabled, and -if both are enabled the state of `retro tapping` will only apply if the tap keycode -is not matched by Auto Shift. `RETRO_TAPPING_PER_KEY` and its corresponding -function, however, are checked before `retro shift` is applied. - -To enable `retro shift`, add the following to your `config.h`: - -```c -#define RETRO_SHIFT -``` - -If `RETRO_SHIFT` is defined to a value, hold times greater than that value will -not produce a tap on release for Mod Taps, and instead triggers the hold action. -This enables modifiers to be held for combining with mouse clicks without -generating taps on release. For example: - -```c -#define RETRO_SHIFT 500 -``` - -This value (if set) must be greater than one's `TAPPING_TERM`, as the key press -must be designated as a 'hold' by `process_tapping` before we send the modifier. -There is no such limitation in regards to `AUTO_SHIFT_TIMEOUT` for normal keys. - -### Retro Shift and Tap Hold Configurations - -Tap Hold Configurations work a little differently when using Retro Shift. -Referencing `TAPPING_TERM` makes little sense, as holding longer would result in -shifting one of the keys. - -`RETRO_SHIFT` enables [`PERMISSIVE_HOLD`-like behaviour](tap_hold.md#permissive-hold) (even if not explicitly enabled) on all mod-taps for which `RETRO_SHIFT` applies. - -## Using Auto Shift Setup - -This will enable you to define three keys temporarily to increase, decrease and report your `AUTO_SHIFT_TIMEOUT`. - -### Setup - -Map three keys temporarily in your keymap: - -|Keycode |Aliases |Description | -|----------------------|---------|--------------------------------------------| -|`QK_AUTO_SHIFT_DOWN` |`AS_DOWN`|Lower the Auto Shift timeout variable (down)| -|`QK_AUTO_SHIFT_UP` |`AS_UP` |Raise the Auto Shift timeout variable (up) | -|`QK_AUTO_SHIFT_REPORT`|`AS_RPT` |Report your current Auto Shift timeout value| -|`QK_AUTO_SHIFT_ON` |`AS_ON` |Turns on the Auto Shift Function | -|`QK_AUTO_SHIFT_OFF` |`AS_OFF` |Turns off the Auto Shift Function | -|`QK_AUTO_SHIFT_TOGGLE`|`AS_TOGG`|Toggles the state of the Auto Shift feature | - -Compile and upload your new firmware. - -### Use - -It is important to note that during these tests, you should be typing -completely normal and with no intention of shifted keys. - -1. Type multiple sentences of alphabetical letters. -2. Observe any upper case letters. -3. If there are none, press the key you have mapped to `AS_DOWN` to decrease - time Auto Shift timeout value and go back to step 1. -4. If there are some upper case letters, decide if you need to work on tapping - those keys with less down time, or if you need to increase the timeout. -5. If you decide to increase the timeout, press the key you have mapped to - `AS_UP` and go back to step 1. -6. Once you are happy with your results, press the key you have mapped to - `AS_RPT`. The keyboard will type by itself the value of your - `AUTO_SHIFT_TIMEOUT`. -7. Update `AUTO_SHIFT_TIMEOUT` in your `config.h` with the value reported. -8. Add `AUTO_SHIFT_NO_SETUP` to your `config.h`. -9. Remove the key bindings `AS_DOWN`, `AS_UP` and `AS_RPT`. -10. Compile and upload your new firmware. - -#### An Example Run - - hello world. my name is john doe. i am a computer programmer playing with - keyboards right now. - - [PRESS AS_DOWN quite a few times] - - heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH - KEYboArDS RiGHT NOw. - - [PRESS AS_UP a few times] - - hello world. my name is john Doe. i am a computer programmer playing with - keyboarDs right now. - - [PRESS AS_RPT] - - 115 - -The keyboard typed `115` which represents your current `AUTO_SHIFT_TIMEOUT` -value. You are now set! Practice on the *D* key a little bit that showed up -in the testing and you'll be golden. diff --git a/docs/feature_autocorrect.md b/docs/feature_autocorrect.md deleted file mode 100644 index 9f80c93f8274..000000000000 --- a/docs/feature_autocorrect.md +++ /dev/null @@ -1,307 +0,0 @@ -# Autocorrect - -There are a lot of words that are prone to being typed incorrectly, due to habit, sequence or just user error. This feature leverages your firmware to automatically correct these errors, to help reduce typos. - -## How does it work? :id=how-does-it-work - -The feature maintains a small buffer of recent key presses. On each key press, it checks whether the buffer ends in a recognized typo, and if so, automatically sends keystrokes to correct it. - -The tricky part is how to efficiently check the buffer for typos. We don’t want to spend too much memory or time on storing or searching the typos. A good solution is to represent the typos with a trie data structure. A trie is a tree data structure where each node is a letter, and words are formed by following a path to one of the leaves. - -![An example trie](https://i.imgur.com/HL5DP8H.png) - -Since we search whether the buffer ends in a typo, we store the trie writing in reverse. The trie is queried starting from the last letter, then second to last letter, and so on, until either a letter doesn’t match or we reach a leaf, meaning a typo was found. - -## How do I enable Autocorrection :id=how-do-i-enable-autocorrection - -In your `rules.mk`, add this: - -```make -AUTOCORRECT_ENABLE = yes -``` - -Additionally, you will need a library for autocorrection. A small sample library is included by default, so that you can get up and running right away, but you can provide a customized library. - -By default, autocorrect is disabled. To enable it, you need to use the `AC_TOGG` keycode to enable it. The status is stored in persistent memory, so you shouldn't need to enabled it again. - -## Customizing autocorrect library :id=customizing-autocorrect-library - -To provide a custom library, you need to create a text file with the corrections. For instance: - -```text -:thier -> their -fitler -> filter -lenght -> length -ouput -> output -widht -> width -``` - -The syntax is `typo -> correction`. Typos and corrections are case insensitive, and any whitespace before or after the typo and correction is ignored. The typo must be only the letters a–z, or the special character : representing a word break. The correction may have any non-unicode characters. - -Then, run: - -```sh -qmk generate-autocorrect-data autocorrect_dictionary.txt -``` - -This will process the file and produce an `autocorrect_data.h` file with the trie library, in the folder that you are at. You can specify the keyboard and keymap (eg `-kb planck/rev6 -km jackhumbert`), and it will place the file in that folder instead. But as long as the file is located in your keymap folder, or user folder, it should be picked up automatically. - -This file will look like this: - -```c -// :thier -> their -// fitler -> filter -// lenght -> length -// ouput -> output -// widht -> width - -#define AUTOCORRECT_MIN_LENGTH 5 // "ouput" -#define AUTOCORRECT_MAX_LENGTH 6 // ":thier" - -#define DICTIONARY_SIZE 74 - -static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {85, 7, 0, 23, 35, 0, 0, 8, 0, 76, 16, 0, 15, 25, 0, 0, - 11, 23, 44, 0, 130, 101, 105, 114, 0, 23, 12, 9, 0, 131, 108, 116, 101, 114, 0, 75, 42, 0, 24, 64, 0, 0, 71, 49, 0, - 10, 56, 0, 0, 12, 26, 0, 129, 116, 104, 0, 17, 8, 15, 0, 129, 116, 104, 0, 19, 24, 18, 0, 130, 116, 112, 117, 116, - 0}; -``` - -### Avoiding false triggers :id=avoiding-false-triggers - -By default, typos are searched within words, to find typos within longer identifiers like maxFitlerOuput. While this is useful, a consequence is that autocorrection will falsely trigger when a typo happens to be a substring of a correctly-spelled word. For instance, if we had thier -> their as an entry, it would falsely trigger on (correct, though relatively uncommon) words like “wealthier” and “filthier.” - -The solution is to set a word break : before and/or after the typo to constrain matching. : matches space, period, comma, underscore, digits, and most other non-alpha characters. - -|Text |thier |:thier |thier: |:thier: | -|-----------------|:------:|:------:|:------:|:------:| -|see `thier` typo |matches |matches |matches |matches | -|it’s `thiers` |matches |matches |no |no | -|wealthier words |matches |no |matches |no | - -:thier: is most restrictive, matching only when thier is a whole word. - -The `qmk generate-autocorrect-data` commands can make an effort to check for entries that would false trigger as substrings of correct words. It searches each typo against a dictionary of 25K English words from the english_words Python package, provided it’s installed. (run `python3 -m pip install english_words` to install it.) - -?> Unfortunately, this is limited to just english words, at this point. - -## Overriding Autocorrect - -Occasionally you might actually want to type a typo (for instance, while editing autocorrect_dict.txt) without being autocorrected. There are a couple of ways to do this: - -1. Begin typing the typo. -2. Before typing the last letter, press and release the Ctrl or Alt key. -3. Type the remaining letters. - -This works because the autocorrection implementation doesn’t understand hotkeys, so it resets itself whenever a modifier other than shift is held. - -Additionally, you can use the `AC_TOGG` keycode to toggle the on/off status for Autocorrect. - -### Keycodes :id=keycodes - -|Keycode |Aliases |Description | -|-----------------------|---------|----------------------------------------------| -|`QK_AUTOCORRECT_ON` |`AC_ON` |Turns on the Autocorrect feature. | -|`QK_AUTOCORRECT_OFF` |`AC_OFF` |Turns off the Autocorrect feature. | -|`QK_AUTOCORRECT_TOGGLE`|`AC_TOGG`|Toggles the status of the Autocorrect feature.| - -## User Callback Functions - -### Process Autocorrect - -Callback function `bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods)` is available to customise incoming keycodes and handle exceptions. You can use this function to sanitise input before they are passed onto the autocorrect engine - -?> Sanitisation of input is required because autocorrect will only match 8-bit [basic keycodes](keycodes_basic.md) for typos. If valid modifier keys or 16-bit keycodes that are part of a user's word input (such as Shift + A) is passed through, they will fail typo letter detection. For example a [Mod-Tap](mod_tap.md) key such as `LCTL_T(KC_A)` is 16-bit and should be masked for the 8-bit `KC_A`. - -The default user callback function is found inside `quantum/process_keycode/process_autocorrect.c`. It covers most use-cases for QMK special functions and quantum keycodes, including [overriding autocorrect](#overriding-autocorrect) with a modifier other than shift. The `process_autocorrect_user` function is `weak` defined to allow user's copy inside `keymap.c` (or code files) to overwrite it. - -#### Process Autocorrect Example - -If you have a custom keycode `QMKBEST` that should be ignored as part of a word, and another custom keycode `QMKLAYER` that should override autocorrect, both can be added to the bottom of the `process_autocorrect_user` `switch` statement in your source code: - -```c -bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) { - // See quantum_keycodes.h for reference on these matched ranges. - switch (*keycode) { - // Exclude these keycodes from processing. - case KC_LSFT: - case KC_RSFT: - case KC_CAPS: - case QK_TO ... QK_ONE_SHOT_LAYER_MAX: - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_MOD_MAX: - case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: - return false; - - // Mask for base keycode from shifted keys. - case QK_LSFT ... QK_LSFT + 255: - case QK_RSFT ... QK_RSFT + 255: - if (*keycode >= QK_LSFT && *keycode <= (QK_LSFT + 255)) { - *mods |= MOD_LSFT; - } else { - *mods |= MOD_RSFT; - } - *keycode &= 0xFF; // Get the basic keycode. - return true; -#ifndef NO_ACTION_TAPPING - // Exclude tap-hold keys when they are held down - // and mask for base keycode when they are tapped. - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: -# ifdef NO_ACTION_LAYER - // Exclude Layer Tap, if layers are disabled - // but action tapping is still enabled. - return false; -# endif - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - // Exclude hold if mods other than Shift is not active - if (!record->tap.count) { - return false; - } - *keycode &= 0xFF; - break; -#else - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: - // Exclude if disabled - return false; -#endif - // Exclude swap hands keys when they are held down - // and mask for base keycode when they are tapped. - case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: -#ifdef SWAP_HANDS_ENABLE - if (*keycode >= 0x56F0 || !record->tap.count) { - return false; - } - *keycode &= 0xFF; - break; -#else - // Exclude if disabled - return false; -#endif - // Handle custom keycodes - case QMKBEST: - return false; - case QMKLAYER: - *typo_buffer_size = 0; - return false; - } - - // Disable autocorrect while a mod other than shift is active. - if ((*mods & ~MOD_MASK_SHIFT) != 0) { - *typo_buffer_size = 0; - return false; - } - - return true; -} -``` - -?> In this callback function, `return false` will skip processing of that keycode for autocorrect. Adding `*typo_buffer_size = 0` will also reset the autocorrect buffer at the same time, cancelling any current letters already stored in the buffer. - -### Apply Autocorrect - -Additionally, `apply_autocorrect(uint8_t backspaces, const char *str)` allows for users to add additional handling to the autocorrection, or replace the functionality entirely. This passes on the number of backspaces needed to replace the words, as well as the replacement string (partial word, not the full word). - -#### Apply Autocorrect Example - -This following example will play a sound when a typo is autocorrected and execute the autocorrection itself: - -```c -#ifdef AUDIO_ENABLE -float autocorrect_song[][2] = SONG(TERMINAL_SOUND); -#endif - -bool apply_autocorrect(uint8_t backspaces, const char *str) { -#ifdef AUDIO_ENABLE - PLAY_SONG(autocorrect_song); -#endif - for (uint8_t i = 0; i < backspaces; ++i) { - tap_code(KC_BSPC); - } - send_string_P(str); - return false; -} -``` - -?> In this callback function, `return false` will stop the normal processing of autocorrect, which requires manually handling of removing the "bad" characters and typing the new characters. - -!> ***IMPORTANT***: `str` is a pointer to `PROGMEM` data for the autocorrection. If you return false, and want to send the string, this needs to use `send_string_P` and not `send_string` or `SEND_STRING`. - -You can also use `apply_autocorrect` to detect and display the event but allow internal code to execute the autocorrection with `return true`: - -```c -bool apply_autocorrect(uint8_t backspaces, const char *str) { -#ifdef OLED_ENABLE - oled_write_P(PSTR("Auto-corrected"), false); -#endif - return true; -} -``` - -### Autocorrect Status - -Additional user callback functions to manipulate Autocorrect: - -| Function | Description | -|----------------------------|----------------------------------------------| -| `autocorrect_enable()` | Turns Autocorrect on. | -| `autocorrect_disable()` | Turns Autocorrect off. | -| `autocorrect_toggle()` | Toggles Autocorrect. | -| `autocorrect_is_enabled()` | Returns true if Autocorrect is currently on. | - - -## Appendix: Trie binary data format :id=appendix - -This section details how the trie is serialized to byte data in autocorrect_data. You don’t need to care about this to use this autocorrection implementation. But it is documented for the record in case anyone is interested in modifying the implementation, or just curious how it works. - -What I did here is fairly arbitrary, but it is simple to decode and gets the job done. - -### Encoding :id=encoding - -All autocorrection data is stored in a single flat array autocorrect_data. Each trie node is associated with a byte offset into this array, where data for that node is encoded, beginning with root at offset 0. There are three kinds of nodes. The highest two bits of the first byte of the node indicate what kind: - -* 00 ⇒ chain node: a trie node with a single child. -* 01 ⇒ branching node: a trie node with multiple children. -* 10 ⇒ leaf node: a leaf, corresponding to a typo and storing its correction. - -![An example trie](https://i.imgur.com/HL5DP8H.png) - -**Branching node**. Each branch is encoded with one byte for the keycode (KC_A–KC_Z) followed by a link to the child node. Links between nodes are 16-bit byte offsets relative to the beginning of the array, serialized in little endian order. - -All branches are serialized this way, one after another, and terminated with a zero byte. As described above, the node is identified as a branch by setting the two high bits of the first byte to 01, done by bitwise ORing the first keycode with 64. keycode. The root node for the above figure would be serialized like: - -``` -+-------+-------+-------+-------+-------+-------+-------+ -| R|64 | node 2 | T | node 3 | 0 | -+-------+-------+-------+-------+-------+-------+-------+ -``` - -**Chain node**. Tries tend to have long chains of single-child nodes, as seen in the example above with f-i-t-l in fitler. So to save space, we use a different format to encode chains than branching nodes. A chain is encoded as a string of keycodes, beginning with the node closest to the root, and terminated with a zero byte. The child of the last node in the chain is encoded immediately after. That child could be either a branching node or a leaf. - -In the figure above, the f-i-t-l chain is encoded as - -``` -+-------+-------+-------+-------+-------+ -| L | T | I | F | 0 | -+-------+-------+-------+-------+-------+ -``` - -If we were to encode this chain using the same format used for branching nodes, we would encode a 16-bit node link with every node, costing 8 more bytes in this example. Across the whole trie, this adds up. Conveniently, we can point to intermediate points in the chain and interpret the bytes in the same way as before. E.g. starting at the i instead of the l, and the subchain has the same format. - -**Leaf node**. A leaf node corresponds to a particular typo and stores data to correct the typo. The leaf begins with a byte for the number of backspaces to type, and is followed by a null-terminated ASCII string of the replacement text. The idea is, after tapping backspace the indicated number of times, we can simply pass this string to the `send_string_P` function. For fitler, we need to tap backspace 3 times (not 4, because we catch the typo as the final ‘r’ is pressed) and replace it with lter. To identify the node as a leaf, the two high bits are set to 10 by ORing the backspace count with 128: - -``` -+-------+-------+-------+-------+-------+-------+ -| 3|128 | 'l' | 't' | 'e' | 'r' | 0 | -+-------+-------+-------+-------+-------+-------+ -``` - -### Decoding :id=decoding - -This format is by design decodable with fairly simple logic. A 16-bit variable state represents our current position in the trie, initialized with 0 to start at the root node. Then, for each keycode, test the highest two bits in the byte at state to identify the kind of node. - -* 00 ⇒ **chain node**: If the node’s byte matches the keycode, increment state by one to go to the next byte. If the next byte is zero, increment again to go to the following node. -* 01 ⇒ **branching node**: Search the branches for one that matches the keycode, and follow its node link. -* 10 ⇒ **leaf node**: a typo has been found! We read its first byte for the number of backspaces to type, then pass its following bytes to send_string_P to type the correction. - -## Credits - -Credit goes to [getreuer](https://github.com/getreuer) for originally implementing this [here](https://getreuer.info/posts/keyboards/autocorrection/#how-does-it-work). As well as to [filterpaper](https://github.com/filterpaper) for converting the code to use PROGMEM, and additional improvements. diff --git a/docs/feature_backlight.md b/docs/feature_backlight.md deleted file mode 100644 index 24057c608f8c..000000000000 --- a/docs/feature_backlight.md +++ /dev/null @@ -1,220 +0,0 @@ -# Backlighting :id=backlighting - -Many keyboards support backlit keys by way of individual LEDs placed through or underneath the keyswitches. This feature is distinct from both the [RGB underglow](feature_rgblight.md) and [RGB matrix](feature_rgb_matrix.md) features as it usually allows for only a single colour per switch, though you can obviously install multiple different single coloured LEDs on a keyboard. - -QMK is able to control the brightness of these LEDs by switching them on and off rapidly in a certain ratio, a technique known as *Pulse Width Modulation*, or PWM. By altering the duty cycle of the PWM signal, it creates the illusion of dimming. - -The MCU can only supply so much current to its GPIO pins. Instead of powering the backlight directly from the MCU, the backlight pin is connected to a transistor or MOSFET that switches the power to the LEDs. - -Most keyboards have backlighting enabled by default if they support it, but if it is not working for you, check that your `rules.mk` includes the following: - -```make -BACKLIGHT_ENABLE = yes -``` - -## Keycodes :id=keycodes - -Once enabled, the following keycodes below can be used to change the backlight level. - -| Key | Aliases | Description | -|---------------------------------|-----------|-------------------------------------| -| `QK_BACKLIGHT_TOGGLE` | `BL_TOGG` | Turn the backlight on or off | -| `QK_BACKLIGHT_STEP` | `BL_STEP` | Cycle through backlight levels | -| `QK_BACKLIGHT_ON` | `BL_ON` | Set the backlight to max brightness | -| `QK_BACKLIGHT_OFF` | `BL_OFF` | Turn the backlight off | -| `QK_BACKLIGHT_UP` | `BL_UP` | Increase the backlight level | -| `QK_BACKLIGHT_DOWN` | `BL_DOWN` | Decrease the backlight level | -| `QK_BACKLIGHT_TOGGLE_BREATHING` | `BL_BRTG` | Toggle backlight breathing | - -## Functions :id=functions - -These functions can be used to change the backlighting in custom code: - -|Function |Description | -|------------------------|--------------------------------------------| -|`backlight_toggle()` |Turn the backlight on or off | -|`backlight_enable()` |Turn the backlight on | -|`backlight_disable()` |Turn the backlight off | -|`backlight_step()` |Cycle through backlight levels | -|`backlight_increase()` |Increase the backlight level | -|`backlight_decrease()` |Decrease the backlight level | -|`backlight_level(x)` |Sets the backlight level to specified level | -|`get_backlight_level()` |Return the current backlight level | -|`is_backlight_enabled()`|Return whether the backlight is currently on| - -If backlight breathing is enabled (see below), the following functions are also available: - -|Function |Description | -|---------------------|--------------------------------------| -|`breathing_toggle()` |Turn the backlight breathing on or off| -|`breathing_enable()` |Turns on backlight breathing | -|`breathing_disable()`|Turns off backlight breathing | - -## Configuration :id=configuration - -To select which driver to use, configure your `rules.mk` with the following: - -```make -BACKLIGHT_DRIVER = software -``` - -Valid driver values are `pwm`, `software`, `custom` or `no`. See below for help on individual drivers. - -To configure the backlighting, `#define` these in your `config.h`: - -|Define |Default |Description | -|-----------------------------|------------------|-----------------------------------------------------------------------------------------------------------------| -|`BACKLIGHT_PIN` |*Not defined* |The pin that controls the LED(s) | -|`BACKLIGHT_LEVELS` |`3` |The number of brightness levels (maximum 31 excluding off) | -|`BACKLIGHT_CAPS_LOCK` |*Not defined* |Enable Caps Lock indicator using backlight (for keyboards without dedicated LED) | -|`BACKLIGHT_BREATHING` |*Not defined* |Enable backlight breathing, if supported | -|`BREATHING_PERIOD` |`6` |The length of one backlight "breath" in seconds | -|`BACKLIGHT_ON_STATE` |`1` |The state of the backlight pin when the backlight is "on" - `1` for high, `0` for low | -|`BACKLIGHT_LIMIT_VAL` |`255` |The maximum duty cycle of the backlight -- `255` allows for full brightness, any lower will decrease the maximum.| -|`BACKLIGHT_DEFAULT_LEVEL` |`BACKLIGHT_LEVELS`|The default backlight level to use upon clearing the EEPROM | -|`BACKLIGHT_DEFAULT_BREATHING`|*Not defined* |Whether to enable backlight breathing upon clearing the EEPROM | - -Unless you are designing your own keyboard, you generally should not need to change the `BACKLIGHT_PIN` or `BACKLIGHT_ON_STATE`. - -### Backlight On State :id=backlight-on-state - -Most backlight circuits are driven by an N-channel MOSFET or NPN transistor. This means that to turn the transistor *on* and light the LEDs, you must drive the backlight pin, connected to the gate or base, *high*. -Sometimes, however, a P-channel MOSFET, or a PNP transistor is used. In this case, when the transistor is on, the pin is driven *low* instead. - -This functionality is configured at the keyboard level with the `BACKLIGHT_ON_STATE` define. - -### AVR Driver :id=avr-driver - -The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be: - -```make -BACKLIGHT_DRIVER = pwm -``` - -#### Caveats :id=avr-caveats - -On AVR boards, QMK automatically decides which driver to use according to the following table: - -|Backlight Pin|AT90USB64/128|AT90USB162|ATmega16/32U4|ATmega16/32U2|ATmega32A|ATmega328/P| -|-------------|-------------|----------|-------------|-------------|---------|-----------| -|`B1` | | | | | |Timer 1 | -|`B2` | | | | | |Timer 1 | -|`B5` |Timer 1 | |Timer 1 | | | | -|`B6` |Timer 1 | |Timer 1 | | | | -|`B7` |Timer 1 |Timer 1 |Timer 1 |Timer 1 | | | -|`C4` |Timer 3 | | | | | | -|`C5` |Timer 3 |Timer 1 | |Timer 1 | | | -|`C6` |Timer 3 |Timer 1 |Timer 3 |Timer 1 | | | -|`D4` | | | | |Timer 1 | | -|`D5` | | | | |Timer 1 | | - -All other pins will use timer-assisted software PWM: - -|Audio Pin|Audio Timer|Software PWM Timer| -|---------|-----------|------------------| -|`C4` |Timer 3 |Timer 1 | -|`C5` |Timer 3 |Timer 1 | -|`C6` |Timer 3 |Timer 1 | -|`B5` |Timer 1 |Timer 3 | -|`B6` |Timer 1 |Timer 3 | -|`B7` |Timer 1 |Timer 3 | - -When both timers are in use for Audio, the backlight PWM cannot use a hardware timer, and will instead be triggered during the matrix scan. In this case, breathing is not supported, and the backlight might flicker, because the PWM computation may not be called with enough timing precision. - -#### Hardware PWM Implementation :id=hardware-pwm-implementation - -When using the supported pins for backlighting, QMK will use a hardware timer configured to output a PWM signal. This timer will count up to `ICRx` (by default `0xFFFF`) before resetting to 0. -The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the backlight pin will go low, and is pulled high again when the counter resets. -In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on. - -The breathing effect is achieved by registering an interrupt handler for `TIMER1_OVF_vect` that is called whenever the counter resets, roughly 244 times per second. -In this handler, the value of an incrementing counter is mapped onto a precomputed brightness curve. To turn off breathing, the interrupt handler is simply disabled, and the brightness reset to the level stored in EEPROM. - -#### Timer Assisted PWM Implementation :id=timer-assisted-implementation - -When `BACKLIGHT_PIN` is not set to a hardware backlight pin, QMK will use a hardware timer configured to trigger software interrupts. This time will count up to `ICRx` (by default `0xFFFF`) before resetting to 0. -When resetting to 0, the CPU will fire an OVF (overflow) interrupt that will turn the LEDs on, starting the duty cycle. -The desired brightness is calculated and stored in the `OCRxx` register. When the counter reaches this value, the CPU will fire a Compare Output match interrupt, which will turn the LEDs off. -In this way `OCRxx` essentially controls the duty cycle of the LEDs, and thus the brightness, where `0x0000` is completely off and `0xFFFF` is completely on. - -The breathing effect is the same as in the hardware PWM implementation. - -### ARM Driver :id=arm-configuration - -While still in its early stages, ARM backlight support aims to eventually have feature parity with AVR. The `pwm` driver is configured by default, however the equivalent setting within `rules.mk` would be: - -```make -BACKLIGHT_DRIVER = pwm -``` - -#### ChibiOS Configuration :id=arm-configuration - -The following `#define`s apply only to ARM-based keyboards: - -|Define |Default|Description | -|-----------------------|-------|-----------------------------------| -|`BACKLIGHT_PWM_DRIVER` |`PWMD4`|The PWM driver to use | -|`BACKLIGHT_PWM_CHANNEL`|`3` |The PWM channel to use | -|`BACKLIGHT_PAL_MODE` |`2` |The pin alternative function to use| - -See the ST datasheet for your particular MCU to determine these values. Unless you are designing your own keyboard, you generally should not need to change them. - -#### Caveats :id=arm-caveats - -Currently only hardware PWM is supported, not timer assisted, and does not provide automatic configuration. - -### Software PWM Driver :id=software-pwm-driver - -In this mode, PWM is "emulated" while running other keyboard tasks. It offers maximum hardware compatibility without extra platform configuration. The tradeoff is the backlight might jitter when the keyboard is busy. To enable, add this to your `rules.mk`: - -```make -BACKLIGHT_DRIVER = software -``` - -#### Multiple Backlight Pins :id=multiple-backlight-pins - -Most keyboards have only one backlight pin which controls all backlight LEDs (especially if the backlight is connected to a hardware PWM pin). -In software PWM, it is possible to define multiple backlight pins, which will be turned on and off at the same time during the PWM duty cycle. - -This feature allows to set, for instance, the Caps Lock LED's (or any other controllable LED) brightness at the same level as the other LEDs of the backlight. This is useful if you have mapped Control in place of Caps Lock and you need the Caps Lock LED to be part of the backlight instead of being activated when Caps Lock is on, as it is usually wired to a separate pin from the backlight. - -To activate multiple backlight pins, add something like this to your `config.h`, instead of `BACKLIGHT_PIN`: - -```c -#define BACKLIGHT_PINS { F5, B2 } -``` - -### Custom Driver :id=custom-driver - -If none of the above drivers apply to your board (for example, you are using a separate IC to control the backlight), you can implement a custom backlight driver using this simple API provided by QMK. To enable, add this to your `rules.mk`: - -```make -BACKLIGHT_DRIVER = custom -``` - -Then implement any of these hooks: - -```c -void backlight_init_ports(void) { - // Optional - runs on startup - // Usually you want to configure pins here -} -void backlight_set(uint8_t level) { - // Optional - runs on level change - // Usually you want to respond to the new value -} - -void backlight_task(void) { - // Optional - runs periodically - // Note that this is called in the main keyboard loop, - // so long running actions here can cause performance issues -} -``` - -## Example Schematic - -In this typical example, the backlight LEDs are all connected in parallel towards an N-channel MOSFET. Its gate pin is wired to one of the microcontroller's GPIO pins through a 470Ω resistor to avoid ringing. -A pulldown resistor is also placed between the gate pin and ground to keep it at a defined state when it is not otherwise being driven by the MCU. -The values of these resistors are not critical - see [this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) for more information. - -![Backlight example circuit](https://i.imgur.com/BmAvoUC.png) diff --git a/docs/feature_bluetooth.md b/docs/feature_bluetooth.md deleted file mode 100644 index f7ded84d8679..000000000000 --- a/docs/feature_bluetooth.md +++ /dev/null @@ -1,46 +0,0 @@ -# Bluetooth - -## Bluetooth Known Supported Hardware - -Currently Bluetooth support is limited to AVR based chips. For Bluetooth 2.1, QMK has support for RN-42 modules. For more recent BLE protocols, currently only the Adafruit Bluefruit SPI Friend is directly supported. BLE is needed to connect to iOS devices. Note iOS does not support mouse input. - -|Board |Bluetooth Protocol |Connection Type|rules.mk |Bluetooth Chip| -|----------------------------------------------------------------|--------------------|---------------|--------------------------------|--------------| -|Roving Networks RN-42 (Sparkfun Bluesmirf) |Bluetooth Classic |UART |`BLUETOOTH_DRIVER = RN42` |RN-42 | -|[Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633)|Bluetooth Low Energy|SPI |`BLUETOOTH_DRIVER = BluefruitLE`|nRF51822 | - -Not Supported Yet but possible: -* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479). [Possible tmk implementation found in](https://github.com/tmk/tmk_keyboard/issues/514) -* HC-05 boards flashed with RN-42 firmware. They apparently both use the CSR BC417 Chip. Flashing it with RN-42 firmware gives it HID capability. -* Sparkfun Bluetooth Mate -* HM-13 based boards - -### Adafruit BLE SPI Friend -Currently The only bluetooth chipset supported by QMK is the Adafruit Bluefruit SPI Friend. It's a Nordic nRF51822 based chip running Adafruit's custom firmware. Data is transmitted via Adafruit's SDEP over Hardware SPI. The [Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) is supported as it's an AVR mcu connected via SPI to the Nordic BLE chip with Adafruit firmware. If Building a custom board with the SPI friend it would be easiest to just use the pin selection that the 32u4 feather uses but you can change the pins in the config.h options with the following defines: -* `#define BLUEFRUIT_LE_RST_PIN D4` -* `#define BLUEFRUIT_LE_CS_PIN B4` -* `#define BLUEFRUIT_LE_IRQ_PIN E6` - -A Bluefruit UART friend can be converted to an SPI friend, however this [requires](https://github.com/qmk/qmk_firmware/issues/2274) some reflashing and soldering directly to the MDBT40 chip. - - -## Bluetooth Rules.mk Options - -The currently supported Bluetooth chipsets do not support [N-Key Rollover (NKRO)](reference_glossary.md#n-key-rollover-nkro), so `rules.mk` must contain `NKRO_ENABLE = no`. - -Add the following to your `rules.mk`: - -```make -BLUETOOTH_ENABLE = yes -BLUETOOTH_DRIVER = BluefruitLE # or RN42 -``` - -## Bluetooth Keycodes - -This is used when multiple keyboard outputs can be selected. Currently this only allows for switching between USB and Bluetooth on keyboards that support both. - -|Key |Aliases |Description | -|---------------------|---------|----------------------------------------------| -|`QK_OUTPUT_AUTO` |`OU_AUTO`|Automatically switch between USB and Bluetooth| -|`QK_OUTPUT_USB` |`OU_USB` |USB only | -|`QK_OUTPUT_BLUETOOTH`|`OU_BT` |Bluetooth only | diff --git a/docs/feature_bootmagic.md b/docs/feature_bootmagic.md deleted file mode 100644 index 4239cdfd2a26..000000000000 --- a/docs/feature_bootmagic.md +++ /dev/null @@ -1,81 +0,0 @@ -# Bootmagic Lite :id=bootmagic-lite - -The Bootmagic Lite feature that only handles jumping into the bootloader. This is great for boards that don't have a physical reset button, giving you a way to jump into the bootloader - -On some keyboards Bootmagic Lite is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk` with: - -```make -BOOTMAGIC_ENABLE = yes -``` - -Additionally, you may want to specify which key to use. This is especially useful for keyboards that have unusual matrices. To do so, you need to specify the row and column of the key that you want to use. Add these entries to your `config.h` file: - -```c -#define BOOTMAGIC_LITE_ROW 0 -#define BOOTMAGIC_LITE_COLUMN 1 -``` - -By default, these are set to 0 and 0, which is usually the "ESC" key on a majority of keyboards. - -And to trigger the bootloader, you hold this key down when plugging the keyboard in. Just the single key. - -!> Using Bootmagic Lite will **always reset** the EEPROM, so you will lose any settings that have been saved. - -## Split Keyboards - -When [handedness](feature_split_keyboard.md#setting-handedness) is predetermined via options like `SPLIT_HAND_PIN` or `EE_HANDS`, you might need to configure a different key between halves. To identify the correct key for the right half, examine the split key matrix defined in the `.h` file, e.g.: - -```c -#define LAYOUT_split_3x5_2( \ - L01, L02, L03, L04, L05, R01, R02, R03, R04, R05, \ - L06, L07, L08, L09, L10, R06, R07, R08, R09, R10, \ - L11, L12, L13, L14, L15, R11, R12, R13, R14, R15, \ - L16, L17, R16, R17 \ - ) \ - { \ - { L01, L02, L03, L04, L05 }, \ - { L06, L07, L08, L09, L10 }, \ - { L11, L12, L13, L14, L15 }, \ - { L16, L17, KC_NO, KC_NO, KC_NO }, \ - { R01, R02, R03, R04, R05 }, \ - { R06, R07, R08, R09, R10 }, \ - { R11, R12, R13, R14, R15 }, \ - { R16, R17, KC_NO, KC_NO, KC_NO } \ - } -``` - -If you pick the top right key for the right half, it is `R05` on the top layout. Within the key matrix below, `R05` is located on row 4 columnn 4. To use that key as the right half's Bootmagic Lite trigger, add these entries to your `config.h` file: - -```c -#define BOOTMAGIC_LITE_ROW_RIGHT 4 -#define BOOTMAGIC_LITE_COLUMN_RIGHT 4 -``` - -?> These values are not set by default. - -## Advanced Bootmagic Lite - -The `bootmagic_lite` function is defined weakly, so that you can replace this in your code, if you need. A great example of this is the Zeal60 boards that have some additional handling needed. - -To replace the function, all you need to do is add something like this to your code: - -```c -void bootmagic_lite(void) { - matrix_scan(); - wait_ms(DEBOUNCE * 2); - matrix_scan(); - - if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { - // Jump to bootloader. - bootloader_jump(); - } -} -``` - -You can define additional logic here. For instance, resetting the EEPROM or requiring additional keys to be pressed to trigger Bootmagic Lite. Keep in mind that `bootmagic_lite` is called before a majority of features are initialized in the firmware. - -## Addenda - -To manipulate settings that were formerly configured through the now-deprecated full Bootmagic feature, see [Magic Keycodes](keycodes_magic.md). - -The Command feature, formerly known as Magic, also allows you to control different aspects of your keyboard. While it shares some functionality with Magic Keycodes, it also allows you to do things that Magic Keycodes cannot, such as printing version information to the console. For more information, see [Command](feature_command.md). diff --git a/docs/feature_caps_word.md b/docs/feature_caps_word.md deleted file mode 100644 index 7f726b059d82..000000000000 --- a/docs/feature_caps_word.md +++ /dev/null @@ -1,189 +0,0 @@ -# Caps Word - -It is often useful to type a single word in all capitals, for instance -abbreviations like "QMK", or in code, identifiers like `KC_SPC`. "Caps Word" is -a modern alternative to Caps Lock: - -* While active, letters are capitalized and `-` becomes `_`. The `_` makes it easier - to type constant names (eg 'PROGRAM\_CONSTANTS'). - -* Caps Word automatically disables - itself at the end of the word. That is, it stops by default once a space or - any key other than `KC_A`--`KC_Z`, `KC_0`--`KC_9`, `KC_MINS`, `KC_UNDS`, - `KC_DELETE`, or `KC_BACKSPACE` is pressed. Caps Word also disables itself if - the keyboard is idle for 5 seconds. This is configurable, see below. - -* To avoid requiring a dedicated key for Caps Word, there is an option - (`BOTH_SHIFTS_TURNS_ON_CAPS_WORD`) to activate Caps Word by simultaneously - pressing both shift keys. See below for other options. - -* The implementation does not use the Caps Lock (`KC_CAPS`) keycode. Caps Word - works even if you're remapping Caps Lock at the OS level to Ctrl or something - else, as Emacs and Vim users often do. As a consequence, Caps Word does not - follow the typical Caps Lock behaviour and may thus act in potentially - unexpected ways, especially when using an *OS* keyboard layout other than US - or UK. For example, Dvorak's , < key (`DV_COMM` aka `KC_W`) will - get shifted because Caps Word interprets that keycode as the letter 'W' by - default, the Spanish Ñ key (`ES_NTIL` aka `KC_SCLN`) will not get - capitalized because Caps Word interprets it as the semicolon ';' punctuation - character, and the US hyphen key (`KC_MINS`), while unaffected by Caps Lock, - is shifted by Caps Word. However, this is not really a problem because you can - [configure which keys should Caps Word - shift](#configure-which-keys-are-word-breaking). - - -## How do I enable Caps Word :id=how-do-i-enable-caps-word - -In your `rules.mk`, add: - -```make -CAPS_WORD_ENABLE = yes -``` - -Next, use one the following methods to activate Caps Word: - -* **Activate by pressing a key**: Use the `QK_CAPS_WORD_TOGGLE` keycode (short - alias `CW_TOGG`) in your keymap. - -* **Activate by pressing Left Shift + Right Shift**: Add `#define - BOTH_SHIFTS_TURNS_ON_CAPS_WORD` to config.h. You may also need to disable or - reconfigure Command, details below. Then, simultaneously pressing both left - and right shifts turns on Caps Word. This method works with the plain - `KC_LSFT` and `KC_RSFT` keycodes as well as one-shot shifts and Space Cadet - shifts. If your shift keys are mod-taps, hold both shift mod-tap keys until - the tapping term, then release them. - -* **Activate by double tapping Left Shift**: Add `#define - DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD` config.h. Then, double tapping Left Shift - turns on Caps Word. This method works with `KC_LSFT` or one-shot Left Shift - `OSM(MOD_LSFT)`. To count as a double tap, the maximum time in milliseconds - between taps is `TAPPING_TERM`, or if using `TAPPING_TERM_PER_KEY`, the time - returned by `get_tapping_term()` for the shift keycode being tapped. - -* **Custom activation**: You can activate Caps Word from code by calling - `caps_word_on()`. This may be used to activate Caps Word through [a - combo](feature_combo.md) or [tap dance](feature_tap_dance.md) or any means - you like. - -### Troubleshooting: Command :id=troubleshooting-command - -When using `BOTH_SHIFTS_TURNS_ON_CAPS_WORD`, you might see a compile message -**"BOTH_SHIFTS_TURNS_ON_CAPS_WORD and Command should not be enabled at the same -time, since both use the Left Shift + Right Shift key combination."** - -Many keyboards enable the [Command feature](feature_command.md), which by -default is also activated using the Left Shift + Right Shift key combination. To -fix this conflict, please disable Command by adding in rules.mk: - -```make -COMMAND_ENABLE = no -``` - -Or configure Command to use another key combination like Left Ctrl + Right Ctrl -by defining `IS_COMMAND()` in config.h: - -```c -// Activate Command with Left Ctrl + Right Ctrl. -#define IS_COMMAND() (get_mods() == MOD_MASK_CTRL) -``` - - -## Customizing Caps Word :id=customizing-caps-word - -### Invert on shift :id=invert-on-shift - -By default, Caps Word turns off when Shift keys are pressed, considering them as -word-breaking. Alternatively with the `CAPS_WORD_INVERT_ON_SHIFT` option, -pressing the Shift key continues Caps Word and inverts the shift state. This -is convenient for uncapitalizing one or a few letters within a word, for -example with Caps Word on, typing "D, B, Shift+A, Shift+A, S" produces "DBaaS", -or typing "P, D, F, Shift+S" produces "PDFs". - -Enable it by adding in config.h - -```c -#define CAPS_WORD_INVERT_ON_SHIFT -``` - -This option works with regular Shift keys `KC_LSFT` and `KC_RSFT`, mod-tap Shift -keys, and one-shot Shift keys. Note that while Caps Word is on, one-shot Shift -keys behave like regular Shift keys, and have effect only while they are held. - - -### Idle timeout :id=idle-timeout - -Caps Word turns off automatically if no keys are pressed for -`CAPS_WORD_IDLE_TIMEOUT` milliseconds. The default is 5000 (5 seconds). -Configure the timeout duration in config.h, for instance - -```c -#define CAPS_WORD_IDLE_TIMEOUT 3000 // 3 seconds. -``` - -Setting `CAPS_WORD_IDLE_TIMEOUT` to 0 configures Caps Word to never time out. -Caps Word then remains active indefinitely until a word breaking key is pressed. - - -### Functions :id=functions - -Functions to manipulate Caps Word: - -| Function | Description | -|-------------------------|------------------------------------------------| -| `caps_word_on()` | Turns Caps Word on. | -| `caps_word_off()` | Turns Caps Word off. | -| `caps_word_toggle()` | Toggles Caps Word. | -| `is_caps_word_on()` | Returns true if Caps Word is currently on. | - - -### Configure which keys are "word breaking" :id=configure-which-keys-are-word-breaking - -You can define the `caps_word_press_user(uint16_t keycode)` callback to -configure which keys should be shifted and which keys are considered "word -breaking" and stop Caps Word. - -The callback is called on every key press while Caps Word is active. When the -key should be shifted (that is, a letter key), the callback should call -`add_weak_mods(MOD_BIT(KC_LSFT))` to shift the key. Returning true continues the -current "word," while returning false is "word breaking" and deactivates Caps -Word. The default callback is - -```c -bool caps_word_press_user(uint16_t keycode) { - switch (keycode) { - // Keycodes that continue Caps Word, with shift applied. - case KC_A ... KC_Z: - case KC_MINS: - add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key. - return true; - - // Keycodes that continue Caps Word, without shifting. - case KC_1 ... KC_0: - case KC_BSPC: - case KC_DEL: - case KC_UNDS: - return true; - - default: - return false; // Deactivate Caps Word. - } -} -``` - - -### Representing Caps Word state :id=representing-caps-word-state - -Define `caps_word_set_user(bool active)` to get callbacks when Caps Word turns -on or off. This is useful to represent the current Caps Word state, e.g. by -setting an LED or playing a sound. In your keymap, define - -```c -void caps_word_set_user(bool active) { - if (active) { - // Do something when Caps Word activates. - } else { - // Do something when Caps Word deactivates. - } -} -``` - diff --git a/docs/feature_combo.md b/docs/feature_combo.md deleted file mode 100644 index fd241061fbf4..000000000000 --- a/docs/feature_combo.md +++ /dev/null @@ -1,397 +0,0 @@ -# Combos - -The Combo feature is a chording type solution for adding custom actions. It lets you hit multiple keys at once and produce a different effect. For instance, hitting `A` and `B` within the combo term would hit `ESC` instead, or have it perform even more complex tasks. - -To enable this feature, you need to add `COMBO_ENABLE = yes` to your `rules.mk`. - -Then, in your `keymap.c` file, you'll need to define a sequence of keys, terminated with `COMBO_END`, and a structure to list the combination of keys, and its resulting action. - -```c -const uint16_t PROGMEM test_combo1[] = {KC_A, KC_B, COMBO_END}; -const uint16_t PROGMEM test_combo2[] = {KC_C, KC_D, COMBO_END}; -combo_t key_combos[] = { - COMBO(test_combo1, KC_ESC), - COMBO(test_combo2, LCTL(KC_Z)), // keycodes with modifiers are possible too! -}; -``` - -This will send "Escape" if you hit the A and B keys, and Ctrl+Z when you hit the C and D keys. - -## Mod-Tap Support -[Mod-Tap](mod_tap.md) feature is also supported together with combos. You will need to use the full Mod-Tap keycode in the combo definition, e.g.: - -```c -const uint16_t PROGMEM test_combo1[] = {LSFT_T(KC_A), LT(1, KC_B), COMBO_END}; -``` - -## Overlapping Combos -It is possible to overlap combos. Before, with the example below both combos would activate when all three keys were pressed. Now only the three key combo will activate. - -```c -const uint16_t PROGMEM test_combo1[] = {LSFT_T(KC_A), LT(1, KC_B), COMBO_END}; -const uint16_t PROGMEM test_combo2[] = {LSFT_T(KC_A), LT(1, KC_B), KC_C, COMBO_END}; -combo_t key_combos[] = { - COMBO(test_combo1, KC_ESC) - COMBO(test_combo2, KC_TAB) -}; -``` - -## Examples - -A long list of combos can be defined in an `enum` list: - -```c -enum combos { - AB_ESC, - JK_TAB, - QW_SFT, - SD_LAYER -}; - -const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; -const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; -const uint16_t PROGMEM qw_combo[] = {KC_Q, KC_W, COMBO_END}; -const uint16_t PROGMEM sd_combo[] = {KC_S, KC_D, COMBO_END}; - -combo_t key_combos[] = { - [AB_ESC] = COMBO(ab_combo, KC_ESC), - [JK_TAB] = COMBO(jk_combo, KC_TAB), - [QW_SFT] = COMBO(qw_combo, KC_LSFT), - [SD_LAYER] = COMBO(sd_combo, MO(_LAYER)), -}; -``` - -For a more complicated implementation, you can use the `process_combo_event` function to add custom handling. - -```c -enum combo_events { - EM_EMAIL, - BSPC_LSFT_CLEAR, -}; - -const uint16_t PROGMEM email_combo[] = {KC_E, KC_M, COMBO_END}; -const uint16_t PROGMEM clear_line_combo[] = {KC_BSPC, KC_LSFT, COMBO_END}; - -combo_t key_combos[] = { - [EM_EMAIL] = COMBO_ACTION(email_combo), - [BSPC_LSFT_CLEAR] = COMBO_ACTION(clear_line_combo), -}; -/* COMBO_ACTION(x) is same as COMBO(x, KC_NO) */ - -void process_combo_event(uint16_t combo_index, bool pressed) { - switch(combo_index) { - case EM_EMAIL: - if (pressed) { - SEND_STRING("john.doe@example.com"); - } - break; - case BSPC_LSFT_CLEAR: - if (pressed) { - tap_code16(KC_END); - tap_code16(S(KC_HOME)); - tap_code16(KC_BSPC); - } - break; - } -} -``` - -This will send "john.doe@example.com" if you chord E and M together, and clear the current line with Backspace and Left-Shift. You could change this to do stuff like play sounds or change settings. - -It is worth noting that `COMBO_ACTION`s are not needed anymore. As of [PR#8591](https://github.com/qmk/qmk_firmware/pull/8591/), it is possible to run your own custom keycodes from combos. Just define the custom keycode, program its functionality in `process_record_user`, and define a combo with `COMBO(, )`. See the first example in [Macros](feature_macros.md). - -## Keycodes -You can enable, disable and toggle the Combo feature on the fly. This is useful if you need to disable them temporarily, such as for a game. The following keycodes are available for use in your `keymap.c` - -|Keycode |Aliases |Description | -|-----------------|---------|--------------------------------| -|`QK_COMBO_ON` |`CM_ON` |Turns on Combo feature | -|`QK_COMBO_OFF` |`CM_OFF` |Turns off Combo feature | -|`QK_COMBO_TOGGLE`|`CM_TOGG`|Toggles Combo feature on and off| - -## Advanced Configuration -These configuration settings can be set in your `config.h` file. - -### Combo Term -By default, the timeout for the Combos to be recognized is set to 50ms. This can be changed if accidental combo misfires are happening or if you're having difficulties pressing keys at the same time. For instance, `#define COMBO_TERM 40` would set the timeout period for combos to 40ms. - -### Buffer and state sizes -If you're using long combos, or you have a lot of overlapping combos, you may run into issues with this, as the buffers may not be large enough to accommodate what you're doing. In this case, you can configure the sizes of the buffers used. Be aware, larger combo sizes and larger buffers will increase memory usage! - -To configure the amount of keys a combo can be composed of, change the following: - -| Keys | Define to be set | -|------|-----------------------------------| -| 6 | `#define EXTRA_SHORT_COMBOS` | -| 8 | QMK Default | -| 16 | `#define EXTRA_LONG_COMBOS` | -| 32 | `#define EXTRA_EXTRA_LONG_COMBOS` | - -Defining `EXTRA_SHORT_COMBOS` combines a combo's internal state into just one byte. This can, in some cases, save some memory. If it doesn't, no point using it. If you do, you also have to make sure you don't define combos with more than 6 keys. - -Processing combos has two buffers, one for the key presses, another for the combos being activated. Use the following options to configure the sizes of these buffers: - -| Define | Default | -|-------------------------------------|------------------------------------------------------| -| `#define COMBO_KEY_BUFFER_LENGTH 8` | 8 (the key amount `(EXTRA_)EXTRA_LONG_COMBOS` gives) | -| `#define COMBO_BUFFER_LENGTH 4` | 4 | - -### Modifier Combos -If a combo resolves to a Modifier, the window for processing the combo can be extended independently from normal combos. By default, this is disabled but can be enabled with `#define COMBO_MUST_HOLD_MODS`, and the time window can be configured with `#define COMBO_HOLD_TERM 150` (default: `TAPPING_TERM`). With `COMBO_MUST_HOLD_MODS`, you cannot tap the combo any more which makes the combo less prone to misfires. - -### Strict key press order -By defining `COMBO_MUST_PRESS_IN_ORDER` combos only activate when the keys are pressed in the same order as they are defined in the key array. - -### Per Combo Timing, Holding, Tapping and Key Press Order -For each combo, it is possible to configure the time window it has to pressed in, if it needs to be held down, if it needs to be tapped, or if its keys need to be pressed in order. - -For example, tap-only combos are useful if any (or all) of the underlying keys are mod-tap or layer-tap keys. When you tap the combo, you get the combo result. When you press the combo and hold it down, the combo doesn't activate. Instead the keys are processed separately as if the combo wasn't even there. - -In order to use these features, the following configuration options and functions need to be defined. Coming up with useful timings and configuration is left as an exercise for the reader. - -| Config Flag | Function | Description | -|-----------------------------|-----------------------------------------------------------|--------------------------------------------------------------------------------------------------------| -| `COMBO_TERM_PER_COMBO` | uint16_t get_combo_term(uint16_t index, combo_t \*combo) | Optional per-combo timeout window. (default: `COMBO_TERM`) | -| `COMBO_MUST_HOLD_PER_COMBO` | bool get_combo_must_hold(uint16_t index, combo_t \*combo) | Controls if a given combo should fire immediately on tap or if it needs to be held. (default: `false`) | -| `COMBO_MUST_TAP_PER_COMBO` | bool get_combo_must_tap(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if tapped within `COMBO_HOLD_TERM`. (default: `false`) | -| `COMBO_MUST_PRESS_IN_ORDER_PER_COMBO` | bool get_combo_must_press_in_order(uint16_t index, combo_t \*combo) | Controls if a given combo should fire only if its keys are pressed in order. (default: `true`) | - -Examples: -```c -uint16_t get_combo_term(uint16_t index, combo_t *combo) { - // decide by combo->keycode - switch (combo->keycode) { - case KC_X: - return 50; - } - - // or with combo index, i.e. its name from enum. - switch (index) { - case COMBO_NAME_HERE: - return 9001; - } - - // And if you're feeling adventurous, you can even decide by the keys in the chord, - // i.e. the exact array of keys you defined for the combo. - // This can be useful if your combos have a common key and you want to apply the - // same combo term for all of them. - if (combo->keys[0] == KC_ENT) { // if first key in the array is Enter - return 150; - } - - return COMBO_TERM; -} - -bool get_combo_must_hold(uint16_t index, combo_t *combo) { - // Same as above, decide by keycode, the combo index, or by the keys in the chord. - - if (KEYCODE_IS_MOD(combo->keycode) || - (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX) // MO(kc) keycodes - ) { - return true; - } - - switch (index) { - case COMBO_NAME_HERE: - return true; - } - - return false; -} - -bool get_combo_must_tap(uint16_t index, combo_t *combo) { - // If you want all combos to be tap-only, just uncomment the next line - // return true - - // If you want *all* combos, that have Mod-Tap/Layer-Tap/Momentary keys in its chord, to be tap-only, this is for you: - uint16_t key; - uint8_t idx = 0; - while ((key = pgm_read_word(&combo->keys[idx])) != COMBO_END) { - switch (key) { - case QK_MOD_TAP...QK_MOD_TAP_MAX: - case QK_LAYER_TAP...QK_LAYER_TAP_MAX: - case QK_MOMENTARY...QK_MOMENTARY_MAX: - return true; - } - idx += 1; - } - return false; - -} - -bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { - switch (combo_index) { - /* List combos here that you want to only activate if their keys - * are pressed in the same order as they are defined in the combo's key - * array. */ - case COMBO_NAME_HERE: - return true; - default: - return false; - } -} -``` - -### Generic hook to (dis)allow a combo activation - -By defining `COMBO_SHOULD_TRIGGER` and its companying function `bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record)` you can block or allow combos to activate on the conditions of your choice. -For example, you could disallow some combos on the base layer and allow them on another. Or disable combos on the home row when a timer is running. - -Examples: -```c -bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { - /* Disable combo `SOME_COMBO` on layer `_LAYER_A` */ - switch (combo_index) { - case SOME_COMBO: - if (layer_state_is(_LAYER_A)) { - return false; - } - } - - return true; -} -``` - -### Combo timer - -Normally, the timer is started on the first key press and then reset on every subsequent key press within the `COMBO_TERM`. -Inputting combos is relaxed like this, but also slightly more prone to accidental misfires. - -The next two options alter the behaviour of the timer. - -#### `#define COMBO_STRICT_TIMER` - -With `COMBO_STRICT_TIMER`, the timer is started only on the first key press. -Inputting combos is now less relaxed; you need to make sure the full chord is pressed within the `COMBO_TERM`. -Misfires are less common but if you type multiple combos fast, there is a -chance that the latter ones might not activate properly. - -#### `#define COMBO_NO_TIMER` - -By defining `COMBO_NO_TIMER`, the timer is disabled completely and combos are activated on the first key release. -This also disables the "must hold" functionalities as they just wouldn't work at all. - -### Customizable key releases - -By defining `COMBO_PROCESS_KEY_RELEASE` and implementing the function `bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode)`, you can run your custom code on each key release after a combo was activated. For example you could change the RGB colors, activate haptics, or alter the modifiers. - -You can also release a combo early by returning `true` from the function. - -Here's an example where a combo resolves to two modifiers, and on key releases the modifiers are unregistered one by one, depending on which key was released. - -```c -enum combos { - AB_MODS -}; - -const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; - -combo_t key_combos[] = { - [AB_MODS] = COMBO(ab_combo, LCTL(KC_LSFT)), -}; - -bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { - switch (combo_index) { - case AB_MODS: - switch(keycode) { - case KC_A: - unregister_mods(MOD_MASK_CTRL); - break; - case KC_B: - unregister_mods(MOD_MASK_SHIFT); - break; - } - return false; // do not release combo - } - return false; -} -``` -### Layer independent combos - -If you, for example, use multiple base layers for different key layouts, one for QWERTY, and another one for Colemak, you might want your combos to work from the same key positions on all layers. Defining the same combos again for another layout is redundant and takes more memory. The solution is to just check the keycodes from one layer. - -With `#define COMBO_ONLY_FROM_LAYER 0` in config.h, the combos' keys are always checked from layer `0`, even if other layers are active. - -#### Combo reference layers by layer. - -If not using `COMBO_ONLY_FROM_LAYER` it is possible to specify a -combo reference layer for any layer using the `combo_ref_from_layer` hook. -The combo macros automatically create this function from the `COMBO_REF_LAYER()` -entries given. - -This function returns the assigned reference layer for the current layer. -if there is no match, it returns the default reference layer if set, -or the current layer otherwise. A default layer can be set with -`DEFAULT_REF_LAYER(_MY_COMBO_REF_LAYER)` - -If not set, the default reference layer selection from the automatically generated -`combo-ref-from-layer()` will be the current layer. - -The following `combo_ref_from_layer` function -will give a reference layer of _QWERTY for the _DVORAK layer and -will give the _NAV layer as a reference to it's self. All other layers -will have the default for their combo reference layer. If the default -is not set, all other layers will reference themselves. - - ```c - #define COMBO_REF_DEFAULT _MY_COMBO_LAYER - ... - - uint8_t combo_ref_from_layer(uint8_t layer){ - switch (get_highest_layer(layer_state)){ - case _DVORAK: return _QWERTY; - case _NAV: return _NAV; - default: return _MY_COMBO_LAYER; - } - return layer; // important if default is not in case. - } - - ``` - - The equivalent definition using the combo macros is this: - - ```c - COMBO_REF_LAYER(_DVORAK, _QWERTY) - COMBO_REF_LAYER(_NAV, _NAV) - DEFAULT_REF_LAYER(_MY_COMBO_LAYER). - ``` - - -## User callbacks - -In addition to the keycodes, there are a few functions that you can use to set the status, or check it: - -|Function |Description | -|-----------|--------------------------------------------------------------------| -| `combo_enable()` | Enables the combo feature | -| `combo_disable()` | Disables the combo feature, and clears the combo buffer | -| `combo_toggle()` | Toggles the state of the combo feature | -| `is_combo_enabled()` | Returns the status of the combo feature state (true or false) | - - -## Dictionary Management - -Having 3 places to update when adding new combos or altering old ones does become cumbersome when you have a lot of combos. We can alleviate this with some magic! ... If you consider C macros magic. -First, you need to add `VPATH += keyboards/gboards` to your `rules.mk`. Next, include the file `g/keymap_combo.h` in your `keymap.c`. - -!> This functionality uses the same `process_combo_event` function as `COMBO_ACTION` macros do, so you cannot use the function yourself in your keymap. Instead, you have to define the `case`s of the `switch` statement by themselves within `inject.h`, which `g/keymap_combo.h` will then include into the function. - -Then, write your combos in `combos.def` file in the following manner: - -```c -// Alternate reference layers by layer -// Layer Reference layer -COMBO_REF_LAYER(_DVORAK, _QWERTY) // reference the qwerty layer for dvorak. -COMBO_REF_LAYER(_NAV, _NAV) // explicit reference to self instead of the default. - -// name result chord keys -COMB(AB_ESC, KC_ESC, KC_A, KC_B) -COMB(JK_TAB, KC_TAB, KC_J, KC_K) -COMB(JKL_SPC, KC_SPC, KC_J, KC_K, KC_L) -COMB(BSSL_CLR, KC_NO, KC_BSPC, KC_LSFT) // using KC_NO as the resulting keycode is the same as COMBO_ACTION before. -COMB(QW_UNDO, C(KC_Z), KC_Q, KC_W) -SUBS(TH_THE, "the", KC_T, KC_H) // SUBS uses SEND_STRING to output the given string. -... -``` - -For small to huge ready made dictionaries of combos, you can check out http://combos.gboards.ca/. diff --git a/docs/feature_command.md b/docs/feature_command.md deleted file mode 100644 index 830006613102..000000000000 --- a/docs/feature_command.md +++ /dev/null @@ -1,51 +0,0 @@ -# Command - -Command, formerly known as Magic, is a way to change your keyboard's behavior without having to flash or unplug it to use [Bootmagic Lite](feature_bootmagic.md). There is a lot of overlap between this functionality and the [Magic Keycodes](keycodes_magic.md). Wherever possible we encourage you to use that feature instead of Command. - -On some keyboards Command is disabled by default. If this is the case, it must be explicitly enabled in your `rules.mk`: - -```make -COMMAND_ENABLE = yes -``` - -## Usage - -To use Command, hold down the key combination defined by the `IS_COMMAND()` macro. By default this is Left Shift+Right Shift. Then, press the key corresponding to the command you want. For example, to output the current QMK version to the QMK Toolbox console, press Left Shift+Right Shift+`V`. - -## Configuration - -If you would like to change the key assignments for Command, `#define` these in your `config.h` at either the keyboard or keymap level. All keycode assignments here must omit the `KC_` prefix. - -|Define |Default |Description | -|------------------------------------|--------------------------------|------------------------------------------------| -|`IS_COMMAND()` |`(get_mods() == MOD_MASK_SHIFT)`|The key combination to activate Command | -|`MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` |`true` |Set default layer with the Function row | -|`MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` |`true` |Set default layer with the number keys | -|`MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM`|`false` |Set default layer with `MAGIC_KEY_LAYER0..9` | -|`MAGIC_KEY_DEBUG` |`D` |Toggle debugging over serial | -|`MAGIC_KEY_DEBUG_MATRIX` |`X` |Toggle key matrix debugging | -|`MAGIC_KEY_DEBUG_KBD` |`K` |Toggle keyboard debugging | -|`MAGIC_KEY_DEBUG_MOUSE` |`M` |Toggle mouse debugging | -|`MAGIC_KEY_CONSOLE` |`C` |Enable the Command console | -|`MAGIC_KEY_VERSION` |`V` |Print the running QMK version to the console | -|`MAGIC_KEY_STATUS` |`S` |Print the current keyboard status to the console| -|`MAGIC_KEY_HELP` |`H` |Print Command help to the console | -|`MAGIC_KEY_HELP_ALT` |`SLASH` |Print Command help to the console (alternate) | -|`MAGIC_KEY_LAYER0` |`0` |Make layer 0 the default layer | -|`MAGIC_KEY_LAYER0_ALT` |`GRAVE` |Make layer 0 the default layer (alternate) | -|`MAGIC_KEY_LAYER1` |`1` |Make layer 1 the default layer | -|`MAGIC_KEY_LAYER2` |`2` |Make layer 2 the default layer | -|`MAGIC_KEY_LAYER3` |`3` |Make layer 3 the default layer | -|`MAGIC_KEY_LAYER4` |`4` |Make layer 4 the default layer | -|`MAGIC_KEY_LAYER5` |`5` |Make layer 5 the default layer | -|`MAGIC_KEY_LAYER6` |`6` |Make layer 6 the default layer | -|`MAGIC_KEY_LAYER7` |`7` |Make layer 7 the default layer | -|`MAGIC_KEY_LAYER8` |`8` |Make layer 8 the default layer | -|`MAGIC_KEY_LAYER9` |`9` |Make layer 9 the default layer | -|`MAGIC_KEY_BOOTLOADER` |`B` |Jump to bootloader | -|`MAGIC_KEY_BOOTLOADER_ALT` |`ESC` |Jump to bootloader (alternate) | -|`MAGIC_KEY_LOCK` |`CAPS` |Lock the keyboard so nothing can be typed | -|`MAGIC_KEY_EEPROM` |`E` |Print stored EEPROM config to the console | -|`MAGIC_KEY_EEPROM_CLEAR` |`BSPACE` |Clear the EEPROM | -|`MAGIC_KEY_NKRO` |`N` |Toggle N-Key Rollover (NKRO) | -|`MAGIC_KEY_SLEEP_LED` |`Z` |Toggle LED when computer is sleeping | diff --git a/docs/feature_converters.md b/docs/feature_converters.md deleted file mode 100644 index b1abfa373ad8..000000000000 --- a/docs/feature_converters.md +++ /dev/null @@ -1,209 +0,0 @@ -# Converters - -Since many drop-in replacement controllers now exist, we've done our best to make them easy to use in existing designs. - -This page documents the handy automated process for converting keyboards. - -### Supported Converters - -Currently the following converters are available: - -| From | To | -|------------|-------------------| -| `promicro` | `proton_c` | -| `promicro` | `kb2040` | -| `promicro` | `promicro_rp2040` | -| `promicro` | `blok` | -| `promicro` | `bit_c_pro` | -| `promicro` | `stemcell` | -| `promicro` | `bonsai_c4` | -| `promicro` | `rp2040_ce` | -| `promicro` | `elite_pi` | -| `promicro` | `helios` | -| `promicro` | `liatris` | -| `promicro` | `michi` | -| `elite_c` | `stemcell` | -| `elite_c` | `rp2040_ce` | -| `elite_c` | `elite_pi` | -| `elite_c` | `helios` | -| `elite_c` | `liatris` | - -See below for more in depth information on each converter. - -## Overview - -Each converter category is broken down by its declared `pin compatibility`. -This ensures that only valid combinations are attempted. - -You can generate the firmware by appending `-e CONVERT_TO=` to your compile/flash command. For example: - -```sh -qmk flash -c -kb keebio/bdn9/rev1 -km default -e CONVERT_TO=proton_c -``` - -You can also add the same `CONVERT_TO=` to your keymap's `rules.mk`, which will accomplish the same thing. - -?> If you get errors about `PORTB/DDRB`, etc not being defined, you'll need to convert the keyboard's code to use the [GPIO Controls](gpio_control.md) that will work for both ARM and AVR. This shouldn't affect the AVR builds at all. - -### Conditional Configuration - -Once a converter is enabled, it exposes the `CONVERT_TO_` flag that you can use in your code with `#ifdef`s, For example: - -```c -#ifdef CONVERT_TO_PROTON_C - // Proton C code -#else - // Pro Micro code -#endif -``` - -### Pin Compatibility - -To ensure compatibility, provide validation, and power future workflows, a keyboard should declare its `pin compatibility`. For legacy reasons, this is currently assumed to be `promicro`. - -Currently the following pin compatibility interfaces are defined: - -| Pinout | Notes | -|------------|-----------------------------------| -| `promicro` | Includes RX/TX LEDs | -| `elite_c` | Includes bottom row pins, no LEDs | - -To declare the base for conversions, add this line to your keyboard's `rules.mk`: - -```makefile -PIN_COMPATIBLE = elite_c -``` - -## Pro Micro - -If a board currently supported in QMK uses a [Pro Micro](https://www.sparkfun.com/products/12640) (or compatible board), the supported alternative controllers are: - -| Device | Target | -|------------------------------------------------------------------------------------------|-------------------| -| [Proton C](https://qmk.fm/proton-c/) | `proton_c` | -| [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) | `kb2040` | -| [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) | `promicro_rp2040` | -| [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) | `blok` | -| [Bit-C PRO](https://nullbits.co/bit-c-pro) | `bit_c_pro` | -| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | -| [customMK Bonsai C4](https://shop.custommk.com/products/bonsai-c4-microcontroller-board) | `bonsai_c4` | -| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | -| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | -| [Liatris](https://splitkb.com/products/liatris) | `liatris` | -| [Michi](https://github.com/ci-bus/michi-promicro-rp2040) | `michi` | - -Converter summary: - -| Target | Argument | `rules.mk` | Condition | -|-------------------|---------------------------------|------------------------------|-------------------------------------| -| `proton_c` | `-e CONVERT_TO=proton_c` | `CONVERT_TO=proton_c` | `#ifdef CONVERT_TO_PROTON_C` | -| `kb2040` | `-e CONVERT_TO=kb2040` | `CONVERT_TO=kb2040` | `#ifdef CONVERT_TO_KB2040` | -| `promicro_rp2040` | `-e CONVERT_TO=promicro_rp2040` | `CONVERT_TO=promicro_rp2040` | `#ifdef CONVERT_TO_PROMICRO_RP2040` | -| `blok` | `-e CONVERT_TO=blok` | `CONVERT_TO=blok` | `#ifdef CONVERT_TO_BLOK` | -| `bit_c_pro` | `-e CONVERT_TO=bit_c_pro` | `CONVERT_TO=bit_c_pro` | `#ifdef CONVERT_TO_BIT_C_PRO` | -| `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | -| `bonsai_c4` | `-e CONVERT_TO=bonsai_c4` | `CONVERT_TO=bonsai_c4` | `#ifdef CONVERT_TO_BONSAI_C4` | -| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | -| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` | -| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | -| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | -| `michi` | `-e CONVERT_TO=michi` | `CONVERT_TO=michi` | `#ifdef CONVERT_TO_MICHI` | - -### Proton C :id=proton_c - -The Proton C only has one on-board LED (C13), and by default, the TXLED (D5) is mapped to it. If you want the RXLED (B0) mapped to it instead, add this line to your `config.h`: - -```c -#define CONVERT_TO_PROTON_C_RXLED -``` - -The following defaults are based on what has been implemented for STM32 boards. - -| Feature | Notes | -|----------------------------------------------|------------------------------------------------------------------------------------------------------------------| -| [Audio](feature_audio.md) | Enabled | -| [RGB Lighting](feature_rgblight.md) | Disabled | -| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration | -| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | -| [Split keyboards](feature_split_keyboard.md) | Partial - heavily dependent on enabled features | - -### Adafruit KB2040 :id=kb2040 - -The following defaults are based on what has been implemented for [RP2040](platformdev_rp2040.md) boards. - -| Feature | Notes | -|----------------------------------------------|------------------------------------------------------------------------------------------------------------------| -| [RGB Lighting](feature_rgblight.md) | Enabled via `PIO` vendor driver | -| [Backlight](feature_backlight.md) | Forces [task driven PWM](feature_backlight.md#software-pwm-driver) until ARM can provide automatic configuration | -| USB Host (e.g. USB-USB converter) | Not supported (USB host code is AVR specific and is not currently supported on ARM) | -| [Split keyboards](feature_split_keyboard.md) | Partial via `PIO` vendor driver - heavily dependent on enabled features | - -### SparkFun Pro Micro - RP2040, Blok, Bit-C PRO and Michi :id=promicro_rp2040 - -Currently identical to [Adafruit KB2040](#kb2040). - -### STeMCell :id=stemcell - -Feature set currently identical to [Proton C](#proton_c). -There are two versions of STeMCell available, with different pinouts: - - v1.0.0 - - v2.0.0 (pre-release v1.0.1, v1.0.2) -Default official firmware only supports v2.0.0 STeMCell. - -STeMCell has support to swap UART and I2C pins, to enable single-wire uart communication in STM chips. - -The following additional flags has to be used while compiling, based on the pin used for split communication. - -| Split Pin | Compile flags | -|-----------|---------------| -| D3 | -e STMC_US=yes| -| D2 | Not needed | -| D1 | -e STMC_IS=yes| -| D0 | Not needed | - -### Bonsai C4 :id=bonsai_c4 - -The Bonsai C4 only has one on-board LED (B2), and by default, both the Pro Micro TXLED (D5) and RXLED (B0) are mapped to it. If you want only one of them mapped, you can undefine one and redefine it to another pin by adding these line to your `config.h`: - -```c -#undef B0 -// If VBUS detection is unused, we can send RXLED to the Vbus detect pin instead -#define B0 PAL_LINE(GPIOA, 9) -``` - -### RP2040 Community Edition - Elite-Pi, Helios, and Liatris :id=rp2040_ce - -Feature set currently identical to [Adafruit KB2040](#kb2040). - -Enables VBUS detection by default for superior split keyboard support. - -For more information, refer to the [RP2040 Community Edition](platformdev_rp2040.md#rp2040_ce) docs. - -## Elite-C - -If a board currently supported in QMK uses an [Elite-C](https://keeb.io/products/elite-c-low-profile-version-usb-c-pro-micro-replacement-atmega32u4), the supported alternative controllers are: - -| Device | Target | -|----------------------------------------------------------------------------------|-------------------| -| [STeMCell](https://github.com/megamind4089/STeMCell) | `stemcell` | -| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | `elite_pi` | -| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | `helios` | -| [Liatris](https://splitkb.com/products/liatris) | `liatris` | - -Converter summary: - -| Target | Argument | `rules.mk` | Condition | -|-------------------|---------------------------------|------------------------------|-------------------------------------| -| `stemcell` | `-e CONVERT_TO=stemcell` | `CONVERT_TO=stemcell` | `#ifdef CONVERT_TO_STEMCELL` | -| `rp2040_ce` | `-e CONVERT_TO=rp2040_ce` | `CONVERT_TO=rp2040_ce` | `#ifdef CONVERT_TO_RP2040_CE` | -| `elite_pi` | `-e CONVERT_TO=elite_pi` | `CONVERT_TO=elite_pi` | `#ifdef CONVERT_TO_ELITE_PI` | -| `helios` | `-e CONVERT_TO=helios` | `CONVERT_TO=helios` | `#ifdef CONVERT_TO_HELIOS` | -| `liatris` | `-e CONVERT_TO=liatris` | `CONVERT_TO=liatris` | `#ifdef CONVERT_TO_LIATRIS` | - -### STeMCell :id=stemcell_elite - -Currently identical to [STeMCell](#stemcell) with support for the additional bottom row of pins. - -### RP2040 Community Edition :id=rp2040_ce_elite - -Currently identical to [RP2040 Community Edition](#rp2040_ce), with support for the additional bottom row of pins. diff --git a/docs/feature_debounce_type.md b/docs/feature_debounce_type.md deleted file mode 100644 index 807b902a6cc3..000000000000 --- a/docs/feature_debounce_type.md +++ /dev/null @@ -1,134 +0,0 @@ -# Contact bounce / contact chatter - -Mechanical switches often don't have a clean single transition between pressed and unpressed states. - -In an ideal world, when you press a switch, you would expect the digital pin to see something like this: -(X axis showing time -``` -voltage +---------------------- - ^ | - | | - | ------------------+ - ----> time -``` - -However in the real world you will actually see contact bounce, which will look like multiple 1->0 and 0->1 transitions, -until the value finally settles. -``` - +-+ +--+ +------------- - | | | | | - | | | | | -+-----------------+ +-+ +-+ -``` -The time it takes for the switch to settle might vary with switch type, age, and even pressing technique. - -If the device chooses not to mitigate contact bounce, then often actions that happen when the switch is pressed are repeated -multiple times. - -There are many ways to handle contact bounce ("Debouncing"). Some include employing additional hardware, for example an RC filter, -while there are various ways to do debouncing in software too, often called debounce algorithms. This page discusses software -debouncing methods available in QMK. - -While technically not considered contact bounce/contact chatter, some switch technologies are susceptible to noise, meaning, -while the key is not changing state, sometimes short random 0->1 or 1->0 transitions might be read by the digital circuit, for example: -``` - +-+ - | | - | | -+-----------------+ +-------------------- -``` - -Many debounce methods (but not all) will also make the device resistant to noise. If you are working with a technology that is -susceptible to noise, you must choose a debounce method that will also mitigate noise for you. - -## Types of debounce algorithms - -1) Unit of time: Timestamp (milliseconds) vs Cycles (scans) - * Debounce algorithms often have a 'debounce time' parameter, that specifies the maximum settling time of the switch contacts. - This time might be measured in various units: - * Cycles-based debouncing waits n cycles (scans), decreasing count by one each matrix_scan - * Timestamp-based debouncing stores the millisecond timestamp a change occurred, and does substraction to figure out time elapsed. - * Timestamp-based debouncing is usually superior, especially in the case of noise-resistant devices because settling times of physical - switches is specified in units of time, and should not depend on the matrix scan-rate of the keyboard. - * Cycles-based debouncing is sometimes considered inferior, because the settling time that it is able to compensate for depends on the - performance of the matrix scanning code. If you use cycles-based debouncing, and you significantly improve the performance of your scanning - code, you might end up with less effective debouncing. A situation in which cycles-based debouncing might be preferable is when - noise is present, and the scanning algorithm is slow, or variable speed. Even if your debounce algorithm is fundamentally noise-resistant, - if the scanning is slow, and you are using a timestamp-based algorithm, you might end up making a debouncing decision based on only two - sampled values, which will limit the noise-resistance of the algorithm. - * Currently all built-in debounce algorithms support timestamp-based debouncing only. In the future we might - implement cycles-based debouncing, and it will be selectable via a `config.h` macro. - -2) Symmetric vs Asymmetric - * Symmetric - apply the same debouncing algorithm, to both key-up and key-down events. - * Recommended naming convention: `sym_*` - * Asymmetric - apply different debouncing algorithms to key-down and key-up events. E.g. Eager key-down, Defer key-up. - * Recommended naming convention: `asym_*` followed by details of the type of algorithm in use, in order, for key-down and then key-up - -3) Eager vs Defer - * Eager - any key change is reported immediately. All further inputs for DEBOUNCE ms are ignored. - * Eager algorithms are not noise-resistant. - * Recommended naming conventions: - * `sym_eager_*` - * `asym_eager_*_*`: key-down is using eager algorithm - * `asym_*_eager_*`: key-up is using eager algorithm - * Defer - wait for no changes for DEBOUNCE ms before reporting change. - * Defer algorithms are noise-resistant - * Recommended naming conventions: - * `sym_defer_*` - * `asym_defer_*_*`: key-down is using defer algorithm - * `asym_*_defer_*`: key-up is using defer algorithm - -4) Global vs Per-Key vs Per-Row - * Global - one timer for all keys. Any key change state affects global timer - * Recommended naming convention: `*_g` - * Per-key - one timer per key - * Recommended naming convention: `*_pk` - * Per-row - one timer per row - * Recommended naming convention: `*_pr` - * Per-key and per-row algorithms consume more resources (in terms of performance, - and ram usage), but fast typists might prefer them over global. - -## Supported Debounce Algorithms - -QMK supports multiple algorithms through its debounce API. - -### Debounce Time - -Default debounce time is 5 milliseconds and it can be changed with the following line in `config.h`: -``` -#define DEBOUNCE 10 -``` -?> Setting `DEBOUNCE` to `0` will disable this feature. - -### Debounce Method - -Keyboards may select one of the core debounce methods by adding the following line into `rules.mk`: -``` -DEBOUNCE_TYPE = -``` -Name of algorithm is one of: - -| Algorithm | Description | -| --------------------- | ----------- | -| `sym_defer_g` | Debouncing per keyboard. On any state change, a global timer is set. When `DEBOUNCE` milliseconds of no changes has occurred, all input changes are pushed. This is the highest performance algorithm with lowest memory usage and is noise-resistant. | -| `sym_defer_pr` | Debouncing per row. On any state change, a per-row timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that row, the entire row is pushed. This can improve responsiveness over `sym_defer_g` while being less susceptible to noise than per-key algorithm. | -| `sym_defer_pk` | Debouncing per key. On any state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key status change is pushed. | -| `sym_eager_pr` | Debouncing per row. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that row. | -| `sym_eager_pk` | Debouncing per key. On any state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. | -| `asym_eager_defer_pk` | Debouncing per key. On a key-down state change, response is immediate, followed by `DEBOUNCE` milliseconds of no further input for that key. On a key-up state change, a per-key timer is set. When `DEBOUNCE` milliseconds of no changes have occurred on that key, the key-up status change is pushed. | - -?> `sym_defer_g` is the default if `DEBOUNCE_TYPE` is undefined. - -?> `sym_eager_pr` is suitable for use in keyboards where refreshing `NUM_KEYS` 8-bit counters is computationally expensive or has low scan rate while fingers usually hit one row at a time. This could be appropriate for the ErgoDox models where the matrix is rotated 90°. Hence its "rows" are really columns and each finger only hits a single "row" at a time with normal usage. - -### Implementing your own debouncing code - -You have the option to implement you own debouncing algorithm with the following steps: - -* Set `DEBOUNCE_TYPE = custom` in `rules.mk`. -* Add `SRC += debounce.c` in `rules.mk` -* Implement your own `debounce.c`. See `quantum/debounce` for examples. -* Debouncing occurs after every raw matrix scan. -* Use num_rows instead of MATRIX_ROWS to support split keyboards correctly. -* If your custom algorithm is applicable to other keyboards, please consider making a pull request. diff --git a/docs/feature_digitizer.md b/docs/feature_digitizer.md deleted file mode 100644 index 2e9e37cd5f24..000000000000 --- a/docs/feature_digitizer.md +++ /dev/null @@ -1,117 +0,0 @@ -# Digitizer :id=digitizer - -Digitizers allow the mouse cursor to be placed at absolute coordinates, unlike the [Pointing Device](feature_pointing_device.md) feature which applies relative displacements. - -This feature implements a stylus device with a tip switch and barrel switch (generally equivalent to the primary and secondary mouse buttons respectively). Tip pressure is not currently implemented. - -## Usage :id=usage - -Add the following to your `rules.mk`: - -```make -DIGITIZER_ENABLE = yes -``` - -## Positioning :id=positioning - -The X and Y coordinates are normalized, meaning their value must be set between 0 and 1. For the X component, the value `0` is the leftmost position, whereas the value `1` is the rightmost position. Similarly for the Y component, `0` is at the top and `1` at the bottom. - -?> Since there is no display attached, the OS will likely map these coordinates to the virtual desktop. This may be important to know if you have multiple monitors. - -## Examples :id=examples - -This example simply places the cursor in the middle of the screen: - -```c -digitizer_in_range_on(); -digitizer_set_position(0.5, 0.5); -``` - -The "in range" indicator is required to be on for the change in coordinates to be taken. It can then be turned off again to signal the end of the digitizer interaction, but it is not strictly required. - -You can also modify the digitizer state directly, if you need to change multiple fields in a single report: - -```c -digitizer_state.in_range = true; -digitizer_state.dirty = true; -digitizer_flush(); -``` - -`digitizer_state` is a struct of type `digitizer_t`. - - -## API :id=api - -### `struct digitizer_t` :id=api-digitizer-t - -Contains the state of the digitizer. - -#### Members :id=api-digitizer-t-members - - - `bool in_range` - Indicates to the host that the contact is within range (ie. close to or in contact with the digitizer surface). - - `bool tip` - The state of the tip switch. - - `bool barrel` - The state of the barrel switch. - - `float x` - The X coordinate of the digitizer contact. - - `float y` - The Y coordinate of the digitizer contact. - - `bool dirty` - Whether the current state needs to be sent to the host. - ---- - -### `void digitizer_flush(void)` :id=api-digitizer-flush - -Send the digitizer report to the host if it is marked as dirty. - ---- - -### `void digitizer_in_range_on(void)` :api-digitizer-in-range-on - -Assert the "in range" indicator, and flush the report. - ---- - -### `void digitizer_in_range_off(void)` :api-digitizer-in-range-off - -Deassert the "in range" indicator, and flush the report. - ---- - -### `void digitizer_tip_switch_on(void)` :api-digitizer-tip-switch-on - -Assert the tip switch, and flush the report. - ---- - -### `void digitizer_tip_switch_off(void)` :api-digitizer-tip-switch-off - -Deassert the tip switch, and flush the report. - ---- - -### `void digitizer_barrel_switch_on(void)` :api-digitizer-barrel-switch-on - -Assert the barrel switch, and flush the report. - ---- - -### `void digitizer_barrel_switch_off(void)` :api-digitizer-barrel-switch-off - -Deassert the barrel switch, and flush the report. - ---- - -### `void digitizer_set_position(float x, float y)` :api-digitizer-set-position - -Set the absolute X and Y position of the digitizer contact, and flush the report. - -#### Arguments :id=api-digitizer-set-position-arguments - - - `float x` - The X value of the contact position, from 0 to 1. - - `float y` - The Y value of the contact position, from 0 to 1. diff --git a/docs/feature_dip_switch.md b/docs/feature_dip_switch.md deleted file mode 100644 index 6fbe91657d50..000000000000 --- a/docs/feature_dip_switch.md +++ /dev/null @@ -1,109 +0,0 @@ -# DIP Switches - -DIP switches are supported by adding this to your `rules.mk`: - - DIP_SWITCH_ENABLE = yes - -and this to your `config.h`: - -```c -// Connects each switch in the dip switch to the GPIO pin of the MCU -#define DIP_SWITCH_PINS { B14, A15, A10, B9 } -// For split keyboards, you can separately define the right side pins -#define DIP_SWITCH_PINS_RIGHT { ... } -``` - -or - -```c -// Connect each switch in the DIP switch to an unused intersections in the key matrix. -#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs -``` - -## Callbacks - -The callback functions can be inserted into your `.c`: - -```c -bool dip_switch_update_kb(uint8_t index, bool active) { - if (!dip_switch_update_user(index, active)) { return false; } - return true; -} -``` - - -or `keymap.c`: - -```c -bool dip_switch_update_user(uint8_t index, bool active) { - switch (index) { - case 0: - if(active) { audio_on(); } else { audio_off(); } - break; - case 1: - if(active) { clicky_on(); } else { clicky_off(); } - break; - case 2: - if(active) { music_on(); } else { music_off(); } - break; - case 3: - if (active) { - #ifdef AUDIO_ENABLE - PLAY_SONG(plover_song); - #endif - layer_on(_PLOVER); - } else { - #ifdef AUDIO_ENABLE - PLAY_SONG(plover_gb_song); - #endif - layer_off(_PLOVER); - } - break; - } - return true; -} -``` - -Additionally, we support bit mask functions which allow for more complex handling. - - -```c -bool dip_switch_update_mask_kb(uint32_t state) { - if (!dip_switch_update_mask_user(state)) { return false; } - return true; -} -``` - - -or `keymap.c`: - -```c -bool dip_switch_update_mask_user(uint32_t state) { - if (state & (1UL<<0) && state & (1UL<<1)) { - layer_on(_ADJUST); // C on esc - } else { - layer_off(_ADJUST); - } - if (state & (1UL<<0)) { - layer_on(_TEST_A); // A on ESC - } else { - layer_off(_TEST_A); - } - if (state & (1UL<<1)) { - layer_on(_TEST_B); // B on esc - } else { - layer_off(_TEST_B); - } - return true; -} -``` - -## Hardware - -### Connects each switch in the dip switch to the GPIO pin of the MCU - -One side of the DIP switch should be wired directly to the pin on the MCU, and the other side to ground. It should not matter which side is connected to which, as it should be functionally the same. - -### Connect each switch in the DIP switch to an unused intersections in the key matrix. - -As with the keyswitch, a diode and DIP switch connect the ROW line to the COL line. diff --git a/docs/feature_dynamic_macros.md b/docs/feature_dynamic_macros.md deleted file mode 100644 index 8ab1bad61c83..000000000000 --- a/docs/feature_dynamic_macros.md +++ /dev/null @@ -1,67 +0,0 @@ -# Dynamic Macros: Record and Replay Macros in Runtime - -QMK supports temporary macros created on the fly. We call these Dynamic Macros. They are defined by the user from the keyboard and are lost when the keyboard is unplugged or otherwise rebooted. - -You can store one or two macros and they may have a combined total of 128 keypresses. You can increase this size at the cost of RAM. - -To enable them, first include `DYNAMIC_MACRO_ENABLE = yes` in your `rules.mk`. Then, add the following keys to your keymap: - -|Key |Alias |Description | -|---------------------------------|---------|--------------------------------------------------| -|`QK_DYNAMIC_MACRO_RECORD_START_1`|`DM_REC1`|Start recording Macro 1 | -|`QK_DYNAMIC_MACRO_RECORD_START_2`|`DM_REC2`|Start recording Macro 2 | -|`QK_DYNAMIC_MACRO_PLAY_1` |`DM_PLY1`|Replay Macro 1 | -|`QK_DYNAMIC_MACRO_PLAY_2` |`DM_PLY2`|Replay Macro 2 | -|`QK_DYNAMIC_MACRO_RECORD_STOP` |`DM_RSTP`|Finish the macro that is currently being recorded.| - -That should be everything necessary. - -To start recording the macro, press either `DM_REC1` or `DM_REC2`. - -To finish the recording, press the `DM_RSTP` layer button. You can also press `DM_REC1` or `DM_REC2` again to stop the recording. - -To replay the macro, press either `DM_PLY1` or `DM_PLY2`. - -It is possible to replay a macro as part of a macro. It's ok to replay macro 2 while recording macro 1 and vice versa but never create recursive macros i.e. macro 1 that replays macro 1. If you do so and the keyboard will get unresponsive, unplug the keyboard and plug it again. You can disable this completely by defining `DYNAMIC_MACRO_NO_NESTING` in your `config.h` file. - -?> For the details about the internals of the dynamic macros, please read the comments in the `process_dynamic_macro.h` and `process_dynamic_macro.c` files. - -## Customization - -There are a number of options added that should allow some additional degree of customization - -|Define |Default |Description | -|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| -|`DYNAMIC_MACRO_SIZE` |128 |Sets the amount of memory that Dynamic Macros can use. This is a limited resource, dependent on the controller. | -|`DYNAMIC_MACRO_USER_CALL` |*Not defined* |Defining this falls back to using the user `keymap.c` file to trigger the macro behavior. | -|`DYNAMIC_MACRO_NO_NESTING` |*Not Defined* |Defining this disables the ability to call a macro from another macro (nested macros). | -|`DYNAMIC_MACRO_DELAY` |*Not Defined* |Sets the waiting time (ms unit) when sending each key. | - - -If the LEDs start blinking during the recording with each keypress, it means there is no more space for the macro in the macro buffer. To fit the macro in, either make the other macro shorter (they share the same buffer) or increase the buffer size by adding the `DYNAMIC_MACRO_SIZE` define in your `config.h` (default value: 128; please read the comments for it in the header). - - -### DYNAMIC_MACRO_USER_CALL - -For users of the earlier versions of dynamic macros: It is still possible to finish the macro recording using just the layer modifier used to access the dynamic macro keys, without a dedicated `DM_RSTP` key. If you want this behavior back, add `#define DYNAMIC_MACRO_USER_CALL` to your `config.h` and insert the following snippet at the beginning of your `process_record_user()` function: - -```c - uint16_t macro_kc = (keycode == MO(_DYN) ? DM_RSTP : keycode); - - if (!process_record_dynamic_macro(macro_kc, record)) { - return false; - } -``` - -### User Hooks - -There are a number of hooks that you can use to add custom functionality and feedback options to Dynamic Macro feature. This allows for some additional degree of customization. - -Note, that direction indicates which macro it is, with `1` being Macro 1, `-1` being Macro 2, and 0 being no macro. - -* `dynamic_macro_record_start_user(int8_t direction)` - Triggered when you start recording a macro. -* `dynamic_macro_play_user(int8_t direction)` - Triggered when you play back a macro. -* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - Triggered on each keypress while recording a macro. -* `dynamic_macro_record_end_user(int8_t direction)` - Triggered when the macro recording is stopped. - -Additionally, you can call `dynamic_macro_led_blink()` to flash the backlights if that feature is enabled. diff --git a/docs/feature_eeprom.md b/docs/feature_eeprom.md deleted file mode 100644 index 088f4f36fff0..000000000000 --- a/docs/feature_eeprom.md +++ /dev/null @@ -1,134 +0,0 @@ -# Persistent Configuration (EEPROM) - -This allows you to configure persistent settings for your keyboard. These settings are stored in the EEPROM of your controller, and are retained even after power loss. The settings can be read with `eeconfig_read_kb` and `eeconfig_read_user`, and can be written to using `eeconfig_update_kb` and `eeconfig_update_user`. This is useful for features that you want to be able to toggle (like toggling rgb layer indication). Additionally, you can use `eeconfig_init_kb` and `eeconfig_init_user` to set the default values for the EEPROM. - -The complicated part here, is that there are a bunch of ways that you can store and access data via EEPROM, and there is no "correct" way to do this. However, you only have a DWORD (4 bytes) for each function. - -Keep in mind that EEPROM has a limited number of writes. While this is very high, it's not the only thing writing to the EEPROM, and if you write too often, you can potentially drastically shorten the life of your MCU. - -* If you don't understand the example, then you may want to avoid using this feature, as it is rather complicated. - -## Example Implementation - -This is an example of how to add settings, and read and write it. We're using the user keymap for the example here. This is a complex function, and has a lot going on. In fact, it uses a lot of the above functions to work! - - -In your keymap.c file, add this to the top: -```c -typedef union { - uint32_t raw; - struct { - bool rgb_layer_change :1; - }; -} user_config_t; - -user_config_t user_config; -``` - -This sets up a 32 bit structure that we can store settings with in memory, and write to the EEPROM. Using this removes the need to define variables, since they're defined in this structure. Remember that `bool` (boolean) values use 1 bit, `uint8_t` uses 8 bits, `uint16_t` uses up 16 bits. You can mix and match, but changing the order can cause issues, as it will change the values that are read and written. - -We're using `rgb_layer_change`, for the `layer_state_set_*` function, and use `keyboard_post_init_user` and `process_record_user` to configure everything. - -Now, using the `keyboard_post_init_user` code above, you want to add `eeconfig_read_user()` to it, to populate the structure you've just created. And you can then immediately use this structure to control functionality in your keymap. And It should look like: -```c -void keyboard_post_init_user(void) { - // Call the keymap level matrix init. - - // Read the user config from EEPROM - user_config.raw = eeconfig_read_user(); - - // Set default layer, if enabled - if (user_config.rgb_layer_change) { - rgblight_enable_noeeprom(); - rgblight_sethsv_noeeprom(HSV_CYAN); - rgblight_mode_noeeprom(1); - } -} -``` -The above function will use the EEPROM config immediately after reading it, to set the default layer's RGB color. The "raw" value of it is converted in a usable structure based on the "union" that you created above. - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom(HSV_MAGENTA); rgblight_mode_noeeprom(1); } - break; - case _LOWER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom(HSV_RED); rgblight_mode_noeeprom(1); } - break; - case _PLOVER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom(HSV_GREEN); rgblight_mode_noeeprom(1); } - break; - case _ADJUST: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom(HSV_WHITE); rgblight_mode_noeeprom(1); } - break; - default: // for any other layers, or the default layer - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom(HSV_CYAN); rgblight_mode_noeeprom(1); } - break; - } - return state; -} -``` -This will cause the RGB underglow to be changed ONLY if the value was enabled. Now to configure this value, create a new keycode for `process_record_user` called `RGB_LYR`. Additionally, we want to make sure that if you use the normal RGB codes, that it turns off Using the example above, make it look this: -```c - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // Do something when pressed - } else { - // Do something else when release - } - return false; // Skip all further processing of this key - case KC_ENTER: - // Play a tone when enter is pressed - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // Let QMK send the enter press/release events - case RGB_LYR: // This allows me to use underglow as layer indication, or as normal - if (record->event.pressed) { - user_config.rgb_layer_change ^= 1; // Toggles the status - eeconfig_update_user(user_config.raw); // Writes the new status to EEPROM - if (user_config.rgb_layer_change) { // if layer state indication is enabled, - layer_state_set(layer_state); // then immediately update the layer color - } - } - return false; - case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // For any of the RGB codes (see quantum_keycodes.h, L400 for reference) - if (record->event.pressed) { //This disables layer indication, as it's assumed that if you're changing this ... you want that disabled - if (user_config.rgb_layer_change) { // only if this is enabled - user_config.rgb_layer_change = false; // disable it, and - eeconfig_update_user(user_config.raw); // write the setings to EEPROM - } - } - return true; break; - default: - return true; // Process all other keycodes normally - } -} -``` -And lastly, you want to add the `eeconfig_init_user` function, so that when the EEPROM is reset, you can specify default values, and even custom actions. To force an EEPROM reset, use the `EE_CLR` keycode or [Bootmagic Lite](feature_bootmagic.md) functionallity. For example, if you want to set rgb layer indication by default, and save the default valued. - -```c -void eeconfig_init_user(void) { // EEPROM is getting reset! - user_config.raw = 0; - user_config.rgb_layer_change = true; // We want this enabled by default - eeconfig_update_user(user_config.raw); // Write default value to EEPROM now - - // use the non noeeprom versions, to write these values to EEPROM too - rgblight_enable(); // Enable RGB by default - rgblight_sethsv(HSV_CYAN); // Set it to CYAN by default - rgblight_mode(1); // set to solid by default -} -``` - -And you're done. The RGB layer indication will only work if you want it to. And it will be saved, even after unplugging the board. And if you use any of the RGB codes, it will disable the layer indication, so that it stays on the mode and color that you set it to. - -## 'EECONFIG' Function Documentation - -* Keyboard/Revision: `void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` and `void eeconfig_update_kb(uint32_t val)` -* Keymap: `void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` and `void eeconfig_update_user(uint32_t val)` - -The `val` is the value of the data that you want to write to EEPROM. And the `eeconfig_read_*` function return a 32 bit (DWORD) value from the EEPROM. diff --git a/docs/feature_encoders.md b/docs/feature_encoders.md deleted file mode 100644 index 891baeefa1d0..000000000000 --- a/docs/feature_encoders.md +++ /dev/null @@ -1,176 +0,0 @@ -# Encoders - -Basic (EC11 compatible) encoders are supported by adding this to your `rules.mk`: - -```make -ENCODER_ENABLE = yes -``` - -and this to your `config.h`: - -```c -#define ENCODERS_PAD_A { B12 } -#define ENCODERS_PAD_B { B13 } -``` - -Each PAD_A/B variable defines an array so multiple encoders can be defined, e.g.: - -```c -#define ENCODERS_PAD_A { encoder1a, encoder2a } -#define ENCODERS_PAD_B { encoder1b, encoder2b } -``` - -If your encoder's clockwise directions are incorrect, you can swap the A & B pad definitions. They can also be flipped with a define: - -```c -#define ENCODER_DIRECTION_FLIP -``` - -Additionally, the resolution, which defines how many pulses the encoder registers between each detent, can be defined with: - -```c -#define ENCODER_RESOLUTION 4 -``` - -It can also be defined per-encoder, by instead defining: - -```c -#define ENCODER_RESOLUTIONS { 4, 2 } -``` - -For 4× encoders you also can assign default position if encoder skips pulses when it changes direction. For example, if your encoder send high level on both pins by default, define this: - -```c -#define ENCODER_DEFAULT_POS 0x3 -``` - -## Split Keyboards - -If you are using different pinouts for the encoders on each half of a split keyboard, you can define the pinout (and optionally, resolutions) for the right half like this: - -```c -#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } -#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } -#define ENCODER_RESOLUTIONS_RIGHT { 2, 4 } -``` - -If the `_RIGHT` definitions aren't specified in your `config.h`, then the non-`_RIGHT` versions will be applied to both sides of the split. - -Additionally, if one side does not have an encoder, you can specify `{}` for the pins/resolution -- for example, a split keyboard with only a right-side encoder: - -```c -#define ENCODERS_PAD_A { } -#define ENCODERS_PAD_B { } -#define ENCODER_RESOLUTIONS { } -#define ENCODERS_PAD_A_RIGHT { B12 } -#define ENCODERS_PAD_B_RIGHT { B13 } -#define ENCODER_RESOLUTIONS_RIGHT { 4 } -``` - -!> Keep in mind that whenver you change the encoder resolution, you will need to reflash the half that has the encoder affected by the change. - -## Encoder map :id=encoder-map - -Encoder mapping may be added to your `keymap.c`, which replicates the normal keyswitch layer handling functionality, but with encoders. Add this to your keymap's `rules.mk`: - -```make -ENCODER_MAP_ENABLE = yes -``` - -Your `keymap.c` will then need an encoder mapping defined (for four layers and two encoders): - -```c -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_BASE] = { ENCODER_CCW_CW(KC_MS_WH_UP, KC_MS_WH_DOWN), ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_LOWER] = { ENCODER_CCW_CW(RGB_HUD, RGB_HUI), ENCODER_CCW_CW(RGB_SAD, RGB_SAI) }, - [_RAISE] = { ENCODER_CCW_CW(RGB_VAD, RGB_VAI), ENCODER_CCW_CW(RGB_SPD, RGB_SPI) }, - [_ADJUST] = { ENCODER_CCW_CW(RGB_RMOD, RGB_MOD), ENCODER_CCW_CW(KC_RIGHT, KC_LEFT) }, -}; -#endif -``` - -?> This should only be enabled at the keymap level. - -Using encoder mapping pumps events through the normal QMK keycode processing pipeline, resulting in a _keydown/keyup_ combination pushed through `process_record_xxxxx()`. To configure the amount of time between the encoder "keyup" and "keydown", you can add the following to your `config.h`: - -```c -#define ENCODER_MAP_KEY_DELAY 10 -``` - -?> By default, the encoder map delay matches the value of `TAP_CODE_DELAY`. - -## Callbacks - -?> [**Default Behaviour**](https://github.com/qmk/qmk_firmware/blob/master/quantum/encoder.c#L79-#L98): all encoders installed will function as volume up (`KC_VOLU`) on clockwise rotation and volume down (`KC_VOLD`) on counter-clockwise rotation. If you do not wish to override this, no further configuration is necessary. - -If you would like the alter the default behaviour, and are not using `ENCODER_MAP_ENABLE = yes`, the callback functions can be inserted into your `.c`: - -```c -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!encoder_update_user(index, clockwise)) { - return false; /* Don't process further events if user function exists and returns false */ - } - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } else if (index == 1) { /* Second encoder */ - if (clockwise) { - rgb_matrix_increase_hue(); - } else { - rgb_matrix_decrease_hue(); - } - } - return true; -} -``` - -or `keymap.c`: - -```c -bool encoder_update_user(uint8_t index, bool clockwise) { - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } else if (index == 1) { /* Second encoder */ - if (clockwise) { - rgb_matrix_increase_hue(); - } else { - rgb_matrix_decrease_hue(); - } - } - return false; -} -``` - -!> If you return `true` in the keymap level `_user` function, it will allow the keyboard/core level encoder code to run on top of your own. Returning `false` will override the keyboard level function, if setup correctly. This is generally the safest option to avoid confusion. - -## Hardware - -The A an B lines of the encoders should be wired directly to the MCU, and the C/common lines should be wired to ground. - -## Multiple Encoders - -Multiple encoders may share pins so long as each encoder has a distinct pair of pins when the following conditions are met: -- using detent encoders -- pads must be high at the detent stability point which is called 'default position' in QMK -- no more than two encoders sharing a pin can be turned at the same time - -For example you can support two encoders using only 3 pins like this -``` -#define ENCODERS_PAD_A { B1, B1 } -#define ENCODERS_PAD_B { B2, B3 } -``` - -You could even support three encoders using only three pins (one per encoder) however in this configuration, rotating two encoders which share pins simultaneously will often generate incorrect output. For example: -``` -#define ENCODERS_PAD_A { B1, B1, B2 } -#define ENCODERS_PAD_B { B2, B3, B3 } -``` -Here rotating Encoder 0 `B1 B2` and Encoder 1 `B1 B3` could be interpreted as rotating Encoder 2 `B2 B3` or `B3 B2` depending on the timing. This may still be a useful configuration depending on your use case diff --git a/docs/feature_grave_esc.md b/docs/feature_grave_esc.md deleted file mode 100644 index 09d098ee4e93..000000000000 --- a/docs/feature_grave_esc.md +++ /dev/null @@ -1,32 +0,0 @@ -# Grave Escape - -If you're using a 60% keyboard, or any other layout with no F-row, you will have noticed that there is no dedicated Escape key. Grave Escape is a feature that allows you to share the grave key (` and `~`) with Escape. - -## Usage - -Replace the `KC_GRV` key in your keymap (usually to the left of the `1` key) with `QK_GESC`. Most of the time this key will output `KC_ESC` when pressed. However, when Shift or GUI are held down it will output `KC_GRV` instead. - -## What Your OS Sees - -If Mary presses `QK_GESC` on her keyboard, the OS will see an KC_ESC character. Now if Mary holds Shift down and presses `QK_GESC` it will output `~`, or a shifted backtick. Now if she holds GUI/CMD/WIN, it will output a simple ` character. - -## Keycodes - -|Key |Aliases |Description | -|-----------------|---------|------------------------------------------------------------------| -|`QK_GRAVE_ESCAPE`|`QK_GESC`|Escape when pressed, ` when Shift or GUI are held| - -### Caveats - -On macOS, Command+` is by default mapped to "Move focus to next window" so it will not output a backtick. Additionally, Terminal always recognises this shortcut to cycle between windows, even if the shortcut is changed in the Keyboard preferences. - -## Configuration - -There are several possible key combinations this will break, among them Control+Shift+Escape on Windows and Command+Option+Escape on macOS. To work around this, you can `#define` these options in your `config.h`: - -|Define |Description | -|--------------------------|-----------------------------------------| -|`GRAVE_ESC_ALT_OVERRIDE` |Always send Escape if Alt is pressed | -|`GRAVE_ESC_CTRL_OVERRIDE` |Always send Escape if Control is pressed | -|`GRAVE_ESC_GUI_OVERRIDE` |Always send Escape if GUI is pressed | -|`GRAVE_ESC_SHIFT_OVERRIDE`|Always send Escape if Shift is pressed | diff --git a/docs/feature_haptic_feedback.md b/docs/feature_haptic_feedback.md deleted file mode 100644 index b456bad736f8..000000000000 --- a/docs/feature_haptic_feedback.md +++ /dev/null @@ -1,213 +0,0 @@ -# Haptic Feedback - -## Haptic feedback rules.mk options - -The following options are currently available for haptic feedback in `rules.mk`: - -``` -HAPTIC_ENABLE = yes - -HAPTIC_DRIVER += DRV2605L -HAPTIC_DRIVER += SOLENOID -``` - -The following `config.h` settings are available for all types of haptic feedback: - -| Settings | Default | Description | -|--------------------------------------|---------------|---------------------------------------------------------------------------------------------------------------| -|`HAPTIC_ENABLE_PIN` | *Not defined* |Configures a pin to enable a boost converter for some haptic solution, often used with solenoid drivers. | -|`HAPTIC_ENABLE_PIN_ACTIVE_LOW` | *Not defined* |If defined then the haptic enable pin is active-low. | -|`HAPTIC_ENABLE_STATUS_LED` | *Not defined* |Configures a pin to reflect the current enabled/disabled status of haptic feedback. | -|`HAPTIC_ENABLE_STATUS_LED_ACTIVE_LOW` | *Not defined* |If defined then the haptic status led will be active-low. | -|`HAPTIC_OFF_IN_LOW_POWER` | `0` |If set to `1`, haptic feedback is disabled before the device is configured, and while the device is suspended. | - -## Known Supported Hardware - -| Name | Description | -|--------------------|-------------------------------------------------| -| [LV061228B-L65-A](https://www.digikey.com/product-detail/en/jinlong-machinery-electronics-inc/LV061228B-L65-A/1670-1050-ND/7732325) | z-axis 2v LRA | -| [Mini Motor Disc](https://www.adafruit.com/product/1201) | small 2-5v ERM | - -## Haptic Keycodes - -Not all keycodes below will work depending on which haptic mechanism you have chosen. - -| Key | Aliases | Description | -|-----------------------------|---------|-------------------------------------------------------| -|`QK_HAPTIC_ON` |`HF_ON` | Turn haptic feedback on | -|`QK_HAPTIC_OFF` |`HF_OFF` | Turn haptic feedback off | -|`QK_HAPTIC_TOGGLE` |`HF_TOGG`| Toggle haptic feedback on/off | -|`QK_HAPTIC_RESET` |`HF_RST` | Reset haptic feedback config to default | -|`QK_HAPTIC_FEEDBACK_TOGGLE` |`HF_FDBK`| Toggle feedback to occur on keypress, release or both | -|`QK_HAPTIC_BUZZ_TOGGLE` |`HF_BUZZ`| Toggle solenoid buzz on/off | -|`QK_HAPTIC_MODE_NEXT` |`HF_NEXT`| Go to next DRV2605L waveform | -|`QK_HAPTIC_MODE_PREVIOUS` |`HF_PREV`| Go to previous DRV2605L waveform | -|`QK_HAPTIC_CONTINUOUS_TOGGLE`|`HF_CONT`| Toggle continuous haptic mode on/off | -|`QK_HAPTIC_CONTINUOUS_UP` |`HF_CONU`| Increase DRV2605L continous haptic strength | -|`QK_HAPTIC_CONTINUOUS_DOWN` |`HF_COND`| Decrease DRV2605L continous haptic strength | -|`QK_HAPTIC_DWELL_UP` |`HF_DWLU`| Increase Solenoid dwell time | -|`QK_HAPTIC_DWELL_DOWN` |`HF_DWLD`| Decrease Solenoid dwell time | - -### Solenoids - -The solenoid code supports relay switches, and similar hardware, as well as solenoids. - -For a regular solenoid, you will need a build a circuit to drive the solenoid through a mosfet as most MCU will not be able to provide the current needed to drive the coil in the solenoid. - -[Wiring diagram provided by Adafruit](https://cdn-shop.adafruit.com/product-files/412/solenoid_driver.pdf) - -For relay switches, the hardware may already contain all of that ciruitry, and just require VCC, GND and a data pin. - -| Settings | Default | Description | -|----------------------------|----------------------|--------------------------------------------------------------| -|`SOLENOID_PIN` | *Not defined* |Configures the pin that the switch is connected to. | -|`SOLENOID_PIN_ACTIVE_LOW` | *Not defined* |If defined then the switch trigger pin is active low. | -|`SOLENOID_PINS` | *Not defined* |Configures an array of pins to be used for switch activation. | -|`SOLENOID_PINS_ACTIVE_LOW` | *Not defined* |Allows you to specify how each pin is pulled for activation. | -|`SOLENOID_RANDOM_FIRE` | *Not defined* |When there are multiple solenoids, will select a random one to fire.| -|`SOLENOID_DEFAULT_DWELL` | `12` ms |Configures the default dwell time for the switch. | -|`SOLENOID_MIN_DWELL` | `4` ms |Sets the lower limit for the dwell. | -|`SOLENOID_MAX_DWELL` | `100` ms |Sets the upper limit for the dwell. | -|`SOLENOID_DWELL_STEP_SIZE` | `1` ms |The step size to use when `HF_DWL*` keycodes are sent. | -|`SOLENOID_DEFAULT_BUZZ` | `0` (disabled) |On `HF_RST` buzz is set "on" if this is "1" | -|`SOLENOID_BUZZ_ACTUATED` | `SOLENOID_MIN_DWELL` |Actuated-time when the switch is in buzz mode. | -|`SOLENOID_BUZZ_NONACTUATED` | `SOLENOID_MIN_DWELL` |Non-Actuated-time when the switch is in buzz mode. | - -* If solenoid buzz is off, then dwell time is how long the "plunger" stays activated. The dwell time changes how the solenoid sounds. -* If solenoid buzz is on, then dwell time sets the length of the buzz, while `SOLENOID_BUZZ_ACTUATED` and `SOLENOID_BUZZ_NONACTUATED` set the (non-)actuation times withing the buzz period. -* With the current implementation, for any of the above time settings, the precision of these settings may be affected by how fast the keyboard is able to scan the matrix. - Therefore, if the keyboards scanning routine is slow, it may be preferable to set `SOLENOID_DWELL_STEP_SIZE` to a value slightly smaller than the time it takes to scan the keyboard. - -Beware that some pins may be powered during bootloader (ie. A13 on the STM32F303 chip) and will result in the solenoid kept in the on state through the whole flashing process. This may overheat and damage the solenoid. If you find that the pin the solenoid is connected to is triggering the solenoid during bootloader/DFU, select another pin. - -### DRV2605L - -DRV2605L is controlled over i2c protocol, and has to be connected to the SDA and SCL pins, these varies depending on the MCU in use. - -#### Feedback motor setup - -This driver supports 2 different feedback motors. Set the following in your `config.h` based on which motor you have selected. - -##### ERM - -Eccentric Rotating Mass vibration motors (ERM) is motor with a off-set weight attached so when drive signal is attached, the off-set weight spins and causes a sinusoidal wave that translate into vibrations. - -``` -#define FB_ERM_LRA 0 -#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ -#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ - -/* Please refer to your datasheet for the optimal setting for your specific motor. */ -#define RATED_VOLTAGE 3 -#define V_PEAK 5 -``` -##### LRA - -Linear resonant actuators (LRA, also know as a linear vibrator) works different from a ERM. A LRA has a weight and magnet suspended by springs and a voice coil. When the drive signal is applied, the weight would be vibrate on a single axis (side to side or up and down). Since the weight is attached to a spring, there is a resonance effect at a specific frequency. This frequency is where the LRA will operate the most efficiently. Refer to the motor's datasheet for the recommanded range for this frequency. - -``` -#define FB_ERM_LRA 1 -#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ -#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ - -/* Please refer to your datasheet for the optimal setting for your specific motor. */ -#define RATED_VOLTAGE 2 -#define V_PEAK 2.8 -#define V_RMS 2.0 -#define V_PEAK 2.1 -#define F_LRA 205 /* resonance freq */ -``` - -#### DRV2605L waveform library - -DRV2605L comes with preloaded library of various waveform sequences that can be called and played. If writing a macro, these waveforms can be played using `DRV_pulse(*sequence name or number*)` - -List of waveform sequences from the datasheet: - -|seq# | Sequence name |seq# | Sequence name |seq# |Sequence name | -|-----|---------------------|-----|-----------------------------------|-----|--------------------------------------| -| 1 | strong_click | 43 | lg_dblclick_med_60 | 85 | transition_rampup_med_smooth2 | -| 2 | strong_click_60 | 44 | lg_dblsharp_tick | 86 | transition_rampup_short_smooth1 | -| 3 | strong_click_30 | 45 | lg_dblsharp_tick_80 | 87 | transition_rampup_short_smooth2 | -| 4 | sharp_click | 46 | lg_dblsharp_tick_60 | 88 | transition_rampup_long_sharp1 | -| 5 | sharp_click_60 | 47 | buzz | 89 | transition_rampup_long_sharp2 | -| 6 | sharp_click_30 | 48 | buzz_80 | 90 | transition_rampup_med_sharp1 | -| 7 | soft_bump | 49 | buzz_60 | 91 | transition_rampup_med_sharp2 | -| 8 | soft_bump_60 | 50 | buzz_40 | 92 | transition_rampup_short_sharp1 | -| 9 | soft_bump_30 | 51 | buzz_20 | 93 | transition_rampup_short_sharp2 | -| 10 | dbl_click | 52 | pulsing_strong | 94 | transition_rampdown_long_smooth1_50 | -| 11 | dbl_click_60 | 53 | pulsing_strong_80 | 95 | transition_rampdown_long_smooth2_50 | -| 12 | trp_click | 54 | pulsing_medium | 96 | transition_rampdown_med_smooth1_50 | -| 13 | soft_fuzz | 55 | pulsing_medium_80 | 97 | transition_rampdown_med_smooth2_50 | -| 14 | strong_buzz | 56 | pulsing_sharp | 98 | transition_rampdown_short_smooth1_50 | -| 15 | alert_750ms | 57 | pulsing_sharp_80 | 99 | transition_rampdown_short_smooth2_50 | -| 16 | alert_1000ms | 58 | transition_click | 100 | transition_rampdown_long_sharp1_50 | -| 17 | strong_click1 | 59 | transition_click_80 | 101 | transition_rampdown_long_sharp2_50 | -| 18 | strong_click2_80 | 60 | transition_click_60 | 102 | transition_rampdown_med_sharp1_50 | -| 19 | strong_click3_60 | 61 | transition_click_40 | 103 | transition_rampdown_med_sharp2_50 | -| 20 | strong_click4_30 | 62 | transition_click_20 | 104 | transition_rampdown_short_sharp1_50 | -| 21 | medium_click1 | 63 | transition_click_10 | 105 | transition_rampdown_short_sharp2_50 | -| 22 | medium_click2_80 | 64 | transition_hum | 106 | transition_rampup_long_smooth1_50 | -| 23 | medium_click3_60 | 65 | transition_hum_80 | 107 | transition_rampup_long_smooth2_50 | -| 24 | sharp_tick1 | 66 | transition_hum_60 | 108 | transition_rampup_med_smooth1_50 | -| 25 | sharp_tick2_80 | 67 | transition_hum_40 | 109 | transition_rampup_med_smooth2_50 | -| 26 | sharp_tick3_60 | 68 | transition_hum_20 | 110 | transition_rampup_short_smooth1_50 | -| 27 | sh_dblclick_str | 69 | transition_hum_10 | 111 | transition_rampup_short_smooth2_50 | -| 28 | sh_dblclick_str_80 | 70 | transition_rampdown_long_smooth1 | 112 | transition_rampup_long_sharp1_50 | -| 29 | sh_dblclick_str_60 | 71 | transition_rampdown_long_smooth2 | 113 | transition_rampup_long_sharp2_50 | -| 30 | sh_dblclick_str_30 | 72 | transition_rampdown_med_smooth1 | 114 | transition_rampup_med_sharp1_50 | -| 31 | sh_dblclick_med | 73 | transition_rampdown_med_smooth2 | 115 | transition_rampup_med_sharp2_50 | -| 32 | sh_dblclick_med_80 | 74 | transition_rampdown_short_smooth1 | 116 | transition_rampup_short_sharp1_50 | -| 33 | sh_dblclick_med_60 | 75 | transition_rampdown_short_smooth2 | 117 | transition_rampup_short_sharp2_50 | -| 34 | sh_dblsharp_tick | 76 | transition_rampdown_long_sharp1 | 118 | long_buzz_for_programmatic_stopping | -| 35 | sh_dblsharp_tick_80 | 77 | transition_rampdown_long_sharp2 | 119 | smooth_hum1_50 | -| 36 | sh_dblsharp_tick_60 | 78 | transition_rampdown_med_sharp1 | 120 | smooth_hum2_40 | -| 37 | lg_dblclick_str | 79 | transition_rampdown_med_sharp2 | 121 | smooth_hum3_30 | -| 38 | lg_dblclick_str_80 | 80 | transition_rampdown_short_sharp1 | 122 | smooth_hum4_20 | -| 39 | lg_dblclick_str_60 | 81 | transition_rampdown_short_sharp2 | 123 | smooth_hum5_10 | -| 40 | lg_dblclick_str_30 | 82 | transition_rampup_long_smooth1 | | | -| 41 | lg_dblclick_med | 83 | transition_rampup_long_smooth2 | | | -| 42 | lg_dblclick_med_80 | 84 | transition_rampup_med_smooth1 | | | -### Optional DRV2605L defines - -``` -#define DRV_GREETING *sequence name or number* -``` -If haptic feedback is enabled, the keyboard will vibrate to a specific sequence during startup. That can be selected using the following define: - -``` -#define DRV_MODE_DEFAULT *sequence name or number* -``` -This will set what sequence `HF_RST` will set as the active mode. If not defined, mode will be set to 1 when `HF_RST` is pressed. - -### DRV2605L Continuous Haptic Mode - -This mode sets continuous haptic feedback with the option to increase or decrease strength. - -## Haptic Key Exclusion -The Haptic Exclusion is implemented as `__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record)` in haptic.c. This allows a re-definition at the required level with the specific requirement / exclusion. - -### NO_HAPTIC_MOD -With the entry of `#define NO_HAPTIC_MOD` in config.h, the following keys will not trigger feedback: - -* Usual modifier keys such as Control/Shift/Alt/Gui (For example `KC_LCTL`) -* `MO()` momentary keys. See also [Layers](feature_layers.md). -* `LM()` momentary keys with mod active. -* `LT()` layer tap keys, when held to activate a layer. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. -* `TT()` layer tap toggle keys, when held to activate a layer. However when tapped `TAPPING_TOGGLE` times to permanently toggle the layer, on the last tap haptic feedback is still triggered. -* `MT()` mod tap keys, when held to keep a usual modifier key pressed. However when tapped, and the key is quickly released, and sends a keycode, haptic feedback is still triggered. See also [Mod-Tap](mod_tap.md). - -### NO_HAPTIC_ALPHA -With the entry of `#define NO_HAPTIC_ALPHA` in config.h, none of the alpha keys (A ... Z) will trigger a feedback. - -### NO_HAPTIC_PUNCTUATION -With the entry of `#define NO_HAPTIC_PUNCTUATION` in config.h, none of the following keys will trigger a feedback: Enter, ESC, Backspace, Space, Minus, Equal, Left Bracket, Right Bracket, Backslash, Non-US Hash, Semicolon, Quote, Grave, Comma, Slash, Dot, Non-US Backslash. - -### NO_HAPTIC_LOCKKEYS -With the entry of `#define NO_HAPTIC_LOCKKEYS` in config.h, none of the following keys will trigger a feedback: Caps Lock, Scroll Lock, Num Lock. - -### NO_HAPTIC_NAV -With the entry of `#define NO_HAPTIC_NAV` in config.h, none of the following keys will trigger a feedback: Print Screen, Pause, Insert, Delete, Page Down, Page Up, Left Arrow, Up Arrow, Right Arrow, Down Arrow, End, Home. - -### NO_HAPTIC_NUMERIC -With the entry of `#define NO_HAPTIC_NUMERIC` in config.h, none of the following keys between 0 and 9 (KC_1 ... KC_0) will trigger a feedback. diff --git a/docs/feature_hd44780.md b/docs/feature_hd44780.md deleted file mode 100644 index 4ade640baae7..000000000000 --- a/docs/feature_hd44780.md +++ /dev/null @@ -1,298 +0,0 @@ -# HD44780 LCD Driver - -## Supported Hardware - -LCD modules using [HD44780U](https://www.sparkfun.com/datasheets/LCD/HD44780.pdf) IC or equivalent, communicating in 4-bit mode. - -|Module|Size |Notes | -|------|--------------|---------------------------------| -|1602A |16x2, 5x8 dots| | -|2004A |20x4, 5x8 dots|Untested, not currently supported| - -To run these modules at 3.3V, an additional MAX660 voltage converter IC must be soldered on, along with two 10µF capacitors. See [this page](https://www.codrey.com/electronic-circuits/hack-your-16x2-lcd/) for more details. - -## Usage - -Add the following to your `rules.mk`: - -```make -HD44780_ENABLE = yes -``` - -## Basic Configuration - -Add the following to your `config.h`: - -|Define |Default |Description | -|-----------------------|--------------|-----------------------------------------------------------------------------------------------------| -|`HD44780_DATA_PINS` |*Not defined* |(Required) An array of four GPIO pins connected to the display's D4-D7 pins, eg. `{ B1, B3, B2, B6 }`| -|`HD44780_RS_PIN` |*Not defined* |(Required) The GPIO connected to the display's RS pin | -|`HD44780_RW_PIN` |*Not defined* |(Required) The GPIO connected to the display's RW pin | -|`HD44780_E_PIN` |*Not defined* |(Required) The GPIO connected to the display's E pin | -|`HD44780_DISPLAY_COLS` |`16` |The number of visible characters on a single line of the display | -|`HD44780_DISPLAY_LINES`|`2` |The number of visible lines on the display | -|`HD44780_WRAP_LINES` |*Not defined* |If defined, input characters will wrap to the next line | - -## Examples - -### Hello World - -Add the following to your `keymap.c`: - -```c -void keyboard_post_init_user(void) { - hd44780_init(true, true); // Show blinking cursor - hd44780_puts_P(PSTR("Hello, world!\n")); -} -``` - -### Custom Character Definition - -Up to eight custom characters can be defined. This data is stored in the Character Generator RAM (CGRAM), and is not persistent across power cycles. - -This example defines the QMK Psi as the first custom character. The first 16 positions in the character set are reserved for the eight custom characters duplicated. - -``` -Byte | 16 8 4 2 1 - 1 | x x x ■ □ ■ □ ■ - 2 | x x x ■ □ ■ □ ■ - 3 | x x x ■ □ ■ □ ■ - 4 | x x x □ ■ ■ ■ □ - 5 | x x x □ □ ■ □ □ - 6 | x x x □ □ ■ □ □ - 7 | x x x □ □ ■ □ □ - 8 | x x x □ □ □ □ □ -``` - -```c -const uint8_t PROGMEM psi[8] = { 0x15, 0x15, 0x15, 0x0E, 0x04, 0x04, 0x04, 0x00 }; - -void keyboard_post_init_user(void) { - hd44780_init(false, false); - hd44780_define_char_P(0, psi); - // Cursor is incremented while defining characters so must be reset - hd44780_home(); - // 0x08 to avoid null terminator - hd44780_puts_P(PSTR("\x08 QMK Firmware")); -} -``` - -## API - -### `void hd44780_init(bool cursor, bool blink)` - -Initialize the display. - -This function should be called only once, before any of the other functions can be called. - -#### Arguments - - - `bool cursor` - Whether to show the cursor. - - `bool blink` - Whether to blink the cursor, if shown. - ---- - -### `void hd44780_clear(void)` - -Clear the display. - -This function is called on init. - ---- - -### `void hd44780_home(void)` - -Move the cursor to the home position. - -This function is called on init. - ---- - -### `void hd44780_on(bool cursor, bool blink)` - -Turn the display on, and/or set the cursor properties. - -This function is called on init. - -#### Arguments - - - `bool cursor` - Whether to show the cursor. - - `bool blink` - Whether to blink the cursor, if shown. - ---- - -### `void hd44780_off(void)` - -Turn the display off. - ---- - -### `void hd44780_set_cursor(uint8_t col, uint8_t line)` - -Move the cursor to the specified position on the display. - -#### Arguments - - - `uint8_t col` - The column number to move to, from 0 to 15 on 16x2 displays. - - `bool line` - The line number to move to, either 0 or 1 on 16x2 displays. - ---- - -### `void hd44780_putc(char c)` - -Print a character to the display. The newline character `\n` will move the cursor to the start of the next line. - -The exact character shown may depend on the ROM code of your particular display - refer to the datasheet for the full character set. - -#### Arguments - - - `char c` - The character to print. - ---- - -### `void hd44780_puts(const char *s)` - -Print a string of characters to the display. - -#### Arguments - - - `const char *s` - The string to print. - ---- - -### `void hd44780_puts_P(const char *s)` - -Print a string of characters from PROGMEM to the display. - -On ARM devices, this function is simply an alias of `hd44780_puts()`. - -#### Arguments - - - `const char *s` - The PROGMEM string to print (ie. `PSTR("Hello")`). - ---- - -### `void hd44780_define_char(uint8_t index, uint8_t *data)` - -Define a custom character. - -#### Arguments - - - `uint8_t index` - The index of the custom character to define, from 0 to 7. - - `uint8_t *data` - An array of 8 bytes containing the 5-bit row data of the character, where the first byte is the topmost row, and the least significant bit of each byte is the rightmost column. - ---- - -### `void hd44780_define_char_P(uint8_t index, const uint8_t *data)` - -Define a custom character from PROGMEM. - -On ARM devices, this function is simply an alias of `hd44780_define_char()`. - -#### Arguments - - - `uint8_t index` - The index of the custom character to define, from 0 to 7. - - `const uint8_t *data` - A PROGMEM array of 8 bytes containing the 5-bit row data of the character, where the first byte is the topmost row, and the least significant bit of each byte is the rightmost column. - ---- - -### `bool hd44780_busy(void)` - -Indicates whether the display is currently processing, and cannot accept instructions. - -#### Return Value - -`true` if the display is busy. - ---- - -### `void hd44780_write(uint8_t data, bool isData)` - -Write a byte to the display. - -#### Arguments - - - `uint8_t data` - The byte to send to the display. - - `bool isData` - Whether the byte is an instruction or character data. - ---- - -### `uint8_t hd44780_read(bool isData)` - -Read a byte from the display. - -#### Arguments - - - `bool isData` - Whether to read the current cursor position, or the character at the cursor. - -#### Return Value - -If `isData` is `true`, the returned byte will be the character at the current DDRAM address. Otherwise, it will be the current DDRAM address and the busy flag. - ---- - -### `void hd44780_command(uint8_t command)` - -Send a command to the display. Refer to the datasheet and `hd44780.h` for the valid commands and defines. - -This function waits for the display to clear the busy flag before sending the command. - -#### Arguments - - - `uint8_t command` - The command to send. - ---- - -### `void hd44780_data(uint8_t data)` - -Send a byte of data to the display. - -This function waits for the display to clear the busy flag before sending the data. - -#### Arguments - - - `uint8_t data` - The byte of data to send. - ---- - -### `void hd44780_set_cgram_address(uint8_t address)` - -Set the CGRAM address. - -This function is used when defining custom characters. - -#### Arguments - - - `uint8_t address` - The CGRAM address to move to, from `0x00` to `0x3F`. - ---- - -### `void hd44780_set_ddram_address(uint8_t address)` - -Set the DDRAM address. - -This function is used when printing characters to the display, and setting the cursor. - -#### Arguments - - - `uint8_t address` - The DDRAM address to move to, from `0x00` to `0x7F`. diff --git a/docs/feature_joystick.md b/docs/feature_joystick.md deleted file mode 100644 index 7b699aef1751..000000000000 --- a/docs/feature_joystick.md +++ /dev/null @@ -1,228 +0,0 @@ -# Joystick :id=joystick - -This feature provides game controller input as a joystick device supporting up to 6 axes and 32 buttons. Axes can be read either from an [ADC-capable input pin](adc_driver.md), or can be virtual, so that its value is provided by your code. - -An analog device such as a [potentiometer](https://en.wikipedia.org/wiki/Potentiometer) found on an analog joystick's axes is based on a voltage divider, where adjusting the movable wiper controls the output voltage which can then be read by the microcontroller's ADC. - -## Usage :id=usage - -Add the following to your `rules.mk`: - -```make -JOYSTICK_ENABLE = yes -``` - -By default the joystick driver is `analog`, but you can change this with: - -```make -JOYSTICK_DRIVER = digital -``` - -## Configuration :id=configuration - -By default, two axes and eight buttons are defined, with a reported resolution of 8 bits (-127 to +127). This can be changed in your `config.h`: - -```c -// Min 0, max 32 -#define JOYSTICK_BUTTON_COUNT 16 -// Min 0, max 6: X, Y, Z, Rx, Ry, Rz -#define JOYSTICK_AXIS_COUNT 3 -// Min 8, max 16 -#define JOYSTICK_AXIS_RESOLUTION 10 -``` - -?> You must define at least one button or axis. Also note that the maximum ADC resolution of the supported AVR MCUs is 10-bit, and 12-bit for most STM32 MCUs. - -### Axes :id=axes - -When defining axes for your joystick, you must provide a definition array typically in your `keymap.c`. - -For instance, the below example configures two axes. The X axis is read from the `A4` pin. With the default axis resolution of 8 bits, the range of values between 900 and 575 are scaled to -127 through 0, and values 575 to 285 are scaled to 0 through 127. The Y axis is configured as a virtual axis, and its value is not read from any pin. Instead, the user must update the axis value programmatically. - -```c -joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = { - JOYSTICK_AXIS_IN(A4, 900, 575, 285), - JOYSTICK_AXIS_VIRTUAL -}; -``` - -Axes can be configured using one of the following macros: - - * `JOYSTICK_AXIS_IN(input_pin, low, rest, high)` - The ADC samples the provided pin. `low`, `high` and `rest` correspond to the minimum, maximum, and resting (or centered) analog values of the axis, respectively. - * `JOYSTICK_AXIS_IN_OUT(input_pin, output_pin, low, rest, high)` - Same as `JOYSTICK_AXIS_IN()`, but the provided `output_pin` will be pulled high before `input_pin` is read. - * `JOYSTICK_AXIS_IN_OUT_GROUND(input_pin, output_pin, ground_pin, low, rest, high)` - Same as `JOYSTICK_AXIS_IN_OUT()`, but the provided `ground_pin` will be pulled low before reading from `input_pin`. - * `JOYSTICK_AXIS_VIRTUAL` - No ADC reading is performed. The value should be provided by user code. - -The `low` and `high` values can be swapped to effectively invert the axis. - -#### Virtual Axes :id=virtual-axes - -The following example adjusts two virtual axes (X and Y) based on keypad presses, with `KC_P0` as a precision modifier: - -```c -joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = { - JOYSTICK_AXIS_VIRTUAL, // x - JOYSTICK_AXIS_VIRTUAL // y -}; - -static bool precision = false; -static uint16_t precision_mod = 64; -static uint16_t axis_val = 127; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - int16_t precision_val = axis_val; - if (precision) { - precision_val -= precision_mod; - } - - switch (keycode) { - case KC_P8: - joystick_set_axis(1, record->event.pressed ? -precision_val : 0); - return false; - case KC_P2: - joystick_set_axis(1, record->event.pressed ? precision_val : 0); - return false; - case KC_P4: - joystick_set_axis(0, record->event.pressed ? -precision_val : 0); - return false; - case KC_P6: - joystick_set_axis(0, record->event.pressed ? precision_val : 0); - return false; - case KC_P0: - precision = record->event.pressed; - return false; - } - return true; -} -``` - -## Keycodes :id=keycodes - -|Key |Aliases|Description| -|-----------------------|-------|-----------| -|`QK_JOYSTICK_BUTTON_0` |`JS_0` |Button 0 | -|`QK_JOYSTICK_BUTTON_1` |`JS_1` |Button 1 | -|`QK_JOYSTICK_BUTTON_2` |`JS_2` |Button 2 | -|`QK_JOYSTICK_BUTTON_3` |`JS_3` |Button 3 | -|`QK_JOYSTICK_BUTTON_4` |`JS_4` |Button 4 | -|`QK_JOYSTICK_BUTTON_5` |`JS_5` |Button 5 | -|`QK_JOYSTICK_BUTTON_6` |`JS_6` |Button 6 | -|`QK_JOYSTICK_BUTTON_7` |`JS_7` |Button 7 | -|`QK_JOYSTICK_BUTTON_8` |`JS_8` |Button 8 | -|`QK_JOYSTICK_BUTTON_9` |`JS_9` |Button 9 | -|`QK_JOYSTICK_BUTTON_10`|`JS_10`|Button 10 | -|`QK_JOYSTICK_BUTTON_11`|`JS_11`|Button 11 | -|`QK_JOYSTICK_BUTTON_12`|`JS_12`|Button 12 | -|`QK_JOYSTICK_BUTTON_13`|`JS_13`|Button 13 | -|`QK_JOYSTICK_BUTTON_14`|`JS_14`|Button 14 | -|`QK_JOYSTICK_BUTTON_15`|`JS_15`|Button 15 | -|`QK_JOYSTICK_BUTTON_16`|`JS_16`|Button 16 | -|`QK_JOYSTICK_BUTTON_17`|`JS_17`|Button 17 | -|`QK_JOYSTICK_BUTTON_18`|`JS_18`|Button 18 | -|`QK_JOYSTICK_BUTTON_19`|`JS_19`|Button 19 | -|`QK_JOYSTICK_BUTTON_20`|`JS_20`|Button 20 | -|`QK_JOYSTICK_BUTTON_21`|`JS_21`|Button 21 | -|`QK_JOYSTICK_BUTTON_22`|`JS_22`|Button 22 | -|`QK_JOYSTICK_BUTTON_23`|`JS_23`|Button 23 | -|`QK_JOYSTICK_BUTTON_24`|`JS_24`|Button 24 | -|`QK_JOYSTICK_BUTTON_25`|`JS_25`|Button 25 | -|`QK_JOYSTICK_BUTTON_26`|`JS_26`|Button 26 | -|`QK_JOYSTICK_BUTTON_27`|`JS_27`|Button 27 | -|`QK_JOYSTICK_BUTTON_28`|`JS_28`|Button 28 | -|`QK_JOYSTICK_BUTTON_29`|`JS_29`|Button 29 | -|`QK_JOYSTICK_BUTTON_30`|`JS_30`|Button 30 | -|`QK_JOYSTICK_BUTTON_31`|`JS_31`|Button 31 | - -## API :id=api - -### `struct joystick_t` :id=api-joystick-t - -Contains the state of the joystick. - -#### Members :id=api-joystick-t-members - - - `uint8_t buttons[]` - A bit-packed array containing the joystick button states. The size is calculated as `(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1`. - - `int16_t axes[]` - An array of analog values for each defined axis. - - `bool dirty` - Whether the current state needs to be sent to the host. - ---- - -### `struct joystick_config_t` :id=api-joystick-config-t - -Describes a single axis. - -#### Members :id=api-joystick-config-t-members - - - `pin_t output_pin` - A pin to set as output high when reading the analog value, or `JS_VIRTUAL_AXIS`. - - `pin_t input_pin` - The pin to read the analog value from, or `JS_VIRTUAL_AXIS`. - - `pin_t ground_pin` - A pin to set as output low when reading the analog value, or `JS_VIRTUAL_AXIS`. - - `uint16_t min_digit` - The minimum analog value. - - `uint16_t mid_digit` - The resting or midpoint analog value. - - `uint16_t max_digit` - The maximum analog value. - ---- - -### `void joystick_flush(void)` :id=api-joystick-flush - -Send the joystick report to the host, if it has been marked as dirty. - ---- - -### `void register_joystick_button(uint8_t button)` :id=api-register-joystick-button - -Set the state of a button, and flush the report. - -#### Arguments :id=api-register-joystick-button-arguments - - - `uint8_t button` - The index of the button to press, from 0 to 31. - ---- - -### `void unregister_joystick_button(uint8_t button)` :id=api-unregister-joystick-button - -Reset the state of a button, and flush the report. - -#### Arguments :id=api-unregister-joystick-button-arguments - - - `uint8_t button` - The index of the button to release, from 0 to 31. - ---- - -### `int16_t joystick_read_axis(uint8_t axis)` :id=api-joystick-read-axis - -Sample and process the analog value of the given axis. - -#### Arguments :id=api-joystick-read-axis-arguments - - - `uint8_t axis` - The axis to read. - -#### Return Value :id=api-joystick-read-axis-return - -A signed 16-bit integer, where 0 is the resting or mid point. - -### `void joystick_set_axis(uint8_t axis, int16_t value)` :id=api-joystick-set-axis - -Set the value of the given axis. - -#### Arguments :id=api-joystick-set-axis-arguments - - - `uint8_t axis` - The axis to set the value of. - - `int16_t value` - The value to set. diff --git a/docs/feature_key_lock.md b/docs/feature_key_lock.md deleted file mode 100644 index 1acee524dad6..000000000000 --- a/docs/feature_key_lock.md +++ /dev/null @@ -1,23 +0,0 @@ -# Key Lock - -Sometimes you may find yourself needing to hold down a specific key for a long period of time. Key Lock holds down the next key you press for you. Press it again, and it will be released. - -Let's say you need to type in ALL CAPS for a few sentences. Hit `QK_LOCK`, and then Shift. Now, Shift will be considered held until you tap it again. You can think of Key Lock as Caps Lock, but supercharged. - -## Usage - -First, enable Key Lock by setting `KEY_LOCK_ENABLE = yes` in your `rules.mk`. Then pick a key in your keymap and assign it the keycode `QK_LOCK`. - -## Keycodes - -|Keycode |Description | -|---------|--------------------------------------------------------------| -|`QK_LOCK`|Hold down the next key pressed, until the key is pressed again| - -## Caveats - -Key Lock is only able to hold standard action keys and [One Shot modifier](one_shot_keys.md) keys (for example, if you have your Shift defined as `OSM(MOD_LSFT)`). -This does not include any of the QMK special functions (except One Shot modifiers), or shifted versions of keys such as `KC_LPRN`. If it's in the [Basic Keycodes](keycodes_basic.md) list, it can be held. - -Switching layers will not cancel the Key Lock. The Key Lock can be cancelled by calling the `cancel_key_lock()` function. - diff --git a/docs/feature_key_overrides.md b/docs/feature_key_overrides.md deleted file mode 100644 index 608eb001e4b8..000000000000 --- a/docs/feature_key_overrides.md +++ /dev/null @@ -1,227 +0,0 @@ -# Key Overrides :id=key-overrides - -Key overrides allow you to override modifier-key combinations to send a different modifier-key combination or perform completely custom actions. Don't want `shift` + `1` to type `!` on your computer? Use a key override to make your keyboard type something different when you press `shift` + `1`. The general behavior is like this: If `modifiers w` + `key x` are pressed, replace these keys with `modifiers y` + `key z` in the keyboard report. - -You can use key overrides in a similar way to momentary layer/fn keys to activate custom keycodes/shortcuts, with a number of benefits: You completely keep the original use of the modifier keys, while being able to save space by removing fn keys from your keyboard. You can also easily configure _combinations of modifiers_ to trigger different actions than individual modifiers, and much more. The possibilities are quite vast and this documentation contains a few examples for inspiration throughout. - -##### A few more examples to get started: You could use key overrides to... -- Send `brightness up/down` when pressing `ctrl` + `volume up/down`. -- Send `delete` when pressing `shift` + `backspace`. -- Create custom shortcuts or change existing ones: E.g. Send `ctrl`+`shift`+`z` when `ctrl`+`y` is pressed. -- Run custom code when `ctrl` + `alt` + `esc` is pressed. - -## Setup :id=setup - -To enable this feature, you need to add `KEY_OVERRIDE_ENABLE = yes` to your `rules.mk`. - -Then, in your `keymap.c` file, you'll need to define the array `key_overrides`, which defines all key overrides to be used. Each override is a value of type `key_override_t`. The array `key_overrides` is `NULL`-terminated and contains pointers to `key_override_t` values (`const key_override_t **`). - -## Creating Key Overrides :id=creating-key-overrides - -The `key_override_t` struct has many options that allow you to precisely tune your overrides. The full reference is shown below. Instead of manually creating a `key_override_t` value, it is recommended to use these dedicated initializers: - -#### `ko_make_basic(modifiers, key, replacement)` -Returns a `key_override_t`, which sends `replacement` (can be a key-modifer combination), when `key` and `modifiers` are all pressed down. This override still activates if any additional modifiers not specified in `modifiers` are also pressed down. See `ko_make_with_layers_and_negmods` to customize this behavior. - -#### `ko_make_with_layers(modifiers, key, replacement, layers)` -Additionally takes a bitmask `layers` that defines on which layers the override is used. - -#### `ko_make_with_layers_and_negmods(modifiers, key, replacement, layers, negative_mods)` -Additionally takes a bitmask `negative_mods` that defines which modifiers may not be pressed for this override to activate. - -#### `ko_make_with_layers_negmods_and_options(modifiers, key, replacement, layers, negative_mods, options)` -Additionally takes a bitmask `options` that specifies additional options. See `ko_option_t` for available options. - -For more customization possibilities, you may directly create a `key_override_t`, which allows you to customize even more behavior. Read further below for details and examples. - -## Simple Example :id=simple-example - -This shows how the mentioned example of sending `delete` when `shift` + `backspace` are pressed is realized: - -```c -const key_override_t delete_key_override = ko_make_basic(MOD_MASK_SHIFT, KC_BSPC, KC_DEL); - -// This globally defines all key overrides to be used -const key_override_t **key_overrides = (const key_override_t *[]){ - &delete_key_override, - NULL // Null terminate the array of overrides! -}; -``` - -## Intermediate Difficulty Examples :id=intermediate-difficulty-examples - -### Media Controls & Screen Brightness :id=media-controls-amp-screen-brightness - -In this example a single key is configured to control media, volume and screen brightness by using key overrides. - -- The key is set to send `play/pause` in the keymap. - -The following key overrides will be configured: - -- `Ctrl` + `play/pause` will send `next track`. -- `Ctrl` + `Shift` + `play/pause` will send `previous track`. -- `Alt` + `play/pause` will send `volume up`. -- `Alt` + `Shift` + `play/pause` will send `volume down`. -- `Ctrl` + `Alt` + `play/pause` will send `brightness up`. -- `Ctrl` + `Alt` + `Shift` + `play/pause` will send `brightness down`. - - -```c -const key_override_t next_track_override = - ko_make_with_layers_negmods_and_options( - MOD_MASK_CTRL, // Trigger modifiers: ctrl - KC_MPLY, // Trigger key: play/pause - KC_MNXT, // Replacement key - ~0, // Activate on all layers - MOD_MASK_SA, // Do not activate when shift or alt are pressed - ko_option_no_reregister_trigger); // Specifies that the play key is not registered again after lifting ctrl - -const key_override_t prev_track_override = ko_make_with_layers_negmods_and_options(MOD_MASK_CS, KC_MPLY, - KC_MPRV, ~0, MOD_MASK_ALT, ko_option_no_reregister_trigger); - -const key_override_t vol_up_override = ko_make_with_layers_negmods_and_options(MOD_MASK_ALT, KC_MPLY, - KC_VOLU, ~0, MOD_MASK_CS, ko_option_no_reregister_trigger); - -const key_override_t vol_down_override = ko_make_with_layers_negmods_and_options(MOD_MASK_SA, KC_MPLY, - KC_VOLD, ~0, MOD_MASK_CTRL, ko_option_no_reregister_trigger); - -const key_override_t brightness_up_override = ko_make_with_layers_negmods_and_options(MOD_MASK_CA, KC_MPLY, - KC_BRIU, ~0, MOD_MASK_SHIFT, ko_option_no_reregister_trigger); - -const key_override_t brightness_down_override = ko_make_basic(MOD_MASK_CSA, KC_MPLY, KC_BRID); - -// This globally defines all key overrides to be used -const key_override_t **key_overrides = (const key_override_t *[]){ - &next_track_override, - &prev_track_override, - &vol_up_override, - &vol_down_override, - &brightness_up_override, - &brightness_down_override, - NULL -}; -``` - -### Flexible macOS-friendly Grave Escape :id=flexible-macos-friendly-grave-escape -The [Grave Escape feature](feature_grave_esc.md) is limited in its configurability and has [bugs when used on macOS](feature_grave_esc.md#caveats). Key overrides can be used to achieve a similar functionality as Grave Escape, but with more customization and without bugs on macOS. - -```c -// Shift + esc = ~ -const key_override_t tilde_esc_override = ko_make_basic(MOD_MASK_SHIFT, KC_ESC, S(KC_GRV)); - -// GUI + esc = ` -const key_override_t grave_esc_override = ko_make_basic(MOD_MASK_GUI, KC_ESC, KC_GRV); - -const key_override_t **key_overrides = (const key_override_t *[]){ - &tilde_esc_override, - &grave_esc_override, - NULL -}; -``` - -In addition to not encountering unexpected bugs on macOS, you can also change the behavior as you wish. Instead setting `GUI` + `ESC` = `` ` `` you may change it to an arbitrary other modifier, for example `Ctrl` + `ESC` = `` ` ``. - -## Advanced Examples :id=advanced-examples -### Modifiers as Layer Keys :id=modifiers-as-layer-keys - -Do you really need a dedicated key to toggle your fn layer? With key overrides, perhaps not. This example shows how you can configure to use `rGUI` + `rAlt` (right GUI and right alt) to access a momentary layer like an fn layer. With this you completely eliminate the need to use a dedicated layer key. Of course the choice of modifier keys can be changed as needed, `rGUI` + `rAlt` is just an example here. - -```c -// This is called when the override activates and deactivates. Enable the fn layer on activation and disable on deactivation -bool momentary_layer(bool key_down, void *layer) { - if (key_down) { - layer_on((uint8_t)(uintptr_t)layer); - } else { - layer_off((uint8_t)(uintptr_t)layer); - } - - return false; -} - -const key_override_t fn_override = {.trigger_mods = MOD_BIT(KC_RGUI) | MOD_BIT(KC_RCTL), // - .layers = ~(1 << LAYER_FN), // - .suppressed_mods = MOD_BIT(KC_RGUI) | MOD_BIT(KC_RCTL), // - .options = ko_option_no_unregister_on_other_key_down, // - .negative_mod_mask = (uint8_t) ~(MOD_BIT(KC_RGUI) | MOD_BIT(KC_RCTL)), // - .custom_action = momentary_layer, // - .context = (void *)LAYER_FN, // - .trigger = KC_NO, // - .replacement = KC_NO, // - .enabled = NULL}; -``` - -## Keycodes :id=keycodes - -|Keycode |Aliases |Description | -|------------------------|---------|----------------------| -|`QK_KEY_OVERRIDE_TOGGLE`|`KO_TOGG`|Toggle key overrides | -|`QK_KEY_OVERRIDE_ON` |`KO_ON` |Turn on key overrides | -|`QK_KEY_OVERRIDE_OFF` |`KO_OFF` |Turn off key overrides| - -## Reference for `key_override_t` :id=reference-for-key_override_t - -Advanced users may need more customization than what is offered by the simple `ko_make` initializers. For this, directly create a `key_override_t` value and set all members. Below is a reference for all members of `key_override_t`. - -| Member | Description | -|--------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `uint16_t trigger` | The non-modifier keycode that triggers the override. This keycode, and the necessary modifiers (`trigger_mods`) must be pressed to activate this override. Set this to the keycode of the key that should activate the override. Set to `KC_NO` to require only the necessary modifiers to be pressed and no non-modifier. | -| `uint8_t trigger_mods` | Which mods need to be down for activation. If both sides of a modifier are set (e.g. left ctrl and right ctrl) then only one is required to be pressed (e.g. left ctrl suffices). Use the `MOD_MASK_XXX` and `MOD_BIT()` macros for this. | -| `layer_state_t layers` | This is a BITMASK (!), defining which layers this override applies to. To use this override on layer i set the ith bit `(1 << i)`. | -| `uint8_t negative_mod_mask` | Which modifiers cannot be down. It must hold that `(active_modifiers & negative_mod_mask) == 0`, otherwise the key override will not be activated. An active override will be deactivated once this is no longer true. | -| `uint8_t suppressed_mods` | Modifiers to 'suppress' while the override is active. To suppress a modifier means that even though the modifier key is held down, the host OS sees the modifier as not pressed. Can be used to suppress the trigger modifiers, as a trivial example. | -| `uint16_t replacement` | The complex keycode to send as replacement when this override is triggered. This can be a simple keycode, a key-modifier combination (e.g. `C(KC_A)`), or `KC_NO` (to register no replacement keycode). Use in combination with suppressed_mods to get the correct modifiers to be sent. | -| `ko_option_t options` | Options controlling the behavior of the override, such as what actions are allowed to activate the override. | -| `bool (*custom_action)(bool activated, void *context)` | If not NULL, this function will be called right before the replacement key is registered, along with the provided context and a flag indicating whether the override was activated or deactivated. This function allows you to run some custom actions for specific key overrides. If you return `false`, the replacement key is not registered/unregistered as it would normally. Return `true` to register and unregister the override normally. | -| `void *context` | A context that will be passed to the custom action function. | -| `bool *enabled` | If this points to false this override will not be used. Set to NULL to always have this override enabled. | - -## Reference for `ko_option_t` :id=reference-for-ko_option_t - -Bitfield with various options controlling the behavior of a key override. - -| Value | Description | -|------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `ko_option_activation_trigger_down` | Allow activating when the trigger key is pressed down. | -| `ko_option_activation_required_mod_down` | Allow activating when a necessary modifier is pressed down. | -| `ko_option_activation_negative_mod_up` | Allow activating when a negative modifier is released. | -| `ko_option_one_mod` | If set, any of the modifiers in `trigger_mods` will be enough to activate the override (logical OR of modifiers). If not set, all the modifiers in `trigger_mods` have to be pressed (logical AND of modifiers). | -| `ko_option_no_unregister_on_other_key_down` | If set, the override will not deactivate when another key is pressed down. Use only if you really know you need this. | -| `ko_option_no_reregister_trigger` | If set, the trigger key will never be registered again after the override is deactivated. | -| `ko_options_default` | The default options used by the `ko_make_xxx` functions | - -## For Advanced Users: Inner Workings :id=for-advanced-users-inner-workings - -This section explains how a key override works in detail, explaining where each member of `key_override_t` comes into play. Understanding this is essential to be able to take full advantage of all the options offered by key overrides. - -#### Activation :id=activation - -When the necessary keys are pressed (`trigger_mods` + `trigger`), the override is 'activated' and the replacement key is registered in the keyboard report (`replacement`), while the `trigger` key is removed from the keyboard report. The trigger modifiers may also be removed from the keyboard report upon activation of an override (`suppressed_mods`). The override will not activate if any of the `negative_modifiers` are pressed. - -Overrides can activate in three different cases: - -1. The trigger key is pressed down and necessary modifiers are already down. -2. A necessary modifier is pressed down, while the trigger key and other necessary modifiers are already down. -3. A negative modifier is released, while all necessary modifiers and the trigger key are already down. - -Use the `option` member to customize which of these events are allowed to activate your overrides (default: all three). - -In any case, a key override can only activate if the `trigger` key is the _last_ non-modifier key that was pressed down. This emulates the behavior of how standard OSes (macOS, Windows, Linux) handle normal key input (to understand: Hold down `a`, then also hold down `b`, then hold down `shift`; `B` will be typed but not `A`). - -#### Deactivation :id=deactivation - -An override is 'deactivated' when one of the trigger keys (`trigger_mods`, `trigger`) is lifted, another non-modifier key is pressed down, or one of the `negative_modifiers` is pressed down. When an override deactivates, the `replacement` key is removed from the keyboard report, while the `suppressed_mods` that are still held down are re-added to the keyboard report. By default, the `trigger` key is re-added to the keyboard report if it is still held down and no other non-modifier key has been pressed since. This again emulates the behavior of how standard OSes handle normal key input (To understand: hold down `a`, then also hold down `b`, then also `shift`, then release `b`; `A` will not be typed even though you are holding the `a` and `shift` keys). Use the `option` field `ko_option_no_reregister_trigger` to prevent re-registering the trigger key in all cases. - -#### Key Repeat Delay :id=key-repeat-delay - -A third way in which standard OS-handling of modifier-key input is emulated in key overrides is with a ['key repeat delay'](https://www.dummies.com/computers/pcs/set-your-keyboards-repeat-delay-and-repeat-rate/). To explain what this is, let's look at how normal keyboard input is handled by mainstream OSes again: If you hold down `a`, followed by `shift`, you will see the letter `a` is first typed, then for a short moment nothing is typed and then repeating `A`s are typed. Take note that, although shift is pressed down just after `a` is pressed, it takes a moment until `A` is typed. This is caused by the aforementioned key repeat delay, and it is a feature that prevents unwanted repeated characters from being typed. - -This applies equally to releasing a modifier: When you hold `shift`, then press `a`, the letter `A` is typed. Now if you release `shift` first, followed by `a` shortly after, you will not see the letter `a` being typed, even though for a short moment of time you were just holding down the key `a`. This is because no modified characters are typed until the key repeat delay has passed. - - This exact behavior is implemented in key overrides as well: If a key override for `shift` + `a` = `b` exists, and `a` is pressed and held, followed by `shift`, you will not immediately see the letter `b` being typed. Instead, this event is deferred for a short moment, until the key repeat delay has passed, measured from the moment when the trigger key (`a`) was pressed down. - -The duration of the key repeat delay is controlled with the `KEY_OVERRIDE_REPEAT_DELAY` macro. Define this value in your `config.h` file to change it. It is 500ms by default. - - -## Difference to Combos :id=difference-to-combos - -Note that key overrides are very different from [combos](https://docs.qmk.fm/#/feature_combo). Combos require that you press down several keys almost _at the same time_ and can work with any combination of non-modifier keys. Key overrides work like keyboard shortcuts (e.g. `ctrl` + `z`): They take combinations of _multiple_ modifiers and _one_ non-modifier key to then perform some custom action. Key overrides are implemented with much care to behave just like normal keyboard shortcuts would in regards to the order of pressed keys, timing, and interacton with other pressed keys. There are a number of optional settings that can be used to really fine-tune the behavior of each key override as well. Using key overrides also does not delay key input for regular key presses, which inherently happens in combos and may be undesirable. diff --git a/docs/feature_layers.md b/docs/feature_layers.md deleted file mode 100644 index 8503603ffefa..000000000000 --- a/docs/feature_layers.md +++ /dev/null @@ -1,188 +0,0 @@ -# Layers :id=layers - -One of the most powerful and well used features of QMK Firmware is the ability to use layers. For most people, this amounts to a function key that allows for different keys, much like what you would see on a laptop or tablet keyboard. - -For a detailed explanation of how the layer stack works, checkout [Keymap Overview](keymap.md#keymap-and-layers). - -## Switching and Toggling Layers :id=switching-and-toggling-layers - -These functions allow you to activate layers in various ways. Note that layers are not generally independent layouts -- multiple layers can be activated at once, and it's typical for layers to use `KC_TRNS` to allow keypresses to pass through to lower layers. When using momentary layer switching with MO(), LM(), TT(), or LT(), make sure to leave the key on the above layers transparent or it may not work as intended. - -* `DF(layer)` - switches the default layer. The default layer is the always-active base layer that other layers stack on top of. See below for more about the default layer. This might be used to switch from QWERTY to Dvorak layout. (Note that this is a temporary switch that only persists until the keyboard loses power. To modify the default layer in a persistent way requires deeper customization, such as calling the `set_single_persistent_default_layer` function inside of [process_record_user](custom_quantum_functions.md#programming-the-behavior-of-any-keycode).) -* `MO(layer)` - momentarily activates *layer*. As soon as you let go of the key, the layer is deactivated. -* `LM(layer, mod)` - Momentarily activates *layer* (like `MO`), but with modifier(s) *mod* active. Only supports layers 0-15. The modifiers this keycode accept are prefixed with `MOD_`, not `KC_`. These modifiers can be combined using bitwise OR, e.g. `LM(_RAISE, MOD_LCTL | MOD_LALT)`. -* `LT(layer, kc)` - momentarily activates *layer* when held, and sends *kc* when tapped. Only supports layers 0-15. -* `OSL(layer)` - momentarily activates *layer* until the next key is pressed. See [One Shot Keys](one_shot_keys.md) for details and additional functionality. -* `TG(layer)` - toggles *layer*, activating it if it's inactive and vice versa -* `TO(layer)` - activates *layer* and de-activates all other layers (except your default layer). This function is special, because instead of just adding/removing one layer to your active layer stack, it will completely replace your current active layers, uniquely allowing you to replace higher layers with a lower one. This is activated on keydown (as soon as the key is pressed). -* `TT(layer)` - Layer Tap-Toggle. If you hold the key down, *layer* is activated, and then is de-activated when you let go (like `MO`). If you repeatedly tap it, the layer will be toggled on or off (like `TG`). It needs 5 taps by default, but you can change this by defining `TAPPING_TOGGLE` -- for example, `#define TAPPING_TOGGLE 2` to toggle on just two taps. - -### Caveats :id=caveats - -Currently, the `layer` argument of `LT()` is limited to layers 0-15, and the `kc` argument to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 4 bits are used for the function identifier and 4 bits for the layer, leaving only 8 bits for the keycode. - -For a similar reason, the `layer` argument of `LM()` is also limited to layers 0-15 and the `mod` argument must fit within 5 bits. As a consequence, although left and right modifiers are supported by `LM()`, it is impossible to mix and match left and right modifiers. Specifying at least one right-hand modifier in a combination such as `MOD_RALT|MOD_LSFT` will convert *all* the listed modifiers to their right-hand counterpart. So, using the aforementionned mod-mask will actually send Right Alt+Right Shift. Make sure to use the `MOD_xxx` constants over alternative ways of specifying modifiers when defining your layer-mod key. - -| `LM(1,KC_LSFT)` | `LM(1,MOD_MASK_SHIFT)` | `LM(1,MOD_BIT(KC_LSFT))` | `LM(1,MOD_LSFT)` | -|:---------------:|:----------------------:|:------------------------:|:----------------:| -| ❌ | ❌ | ❌ | ✅ | - -Expanding this would be complicated, at best. Moving to a 32-bit keycode would solve a lot of this, but would double the amount of space that the keymap matrix uses. And it could potentially cause issues, too. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this. - -## Working with Layers :id=working-with-layers - -Care must be taken when switching layers, it's possible to lock yourself into a layer with no way to deactivate that layer (without unplugging your keyboard.) We've created some guidelines to help users avoid the most common problems. - -### Beginners :id=beginners - -If you are just getting started with QMK you will want to keep everything simple. Follow these guidelines when setting up your layers: - -* Setup layer 0 as your default, "base" layer. This is your normal typing layer, and could be whatever layout you want (qwerty, dvorak, colemak, etc.). It's important to set this as the lowest layer since it will typically have most or all of the keyboard's keys defined, so would block other layers from having any effect if it were above them (i.e., had a higher layer number). -* Arrange your layers in a "tree" layout, with layer 0 as the root. Do not try to enter the same layer from more than one other layer. -* In a layer's keymap, only reference higher-numbered layers. Because layers are processed from the highest-numbered (topmost) active layer down, modifying the state of lower layers can be tricky and error-prone. - -### Intermediate Users :id=intermediate-users - -Sometimes you need more than one base layer. For example, if you want to switch between QWERTY and Dvorak, switch between layouts for different countries, or switch your layout for different videogames. Your base layers should always be the lowest numbered layers. When you have multiple base layers you should always treat them as mutually exclusive. When one base layer is on the others are off. - -### Advanced Users :id=advanced-users - -Once you have a good feel for how layers work and what you can do, you can get more creative. The rules listed in the beginner section will help you be successful by avoiding some of the tricker details but they can be constraining, especially for ultra-compact keyboard users. Understanding how layers work will allow you to use them in more advanced ways. - -Layers stack on top of each other in numerical order. When determining what a keypress does, QMK scans the layers from the top down, stopping when it reaches the first active layer that is not set to `KC_TRNS`. As a result if you activate a layer that is numerically lower than your current layer, and your current layer (or another layer that is active and higher than your target layer) has something other than `KC_TRNS`, that is the key that will be sent, not the key on the layer you just activated. This is the cause of most people's "why doesn't my layer get switched" problem. - -Sometimes, you might want to switch between layers in a macro or as part of a tap dance routine. `layer_on` activates a layer, and `layer_off` deactivates it. More layer-related functions can be found in [action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/action_layer.h). - -## Functions :id=functions - -There are a number of functions (and variables) related to how you can use or manipulate the layers. - -|Function |Description | -|----------------------------------------------|---------------------------------------------------------------------------------------------------------| -| `layer_state_set(layer_mask)` | Directly sets the layer state (avoid unless you know what you are doing). | -| `layer_clear()` | Clears all layers (turns them all off). | -| `layer_move(layer)` | Turns specified layer on, and all other layers off. | -| `layer_on(layer)` | Turns specified layer on, leaves all other layers in existing state. | -| `layer_off(layer)` | Turns specified layer off, leaves all other layers in existing state. | -| `layer_invert(layer)` | Interverts/toggles the state of the specified layer | -| `layer_or(layer_mask)` | Turns on layers based on matching bits between specifed layer and existing layer state. | -| `layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing layer state. | -| `layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing layer state. | -| `layer_debug(layer_mask)` | Prints out the current bit mask and highest active layer to debugger console. | -| `default_layer_set(layer_mask)` | Directly sets the default layer state (avoid unless you know what you are doing). | -| `default_layer_or(layer_mask)` | Turns on layers based on matching bits between specifed layer and existing default layer state. | -| `default_layer_and(layer_mask)` | Turns on layers based on matching enabled bits between specifed layer and existing default layer state. | -| `default_layer_xor(layer_mask)` | Turns on layers based on non-matching bits between specifed layer and existing default layer state. | -| `default_layer_debug(layer_mask)` | Prints out the current bit mask and highest active default layer to debugger console. | -| [`set_single_persistent_default_layer(layer)`](ref_functions.md#setting-the-persistent-default-layer) | Sets the default layer and writes it to persistent memory (EEPROM). | -| [`update_tri_layer(x, y, z)`](ref_functions.md#update_tri_layerx-y-z) | Checks if layers `x` and `y` are both on, and sets `z` based on that (on if both on, otherwise off). | -| [`update_tri_layer_state(state, x, y, z)`](ref_functions.md#update_tri_layer_statestate-x-y-z) | Does the same as `update_tri_layer(x, y, z)`, but from `layer_state_set_*` functions. | - -In addition to the functions that you can call, there are a number of callback functions that get called every time the layer changes. This passes the layer state to the function, where it can be read or modified. - -|Callback |Description | -|-----------------------------------------------------|----------------------------------------------------------------------------------------| -| `layer_state_set_kb(layer_state_t state)` | Callback for layer functions, for keyboard. | -| `layer_state_set_user(layer_state_t state)` | Callback for layer functions, for users. | -| `default_layer_state_set_kb(layer_state_t state)` | Callback for default layer functions, for keyboard. Called on keyboard initialization. | -| `default_layer_state_set_user(layer_state_t state)` | Callback for default layer functions, for users. Called on keyboard initialization. | - -?> For additional details on how you can use these callbacks, check out the [Layer Change Code](custom_quantum_functions.md#layer-change-code) document. - -It is also possible to check the state of a particular layer using the following functions and macros. - -|Function |Description |Aliases -|---------------------------------|-------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------| -| `layer_state_is(layer)` | Checks if the specified `layer` is enabled globally. | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` | -| `layer_state_cmp(state, layer)` | Checks `state` to see if the specified `layer` is enabled. Intended for use in layer callbacks. | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` | - -## Layer Change Code :id=layer-change-code - -This runs code every time that the layers get changed. This can be useful for layer indication, or custom layer handling. - -### Example `layer_state_set_*` Implementation - -This example shows how to set the [RGB Underglow](feature_rgblight.md) lights based on the layer, using the Planck as an example. - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - rgblight_setrgb (0x00, 0x00, 0xFF); - break; - case _LOWER: - rgblight_setrgb (0xFF, 0x00, 0x00); - break; - case _PLOVER: - rgblight_setrgb (0x00, 0xFF, 0x00); - break; - case _ADJUST: - rgblight_setrgb (0x7A, 0x00, 0xFF); - break; - default: // for any other layers, or the default layer - rgblight_setrgb (0x00, 0xFF, 0xFF); - break; - } - return state; -} -``` - -### Example: Keycode to cycle through layers - -This example shows how to implement a custom keycode to cycle through a range of layers. - -```c -// Define the keycode, `QK_USER` avoids collisions with existing keycodes -enum keycodes { - KC_CYCLE_LAYERS = QK_USER, -}; - -// 1st layer on the cycle -#define LAYER_CYCLE_START 0 -// Last layer on the cycle -#define LAYER_CYCLE_END 4 - -// Add the behaviour of this new keycode -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_CYCLE_LAYERS: - // Our logic will happen on presses, nothing is done on releases - if (!record->event.pressed) { - // We've already handled the keycode (doing nothing), let QMK know so no further code is run unnecessarily - return false; - } - - uint8_t current_layer = get_highest_layer(layer_state); - - // Check if we are within the range, if not quit - if (curent_layer > LAYER_CYCLE_END || current_layer < LAYER_CYCLE_START) { - return false; - } - - uint8_t next_layer = current_layer + 1; - if (next_layer > LAYER_CYCLE_END) { - next_layer = LAYER_CYCLE_START; - } - layer_move(next_layer); - return false; - - // Process other keycodes normally - default: - return true; - } -} - -// Place `KC_CYCLE_LAYERS` as a keycode in your keymap -``` - -Use the `IS_LAYER_ON_STATE(state, layer)` and `IS_LAYER_OFF_STATE(state, layer)` macros to check the status of a particular layer. - -Outside of `layer_state_set_*` functions, you can use the `IS_LAYER_ON(layer)` and `IS_LAYER_OFF(layer)` macros to check global layer state. - -### `layer_state_set_*` Function Documentation - -* Keyboard/Revision: `layer_state_t layer_state_set_kb(layer_state_t state)` -* Keymap: `layer_state_t layer_state_set_user(layer_state_t state)` - - -The `state` is the bitmask of the active layers, as explained in the [Keymap Overview](keymap.md#keymap-layer-status) diff --git a/docs/feature_layouts.md b/docs/feature_layouts.md deleted file mode 100644 index 93d040b5542c..000000000000 --- a/docs/feature_layouts.md +++ /dev/null @@ -1,109 +0,0 @@ -# Layouts: Using a Keymap with Multiple Keyboards - -The `layouts/` folder contains different physical key layouts that can apply to different keyboards. - -``` -layouts/ -+ default/ -| + 60_ansi/ -| | + readme.md -| | + layout.json -| | + a_good_keymap/ -| | | + keymap.c -| | | + readme.md -| | | + config.h -| | | + rules.mk -| | + / -| | + ... -| + / -+ community/ -| + / -| + ... -``` - -The `layouts/default/` and `layouts/community/` are two examples of layout "repositories" - currently `default` will contain all of the information concerning the layout, and one default keymap named `default_`, for users to use as a reference. `community` contains all of the community keymaps, with the eventual goal of being split-off into a separate repo for users to clone into `layouts/`. QMK searches through all folders in `layouts/`, so it's possible to have multiple repositories here. - -Each layout folder is named (`[a-z0-9_]`) after the physical aspects of the layout, in the most generic way possible, and contains a `readme.md` with the layout to be defined by the keyboard: - -```markdown -# 60_ansi - - LAYOUT_60_ansi -``` - -New names should try to stick to the standards set by existing layouts, and can be discussed in the PR/Issue. - -## Supporting a Layout - -For a keyboard to support a layout, the variable must be defined in it's `.h`, and match the number of arguments/keys (and preferably the physical layout): - - #define LAYOUT_60_ansi KEYMAP_ANSI - -The name of the layout must match this regex: `[a-z0-9_]+` - -The folder name must be added to the keyboard's `rules.mk`: - - LAYOUTS = 60_ansi - -`LAYOUTS` can be set in any keyboard folder level's `rules.mk`: - - LAYOUTS = 60_iso - -but the `LAYOUT_` variable must be defined in `.h` as well. - -## Building a Keymap - -You should be able to build the keyboard keymap with a command in this format: - - make : - -### Conflicting layouts -When a keyboard supports multiple layout options, - - LAYOUTS = ortho_4x4 ortho_4x12 - -And a layout exists for both options, -``` -layouts/ -+ community/ -| + ortho_4x4/ -| | + / -| | | + ... -| + ortho_4x12/ -| | + / -| | | + ... -| + ... -``` - -The FORCE_LAYOUT argument can be used to specify which layout to build - - make : FORCE_LAYOUT=ortho_4x4 - make : FORCE_LAYOUT=ortho_4x12 - -## Tips for Making Layouts Keyboard-Agnostic - -### Includes - -Instead of using `#include "planck.h"`, you can use this line to include whatever `.h` (`.h` should not be included here) file that is being compiled: - - #include QMK_KEYBOARD_H - -If you want to keep some keyboard-specific code, you can use these variables to escape it with an `#ifdef` statement: - -* `KEYBOARD__` - -For example: - -```c -#ifdef KEYBOARD_planck - #ifdef KEYBOARD_planck_rev4 - planck_rev4_function(); - #endif -#endif -``` - -Note that the names are lowercase and match the folder/file names for the keyboard/revision exactly. - -### Keymaps - -In order to support both split and non-split keyboards with the same layout, you need to use the keyboard agnostic `LAYOUT_` macro in your keymap. For instance, in order for a Let's Split and Planck to share the same layout file, you need to use `LAYOUT_ortho_4x12` instead of `LAYOUT_planck_grid` or just `{}` for a C array. diff --git a/docs/feature_leader_key.md b/docs/feature_leader_key.md deleted file mode 100644 index 72a6818dd1dd..000000000000 --- a/docs/feature_leader_key.md +++ /dev/null @@ -1,297 +0,0 @@ -# The Leader Key: A New Kind of Modifier :id=the-leader-key - -If you're a Vim user, you probably know what a Leader key is. In contrast to [Combos](feature_combo.md), the Leader key allows you to hit a *sequence* of up to five keys instead, which triggers some custom functionality once complete. - -## Usage :id=usage - -Add the following to your `rules.mk`: - -```make -LEADER_ENABLE = yes -``` - -Then add the `QK_LEAD` keycode to your keymap. - -## Callbacks :id=callbacks - -These callbacks are invoked when the leader sequence begins and ends. In the latter you can implement your custom functionality based on the contents of the sequence buffer. - -```c -void leader_start_user(void) { - // Do something when the leader key is pressed -} - -void leader_end_user(void) { - if (leader_sequence_one_key(KC_F)) { - // Leader, f => Types the below string - SEND_STRING("QMK is awesome."); - } else if (leader_sequence_two_keys(KC_D, KC_D)) { - // Leader, d, d => Ctrl+A, Ctrl+C - SEND_STRING(SS_LCTL("a") SS_LCTL("c")); - } else if (leader_sequence_three_keys(KC_D, KC_D, KC_S)) { - // Leader, d, d, s => Types the below string - SEND_STRING("https://start.duckduckgo.com\n"); - } else if (leader_sequence_two_keys(KC_A, KC_S)) { - // Leader, a, s => GUI+S - tap_code16(LGUI(KC_S)); - } -} -``` - -## Basic Configuration :id=basic-configuration - -### Timeout :id=timeout - -This is the amount of time you have to complete a sequence once the leader key has been pressed. The default value is 300 milliseconds, but you can change this by adding the following to your `config.h`: - -```c -#define LEADER_TIMEOUT 350 -``` - -### Per-Key Timeout :id=per-key-timeout - -Rather than relying on an incredibly high timeout for long leader key strings or those of us without 200 wpm typing skills, you can enable per-key timing to ensure that each key pressed provides you with more time to finish the sequence. This is incredibly helpful with leader key emulation of tap dance (such as multiple taps of the same key like C, C, C). - -To enable this, add the following to your `config.h`: - -```c -#define LEADER_PER_KEY_TIMING -``` - -After this, it's recommended that you lower your timeout below 300 ms: - -```c -#define LEADER_TIMEOUT 250 -``` - -Now, something like this won't seem impossible to do without a 1000 millisecond timeout: - -```c -if (leader_sequence_three_keys(KC_C, KC_C, KC_C)) { - SEND_STRING("Per key timing is great!!!"); -} -``` - -### Disabling Initial Timeout :id=disabling-initial-timeout - -Sometimes your leader key may be too far away from the rest of the keys in the sequence. Imagine that your leader key is one of your outer top right keys - you may need to reposition your hand just to reach your leader key. This can make typing the entire sequence on time hard difficult if you are able to type most of the sequence fast. For example, if your sequence is `Leader + asd`, typing `asd` fast is very easy once you have your hands in your home row, but starting the sequence in time after moving your hand out of the home row to reach the leader key and back is not. - -To remove the stress this situation produces to your hands, you can disable the timeout just for the leader key. Add the following to your `config.h`: - -```c -#define LEADER_NO_TIMEOUT -``` - -Now, after you hit the leader key, you will have an infinite amount of time to start the rest of the sequence, allowing you to properly position your hands to type the rest of the sequence comfortably. This way you can configure a very short `LEADER_TIMEOUT`, but still have plenty of time to position your hands. - -### Strict Key Processing :id=strict-key-processing - -By default, only the "tap keycode" portions of [Mod-Taps](mod_tap.md) and [Layer Taps](feature_layers.md#switching-and-toggling-layers) are added to the sequence buffer. This means if you press eg. `LT(3, KC_A)` as part of a sequence, `KC_A` will be added to the buffer, rather than the entire `LT(3, KC_A)` keycode. - -This gives a more expected behaviour for most users, however you may want to change this. - -To enable this, add the following to your `config.h`: - -```c -#define LEADER_KEY_STRICT_KEY_PROCESSING -``` - -## Example :id=example - -This example will play the Mario "One Up" sound when you hit `QK_LEAD` to start the leader sequence. When the sequence ends, it will play "All Star" if it completes successfully or "Rick Roll" you if it fails (in other words, no sequence matched). - -```c -#ifdef AUDIO_ENABLE -float leader_start_song[][2] = SONG(ONE_UP_SOUND); -float leader_succeed_song[][2] = SONG(ALL_STAR); -float leader_fail_song[][2] = SONG(RICK_ROLL); -#endif - -void leader_start_user(void) { -#ifdef AUDIO_ENABLE - PLAY_SONG(leader_start_song); -#endif -} - -void leader_end_user(void) { - bool did_leader_succeed = false; - - if (leader_sequence_one_key(KC_E)) { - SEND_STRING(SS_LCTL(SS_LSFT("t"))); - did_leader_succeed = true; - } else if (leader_sequence_two_keys(KC_E, KC_D)) { - SEND_STRING(SS_LGUI("r") "cmd\n" SS_LCTL("c")); - did_leader_succeed = true; - } - -#ifdef AUDIO_ENABLE - if (did_leader_succeed) { - PLAY_SONG(leader_succeed_song); - } else { - PLAY_SONG(leader_fail_song); - } -#endif -} -``` - -## Keycodes :id=keycodes - -|Key |Aliases |Description | -|-----------------------|---------|-------------------------| -|`QK_LEADER` |`QK_LEAD`|Begin the leader sequence| - -## API :id=api - -### `void leader_start_user(void)` :id=api-leader-start-user - -User callback, invoked when the leader sequence begins. - ---- - -### `void leader_end_user(void)` :id=api-leader-end-user - -User callback, invoked when the leader sequence ends. - ---- - -### `void leader_start(void)` :id=api-leader-start - -Begin the leader sequence, resetting the buffer and timer. - ---- - -### `void leader_end(void)` :id=api-leader-end - -End the leader sequence. - ---- - -### `bool leader_sequence_active(void)` :id=api-leader-sequence-active - -Whether the leader sequence is active. - ---- - -### `bool leader_sequence_add(uint16_t keycode)` :id=api-leader-sequence-add - -Add the given keycode to the sequence buffer. - -If `LEADER_NO_TIMEOUT` is defined, the timer is reset if the buffer is empty. - -#### Arguments :id=api-leader-sequence-add-arguments - - - `uint16_t keycode` - The keycode to add. - -#### Return Value :id=api-leader-sequence-add-return - -`true` if the keycode was added, `false` if the buffer is full. - ---- - -### `bool leader_sequence_timed_out(void)` :id=api-leader-sequence-timed-out - -Whether the leader sequence has reached the timeout. - -If `LEADER_NO_TIMEOUT` is defined, the buffer must also contain at least one key. - ---- - -### `bool leader_reset_timer(void)` :id=api-leader-reset-timer - -Reset the leader sequence timer. - ---- - -### `bool leader_sequence_one_key(uint16_t kc)` :id=api-leader-sequence-one-key - -Check the sequence buffer for the given keycode. - -#### Arguments :id=api-leader-sequence-one-key-arguments - - - `uint16_t kc` - The keycode to check. - -#### Return Value :id=api-leader-sequence-one-key-return - -`true` if the sequence buffer matches. - ---- - -### `bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2)` :id=api-leader-sequence-two-keys - -Check the sequence buffer for the given keycodes. - -#### Arguments :id=api-leader-sequence-two-keys-arguments - - - `uint16_t kc1` - The first keycode to check. - - `uint16_t kc2` - The second keycode to check. - -#### Return Value :id=api-leader-sequence-two-keys-return - -`true` if the sequence buffer matches. - ---- - -### `bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3)` :id=api-leader-sequence-three-keys - -Check the sequence buffer for the given keycodes. - -#### Arguments :id=api-leader-sequence-three-keys-arguments - - - `uint16_t kc1` - The first keycode to check. - - `uint16_t kc2` - The second keycode to check. - - `uint16_t kc3` - The third keycode to check. - -#### Return Value :id=api-leader-sequence-three-keys-return - -`true` if the sequence buffer matches. - ---- - -### `bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4)` :id=api-leader-sequence-four-keys - -Check the sequence buffer for the given keycodes. - -#### Arguments :id=api-leader-sequence-four-keys-arguments - - - `uint16_t kc1` - The first keycode to check. - - `uint16_t kc2` - The second keycode to check. - - `uint16_t kc3` - The third keycode to check. - - `uint16_t kc4` - The fourth keycode to check. - -#### Return Value :id=api-leader-sequence-four-keys-return - -`true` if the sequence buffer matches. - ---- - -### `bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5)` :id=api-leader-sequence-five-keys - -Check the sequence buffer for the given keycodes. - -#### Arguments :id=api-leader-sequence-five-keys-arguments - - - `uint16_t kc1` - The first keycode to check. - - `uint16_t kc2` - The second keycode to check. - - `uint16_t kc3` - The third keycode to check. - - `uint16_t kc4` - The fourth keycode to check. - - `uint16_t kc5` - The fifth keycode to check. - -#### Return Value :id=api-leader-sequence-five-keys-return - -`true` if the sequence buffer matches. diff --git a/docs/feature_led_indicators.md b/docs/feature_led_indicators.md deleted file mode 100644 index 1f71cdb1c81d..000000000000 --- a/docs/feature_led_indicators.md +++ /dev/null @@ -1,121 +0,0 @@ -# LED Indicators - -?> LED indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LED_STATE_ENABLE`). See [data sync options](feature_split_keyboard.md#data-sync-options) for more details. - -QMK provides methods to read 5 of the LEDs defined in the HID spec: - -* Num Lock -* Caps Lock -* Scroll Lock -* Compose -* Kana - -There are three ways to get the lock LED state: -* Configuration options in `config.h` -* Implement `led_update_*` function -* Call `led_t host_keyboard_led_state()` - -!> The `host_keyboard_led_state()` may reflect an updated state before `led_update_user()` is called. - -Two deprecated functions that provide the LED state as `uint8_t`: - -* `uint8_t led_set_user(uint8_t usb_led)` -* `uint8_t host_keyboard_leds()` - -## Configuration Options - -To configure the indicators, `#define` these in your `config.h`: - -|Define |Default |Description | -|---------------------|-------------|-------------------------------------------| -|`LED_NUM_LOCK_PIN` |*Not defined*|The pin that controls the `Num Lock` LED | -|`LED_CAPS_LOCK_PIN` |*Not defined*|The pin that controls the `Caps Lock` LED | -|`LED_SCROLL_LOCK_PIN`|*Not defined*|The pin that controls the `Scroll Lock` LED| -|`LED_COMPOSE_PIN` |*Not defined*|The pin that controls the `Compose` LED | -|`LED_KANA_PIN` |*Not defined*|The pin that controls the `Kana` LED | -|`LED_PIN_ON_STATE` |`1` |The state of the indicator pins when the LED is "on" - `1` for high, `0` for low| - -Unless you are designing your own keyboard, you generally should not need to change the above config options. - -## LED update function - -When the configuration options do not provide enough flexibility, the following callbacks allow custom control of the LED behavior. These functions will be called when one of those 5 LEDs changes state: - -* Keyboard/revision: `bool led_update_kb(led_t led_state)` -* Keymap: `bool led_update_user(led_t led_state)` - -Both receives LED state as a struct parameter. Returning `true` in `led_update_user()` will allow the keyboard level code in `led_update_kb()` to run as well. Returning `false` will override the keyboard level code, depending on how the keyboard level function is set up. - -?> This boolean return type of `led_update_user` allows for overriding keyboard LED controls, and is thus recommended over the void `led_set_user` function. - -### Example of keyboard LED update implementation - -This is a template indicator function that can be implemented on keyboard level code: - -```c -bool led_update_kb(led_t led_state) { - bool res = led_update_user(led_state); - if(res) { - // writePin sets the pin high for 1 and low for 0. - // In this example the pins are inverted, setting - // it low/0 turns it on, and high/1 turns the LED off. - // This behavior depends on whether the LED is between the pin - // and VCC or the pin and GND. - writePin(B0, !led_state.num_lock); - writePin(B1, !led_state.caps_lock); - writePin(B2, !led_state.scroll_lock); - writePin(B3, !led_state.compose); - writePin(B4, !led_state.kana); - } - return res; -} -``` - -### Example of user LED update implementation - -This is an incomplete example will play a sound if Caps Lock is turned on or off. It returns `true` to allow keyboard LED function to maintain their state. - -```c -#ifdef AUDIO_ENABLE - float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); - float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); -#endif - -bool led_update_user(led_t led_state) { - #ifdef AUDIO_ENABLE - static uint8_t caps_state = 0; - if (caps_state != led_state.caps_lock) { - led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); - caps_state = led_state.caps_lock; - } - #endif - return true; -} -``` - -## Host keyboard LED state - -The `host_keyboard_led_state()` function will report the LED state returned from the host computer as `led_t`. This is useful for reading the LED state outside `led_update_*`. For example, you can get the boolean state of Caps Lock from the host with: - -```c -bool caps = host_keyboard_led_state().caps_lock; -``` - -## `led_update_ports()` - -This function writes the LED state to the actual hardware. Call it manually -from your `led_update_*()` callbacks to modify the handling of the standard -keyboard LEDs. -For example when repurposing a standard LED indicator as layer indicator. - -## Setting Physical LED State - -Some keyboard implementations provide convenient methods for setting the state of the physical LEDs. - -### Ergodox Boards - -The Ergodox implementations provide `ergodox_right_led_1`/`2`/`3_on`/`off()` to turn individual LEDs on or off, as well as `ergodox_right_led_on`/`off(uint8_t led)` to turn them on or off by their index. - -In addition, it is possible to specify the brightness level of all LEDs with `ergodox_led_all_set(uint8_t n)`; of individual LEDs with `ergodox_right_led_1`/`2`/`3_set(uint8_t n)`; or by index with `ergodox_right_led_set(uint8_t led, uint8_t n)`. - -Ergodox boards also define `LED_BRIGHTNESS_LO` for the lowest brightness and `LED_BRIGHTNESS_HI` for the highest brightness (which is the default). diff --git a/docs/feature_led_matrix.md b/docs/feature_led_matrix.md deleted file mode 100644 index bc86099f1ffe..000000000000 --- a/docs/feature_led_matrix.md +++ /dev/null @@ -1,454 +0,0 @@ -# LED Matrix Lighting :id=led-matrix-lighting - -This feature allows you to use LED matrices driven by external drivers. It hooks into the backlight system so you can use the same keycodes as backlighting to control it. - -If you want to use RGB LED's you should use the [RGB Matrix Subsystem](feature_rgb_matrix.md) instead. - -## Driver configuration :id=driver-configuration ---- -### IS31FL3731 :id=is31fl3731 - -There is basic support for addressable LED matrix lighting with the I2C IS31FL3731 LED controller. To enable it, add this to your `rules.mk`: - -```make -LED_MATRIX_ENABLE = yes -LED_MATRIX_DRIVER = IS31FL3731 -``` - -You can use between 1 and 4 IS31FL3731 IC's. Do not specify `LED_DRIVER_ADDR_` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `LED_DRIVER_COUNT` | (Required) How many LED driver IC's are present | | -| `LED_MATRIX_LED_COUNT` | (Required) How many LED lights are present across all drivers | | -| `LED_DRIVER_ADDR_1` | (Required) Address for the first LED driver | | -| `LED_DRIVER_ADDR_2` | (Optional) Address for the second LED driver | | -| `LED_DRIVER_ADDR_3` | (Optional) Address for the third LED driver | | -| `LED_DRIVER_ADDR_4` | (Optional) Address for the fourth LED driver | | - -Here is an example using 2 drivers. - -```c -// This is a 7-bit address, that gets left-shifted and bit 0 -// set to 0 for write, 1 for read (as per I2C protocol) -// The address will vary depending on your wiring: -// 0b1110100 AD <-> GND -// 0b1110111 AD <-> VCC -// 0b1110101 AD <-> SCL -// 0b1110110 AD <-> SDA -#define LED_DRIVER_ADDR_1 0b1110100 -#define LED_DRIVER_ADDR_2 0b1110110 - -#define LED_DRIVER_COUNT 2 -#define LED_DRIVER_1_LED_TOTAL 25 -#define LED_DRIVER_2_LED_TOTAL 24 -#define LED_MATRIX_LED_COUNT (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL) -``` - -!> Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL)` will give very different results than `rand() % LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL`. - -For split keyboards using `LED_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `DRIVER_ADDR_1` for one and `DRIVER_ADDR_2` for the other one. Then, in `g_is31_leds`, fill out the correct driver index (0 or 1). If using one address, use `DRIVER_ADDR_1` for both, and use index 0 for `g_is31_leds`. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led PROGMEM g_is31_leds[LED_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | LED address - * | | */ - { 0, C1_1 }, - { 0, C1_15 }, - // ... -} -``` - -Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731-simple.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` ). - ---- -### IS31FLCOMMON :id=is31flcommon - -There is basic support for addressable LED matrix lighting with a selection of I2C ISSI Lumissil LED controllers through a shared common driver. To enable it, add this to your `rules.mk`: - -```makefile -LED_MATRIX_ENABLE = yes -LED_MATRIX_DRIVER = -``` - -Where `` is the applicable LED driver chip as below - -| Driver Name | Data Sheet | Capability | -|-------------|------------|------------| -| `IS31FL3742A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3742A_DS.pdf) | 180 LED, 30x6 Matrix | -| `IS31FL3743A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3743A_DS.pdf) | 198 LED, 18x11 Matrix | -| `IS31FL3745` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf) | 144 LED, 18x8 Matrix | -| `IS31FL3746A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf) | 72 LED, 18x4 Matrix | - -You can use between 1 and 4 IC's. Do not specify `DRIVER_ADDR_` define for IC's if not present on your keyboard. The `DRIVER_ADDR_1` default assumes that all Address pins on the controller have been connected to GND. Drivers that have SYNC functionality have the default settings to disable if 1 driver. If more than 1 drivers then `DRIVER_ADDR_1` will be set to Master and the remaiing ones set to Slave. - -Configure the hardware via your `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `DRIVER_COUNT` | (Required) How many LED driver IC's are present | | -| `LED_MATRIX_LED_COUNT` | (Required) How many LED lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Optional) Address for the first LED driver | | -| `DRIVER_ADDR_` | (Required) Address for the additional LED drivers | | -| `ISSI_SSR_` | (Optional) Configuration for the Spread Spectrum Register | | -| `ISSI_CONFIGURATION` | (Optional) Configuration for the Configuration Register | | -| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF | -| `ISSI_PULLDOWNUP` | (Optional) Configuration for the Pull Up & Pull Down Register | | -| `ISSI_TEMP` | (Optional) Configuration for the Tempature Register | | -| `ISSI_PWM_ENABLE` | (Optional) Configuration for the PWM Enable Register | | -| `ISSI_PWM_SET` | (Optional) Configuration for the PWM Setting Register | | -| `ISSI_SCAL_LED ` | (Optional) Configuration for the LEDs Scaling Registers | 0xFF | -| `ISSI_MANUAL_SCALING` | (Optional) If you wish to configure the Scaling Registers manually | | - - -Defaults - -| Variable | IS31FL3742A | IS31FL3743A | IS31FL3745 | IS31FL3746 | -|----------|-------------|-------------|------------|------------| -| `DRIVER_ADDR_1` | 0b0110000 | 0b0100000 | 0b0100000 | 0b1100000 | -| `ISSI_SSR_1` | 0x00 | 0x00 / 0x60 | 0x00 / 0xC0 | 0x00 | -| `ISSI_SSR_<2-4>` | 0x00 | 0x40 | 0x80 | 0x00 | -| `ISSI_CONFIGURATION` | 0x31 | 0x01 | 0x31 | 0x01 | -| `ISSI_PULLDOWNUP` | 0x55 | 0x33 | 0x33 | 0x33 | -| `ISSI_TEMP` | N/A | 0x00 | 0x00 | 0x00 | -| `ISSI_PWM_ENABLE` | N/A | N/A | N/A | 0x00 | -| `ISSI_PWM_SET` | 0x00 | N/A | N/A | 0x00 | - -Here is an example using 2 drivers. - -```c -#define DRIVER_ADDR_2 0b0100001 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 66 -#define DRIVER_2_LED_TOTAL 42 -#define LED_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` -!> Note the parentheses, this is so when `LED_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led __flash g_is31_leds[LED_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | LED address - * | | */ - { 0, CS1_SW1 }, - { 0, CS2_SW1 }, - // ... -} -``` - -Where `CSx_SWx` is the location of the LED in the matrix defined by the datasheet. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now). - -`ISSI_MANUAL_SCALING` is used to override the Scaling for individual LED's. By default they will be set as per `ISSI_SCAL_LED`. In `config.h` set how many LED's you want to manually set scaling for. -Eg `#define ISSI_MANUAL_SCALING 3` - -Then Define the array listing all the LEDs you want to override in your `.c`: - -```c -const is31_led __flash g_is31_scaling[ISSI_MANUAL_SCALING] = { - * LED Index - * | Scaling - * | | */ - {5, 120}, - {9, 120}, - .... -} -``` - -Where LED Index is the position of the LED in the `g_is31_leds` array. The `scaling` value between 0 and 255 to be written to the Scaling Register. - ---- - -## Common Configuration :id=common-configuration - -From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example: - -```c -led_config_t g_led_config = { { - // Key Matrix to LED Index - { 5, NO_LED, NO_LED, 0 }, - { NO_LED, NO_LED, NO_LED, NO_LED }, - { 4, NO_LED, NO_LED, 1 }, - { 3, NO_LED, NO_LED, 2 } -}, { - // LED Index to Physical Position - { 188, 16 }, { 187, 48 }, { 149, 64 }, { 112, 64 }, { 37, 48 }, { 38, 16 } -}, { - // LED Index to Flag - 1, 4, 4, 4, 4, 1 -} }; -``` - -The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position: - -```c -x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION -y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION -``` - -Where NUMBER_OF_COLS, NUMBER_OF_ROWS, COL_POSITION, & ROW_POSITION are all based on the physical layout of your keyboard, not the electrical layout. - -As mentioned earlier, the center of the keyboard by default is expected to be `{ 112, 32 }`, but this can be changed if you want to more accurately calculate the LED's physical `{ x, y }` positions. Keyboard designers can implement `#define LED_MATRIX_CENTER { 112, 32 }` in their config.h file with the new center point of the keyboard, or where they want it to be allowing more possibilities for the `{ x, y }` values. Do note that the maximum value for x or y is 255, and the recommended maximum is 224 as this gives animations runoff room before they reset. - -`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type. - -## Flags :id=flags - -|Define |Value |Description | -|----------------------------|------|-------------------------------------------------| -|`HAS_FLAGS(bits, flags)` |*n/a* |Evaluates to `true` if `bits` has all `flags` set| -|`HAS_ANY_FLAGS(bits, flags)`|*n/a* |Evaluates to `true` if `bits` has any `flags` set| -|`LED_FLAG_NONE` |`0x00`|If this LED has no flags | -|`LED_FLAG_ALL` |`0xFF`|If this LED has all flags | -|`LED_FLAG_MODIFIER` |`0x01`|If the LED is on a modifier key | -|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight | -|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication | - -## Keycodes :id=keycodes - -All LED matrix keycodes are currently shared with the [Backlight feature](feature_backlight.md). - -| Key | Aliases | Description | -|-------------------------|-----------|-------------------------------| -| `QK_BACKLIGHT_TOGGLE` | `BL_TOGG` | Toggle LED Matrix on or off | -| `QK_BACKLIGHT_STEP` | `BL_STEP` | Cycle through modes | -| `QK_BACKLIGHT_ON` | `BL_ON` | Turn on LED Matrix | -| `QK_BACKLIGHT_OFF` | `BL_OFF` | Turn off LED Matrix | -| `QK_BACKLIGHT_UP` | `BL_UP` | Increase the brightness level | -| `QK_BACKLIGHT_DOWN` | `BL_DOWN` | Decrease the brightness level | - -## LED Matrix Effects :id=led-matrix-effects - -These are the effects that are currently available: - -```c -enum led_matrix_effects { - LED_MATRIX_NONE = 0, - LED_MATRIX_SOLID = 1, // Static single val, no speed support - LED_MATRIX_ALPHAS_MODS, // Static dual val, speed is val for LEDs marked as modifiers - LED_MATRIX_BREATHING, // Cycling brightness animation - LED_MATRIX_BAND, // Band fading brightness scrolling left to right - LED_MATRIX_BAND_PINWHEEL, // 3 blade spinning pinwheel fades brightness - LED_MATRIX_BAND_SPIRAL, // Spinning spiral fades brightness - LED_MATRIX_CYCLE_LEFT_RIGHT, // Full gradient scrolling left to right - LED_MATRIX_CYCLE_UP_DOWN, // Full gradient scrolling top to bottom - LED_MATRIX_CYCLE_OUT_IN, // Full gradient scrolling out to in - LED_MATRIX_DUAL_BEACON, // Full gradient spinning around center of keyboard -#if defined(LED_MATRIX_KEYPRESSES) || defined(LED_MATRIX_KEYRELEASES) - LED_MATRIX_SOLID_REACTIVE_SIMPLE, // Pulses keys hit then fades out - LED_MATRIX_SOLID_REACTIVE_WIDE // Value pulses near a single key hit then fades out - LED_MATRIX_SOLID_REACTIVE_MULTIWIDE // Value pulses near multiple key hits then fades out - LED_MATRIX_SOLID_REACTIVE_CROSS // Value pulses the same column and row of a single key hit then fades out - LED_MATRIX_SOLID_REACTIVE_MULTICROSS // Value pulses the same column and row of multiple key hits then fades out - LED_MATRIX_SOLID_REACTIVE_NEXUS // Value pulses away on the same column and row of a single key hit then fades out - LED_MATRIX_SOLID_REACTIVE_MULTINEXUS // Value pulses away on the same column and row of multiple key hits then fades out - LED_MATRIX_SOLID_SPLASH, // Value pulses away from a single key hit then fades out - LED_MATRIX_SOLID_MULTISPLASH, // Value pulses away from multiple key hits then fades out -#endif - LED_MATRIX_WAVE_LEFT_RIGHT // Sine wave scrolling from left to right - LED_MATRIX_WAVE_UP_DOWN // Sine wave scrolling from up to down - LED_MATRIX_EFFECT_MAX -}; -``` - -You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `config.h`: - - -|Define |Description | -|-------------------------------------------------------|----------------------------------------------| -|`#define ENABLE_LED_MATRIX_ALPHAS_MODS` |Enables `LED_MATRIX_ALPHAS_MODS` | -|`#define ENABLE_LED_MATRIX_BREATHING` |Enables `LED_MATRIX_BREATHING` | -|`#define ENABLE_LED_MATRIX_BAND` |Enables `LED_MATRIX_BAND` | -|`#define ENABLE_LED_MATRIX_BAND_PINWHEEL` |Enables `LED_MATRIX_BAND_PINWHEEL` | -|`#define ENABLE_LED_MATRIX_BAND_SPIRAL` |Enables `LED_MATRIX_BAND_SPIRAL` | -|`#define ENABLE_LED_MATRIX_CYCLE_LEFT_RIGHT` |Enables `LED_MATRIX_CYCLE_LEFT_RIGHT` | -|`#define ENABLE_LED_MATRIX_CYCLE_UP_DOWN` |Enables `LED_MATRIX_CYCLE_UP_DOWN` | -|`#define ENABLE_LED_MATRIX_CYCLE_OUT_IN` |Enables `LED_MATRIX_CYCLE_OUT_IN` | -|`#define ENABLE_LED_MATRIX_DUAL_BEACON` |Enables `LED_MATRIX_DUAL_BEACON` | -|`#define ENABLE_LED_MATRIX_WAVE_LEFT_RIGHT` |Enables `LED_MATRIX_WAVE_LEFT_RIGHT` | -|`#define ENABLE_LED_MATRIX_WAVE_UP_DOWN` |Enables `LED_MATRIX_WAVE_UP_DOWN` | - -?> These modes don't require any additional defines. - -|Reactive Defines |Description | -|-------------------------------------------------------|----------------------------------------------| -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE` |Enables `LED_MATRIX_SOLID_REACTIVE_SIMPLE` | -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE` |Enables `LED_MATRIX_SOLID_REACTIVE_WIDE` | -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE` |Enables `LED_MATRIX_SOLID_REACTIVE_MULTIWIDE` | -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS` |Enables `LED_MATRIX_SOLID_REACTIVE_CROSS` | -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS` |Enables `LED_MATRIX_SOLID_REACTIVE_MULTICROSS`| -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS` |Enables `LED_MATRIX_SOLID_REACTIVE_NEXUS` | -|`#define ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS` |Enables `LED_MATRIX_SOLID_REACTIVE_MULTINEXUS`| -|`#define ENABLE_LED_MATRIX_SOLID_SPLASH` |Enables `LED_MATRIX_SOLID_SPLASH` | -|`#define ENABLE_LED_MATRIX_SOLID_MULTISPLASH` |Enables `LED_MATRIX_SOLID_MULTISPLASH` | - -?> These modes also require the `LED_MATRIX_KEYPRESSES` or `LED_MATRIX_KEYRELEASES` define to be available. - -## Custom LED Matrix Effects :id=custom-led-matrix-effects - -By setting `LED_MATRIX_CUSTOM_USER` (and/or `LED_MATRIX_CUSTOM_KB`) in `rules.mk`, new effects can be defined directly from userspace, without having to edit any QMK core files. - -To declare new effects, create a new `led_matrix_user/kb.inc` that looks something like this: - -`led_matrix_user.inc` should go in the root of the keymap directory. -`led_matrix_kb.inc` should go in the root of the keyboard directory. - -To use custom effects in your code, simply prepend `LED_MATRIX_CUSTOM_` to the effect name specified in `LED_MATRIX_EFFECT()`. For example, an effect declared as `LED_MATRIX_EFFECT(my_cool_effect)` would be referenced with: - -```c -led_matrix_mode(led_MATRIX_CUSTOM_my_cool_effect); -``` - -```c -// !!! DO NOT ADD #pragma once !!! // - -// Step 1. -// Declare custom effects using the LED_MATRIX_EFFECT macro -// (note the lack of semicolon after the macro!) -LED_MATRIX_EFFECT(my_cool_effect) -LED_MATRIX_EFFECT(my_cool_effect2) - -// Step 2. -// Define effects inside the `LED_MATRIX_CUSTOM_EFFECT_IMPLS` ifdef block -#ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -// e.g: A simple effect, self-contained within a single method -static bool my_cool_effect(effect_params_t* params) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - for (uint8_t i = led_min; i < led_max; i++) { - led_matrix_set_value(i, 0xFF); - } - return led_matrix_check_finished_leds(led_max); -} - -// e.g: A more complex effect, relying on external methods and state, with -// dedicated init and run methods -static uint8_t some_global_state; -static void my_cool_effect2_complex_init(effect_params_t* params) { - some_global_state = 1; -} -static bool my_cool_effect2_complex_run(effect_params_t* params) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - for (uint8_t i = led_min; i < led_max; i++) { - led_matrix_set_value(i, some_global_state++); - } - return led_matrix_check_finished_leds(led_max); -} -static bool my_cool_effect2(effect_params_t* params) { - if (params->init) my_cool_effect2_complex_init(params); - return my_cool_effect2_complex_run(params); -} - -#endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -``` - -For inspiration and examples, check out the built-in effects under `quantum/led_matrix/animations/`. - - -## Additional `config.h` Options :id=additional-configh-options - -```c -#define LED_MATRIX_KEYPRESSES // reacts to keypresses -#define LED_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) -#define LED_MATRIX_FRAMEBUFFER_EFFECTS // enable framebuffer effects -#define LED_MATRIX_TIMEOUT 0 // number of milliseconds to wait until led automatically turns off -#define LED_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended -#define LED_MATRIX_LED_PROCESS_LIMIT (LED_MATRIX_LED_COUNT + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) -#define LED_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) -#define LED_MATRIX_MAXIMUM_BRIGHTNESS 255 // limits maximum brightness of LEDs -#define LED_MATRIX_DEFAULT_MODE LED_MATRIX_SOLID // Sets the default mode, if none has been set -#define LED_MATRIX_DEFAULT_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set -#define LED_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set -#define LED_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right. - // If LED_MATRIX_KEYPRESSES or LED_MATRIX_KEYRELEASES is enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR -``` - -## EEPROM storage :id=eeprom-storage - -The EEPROM for it is currently shared with the RGB Matrix system (it's generally assumed only one feature would be used at a time). - -### Direct Operation :id=direct-operation -|Function |Description | -|--------------------------------------------|-------------| -|`led_matrix_set_value_all(v)` |Set all of the LEDs to the given value, where `v` is between 0 and 255 (not written to EEPROM) | -|`led_matrix_set_value(index, v)` |Set a single LED to the given value, where `v` is between 0 and 255, and `index` is between 0 and `LED_MATRIX_LED_COUNT` (not written to EEPROM) | - -### Disable/Enable Effects :id=disable-enable-effects -|Function |Description | -|--------------------------------------------|-------------| -|`led_matrix_toggle()` |Toggle effect range LEDs between on and off | -|`led_matrix_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) | -|`led_matrix_enable()` |Turn effect range LEDs on, based on their previous state | -|`led_matrix_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) | -|`led_matrix_disable()` |Turn effect range LEDs off, based on their previous state | -|`led_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) | - -### Change Effect Mode :id=change-effect-mode -|Function |Description | -|--------------------------------------------|-------------| -|`led_matrix_mode(mode)` |Set the mode, if LED animations are enabled | -|`led_matrix_mode_noeeprom(mode)` |Set the mode, if LED animations are enabled (not written to EEPROM) | -|`led_matrix_step()` |Change the mode to the next LED animation in the list of enabled LED animations | -|`led_matrix_step_noeeprom()` |Change the mode to the next LED animation in the list of enabled LED animations (not written to EEPROM) | -|`led_matrix_step_reverse()` |Change the mode to the previous LED animation in the list of enabled LED animations | -|`led_matrix_step_reverse_noeeprom()` |Change the mode to the previous LED animation in the list of enabled LED animations (not written to EEPROM) | -|`led_matrix_increase_speed()` |Increase the speed of the animations | -|`led_matrix_increase_speed_noeeprom()` |Increase the speed of the animations (not written to EEPROM) | -|`led_matrix_decrease_speed()` |Decrease the speed of the animations | -|`led_matrix_decrease_speed_noeeprom()` |Decrease the speed of the animations (not written to EEPROM) | -|`led_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 | -|`led_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) | - -### Change Value :id=change-value -|Function |Description | -|--------------------------------------------|-------------| -|`led_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value | -|`led_matrix_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) | -|`led_matrix_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value | -|`led_matrix_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) | - -### Query Current Status :id=query-current-status -|Function |Description | -|---------------------------------|---------------------------| -|`led_matrix_is_enabled()` |Gets current on/off status | -|`led_matrix_get_mode()` |Gets current mode | -|`led_matrix_get_val()` |Gets current val | -|`led_matrix_get_speed()` |Gets current speed | -|`led_matrix_get_suspend_state()` |Gets current suspend state | - -## Callbacks :id=callbacks - -### Indicators :id=indicators - -If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, you can use the `led_matrix_indicators_kb` or `led_matrix_indicators_user` function for that: -```c -bool led_matrix_indicators_kb(void) { - if (!led_matrix_indicators_user()) { - return false; - } - led_matrix_set_value(index, value); - return true; -} -``` - -In addition, there are the advanced indicator functions. These are aimed at those with heavily customized displays, where rendering every LED per cycle is expensive. This includes a special macro to help make this easier to use: `LED_MATRIX_INDICATOR_SET_VALUE(i, v)`. - -```c -void led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - LED_MATRIX_INDICATOR_SET_VALUE(index, value); - return false; -} -``` diff --git a/docs/feature_macros.md b/docs/feature_macros.md deleted file mode 100644 index 08310555fb77..000000000000 --- a/docs/feature_macros.md +++ /dev/null @@ -1,410 +0,0 @@ -# Macros - -Macros allow you to send multiple keystrokes when pressing just one key. QMK has a number of ways to define and use macros. These can do anything you want: type common phrases for you, copypasta, repetitive game movements, or even help you code. - -!> **Security Note**: While it is possible to use macros to send passwords, credit card numbers, and other sensitive information it is a supremely bad idea to do so. Anyone who gets a hold of your keyboard will be able to access that information by opening a text editor. - -## Using Macros In JSON Keymaps - -You can define up to 32 macros in a `keymap.json` file, as used by [Configurator](newbs_building_firmware_configurator.md), and `qmk compile`. You can define these macros in a list under the `macros` keyword, like this: - -```json -{ - "keyboard": "handwired/my_macropad", - "keymap": "my_keymap", - "macros": [ - [ - {"action":"down", "keycodes": ["LSFT"]}, - "hello world1", - {"action": "up","keycodes": ["LSFT"]} - ], - [ - {"action":"tap", "keycodes": ["LCTL", "LALT", "DEL"]} - ], - [ - "ding!", - {"action":"beep"} - ], - [ - {"action":"tap", "keycodes": ["F1"]}, - {"action":"delay", "duration": "1000"}, - {"action":"tap", "keycodes": ["PGDN"]} - ] - ], - "layout": "LAYOUT_all", - "layers": [ - ["QK_MACRO_0", "QK_MACRO_1", "QK_MACRO_2", "QK_MACRO_3"] - ] -} -``` - -### Selecting Your Host Keyboard Layout - -If you type in a language other than English, or use a non-QWERTY layout like Colemak, Dvorak, or Workman, you may have set your computer's input language to match this layout. This presents a challenge when creating macros - you may need to type different keys to get the same letters! To address this you can add the `host_language` key to your `keymap.json`, like so: - -```json -{ - "keyboard": "handwired/my_macropad", - "keymap": "my_keymap", - "host_language": "dvorak", - "macros": [ - ["Hello, World!"] - ], - "layout": "LAYOUT_all", - "layers": [ - ["QK_MACRO_0"] - ] -} -``` - -The current list of available languages is: - -| belgian | bepo | br_abnt2 | canadian_multilingual | -|:-------:|:----:|:--------:|:---------------------:| -| **colemak** | **croatian** | **czech** | **danish** | -| **dvorak_fr** | **dvorak** | **dvp** | **estonian** | -| **finnish** | **fr_ch** | **french_afnor** | **french** | -| **french_osx** | **german_ch** | **german** | **german_osx** | -| **hungarian** | **icelandic** | **italian** | **italian_osx_ansi** | -| **italian_osx_iso** | **jis** | **latvian** | **lithuanian_azerty** | -| **lithuanian_qwerty** | **norman** | **norwegian** | **portuguese** | -| **portuguese_osx_iso** | **romanian** | **serbian_latin** | **slovak** | -| **slovenian** | **spanish_dvorak** | **spanish** | **swedish** | -| **turkish_f** | **turkish_q** | **uk** | **us_international** | -| **workman** | **workman_zxcvm** | - -### Macro Basics - -Each macro is an array consisting of strings and objects (dictionaries). Strings are typed to your computer while objects allow you to control how your macro is typed out. - -#### Object Format - -All objects have one required key: `action`. This tells QMK what the object does. There are currently 5 actions: beep, delay, down, tap, up - -Only basic keycodes (prefixed by `KC_`) are supported. Do not include the `KC_` prefix when listing keycodes. - -* `beep` - * Play a bell if the keyboard has [audio enabled](feature_audio.md). - * Example: `{"action": "beep"}` -* `delay` - * Pause macro playback. Duration is specified in milliseconds (ms). - * Example: `{"action": "delay", "duration": 500}` -* `down` - * Send a key down event for one or more keycodes. - * Example, single key: `{"action":"down", "keycodes": ["LSFT"]}` - * Example, multiple keys: `{"action":"down", "keycodes": ["CTRL", "LSFT"]}` -* `tap` - * Type a chord, which sends a down event for each key followed by an up event for each key. - * Example, single key: `{"action":"tap", "keycodes": ["F13"]}` - * Example, multiple keys: `{"action":"tap", "keycodes": ["CTRL", "LALT", "DEL"]}` -* `up` - * Send a key up event for one or more keycodes. - * Example, single key: `{"action":"up", "keycodes": ["LSFT"]}` - * Example, multiple keys: `{"action":"up", "keycodes": ["CTRL", "LSFT"]}` - -## Using Macros in C Keymaps - -### `SEND_STRING()` & `process_record_user` - -See also: [Send String](feature_send_string.md) - -Sometimes you want a key to type out words or phrases. For the most common situations, we've provided `SEND_STRING()`, which will type out a string (i.e. a sequence of characters) for you. All ASCII characters that are easily translatable to a keycode are supported (e.g. `qmk 123\n\t`). - -Here is an example `keymap.c` for a two-key keyboard: - -```c -enum custom_keycodes { - QMKBEST = SAFE_RANGE, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QMKBEST: - if (record->event.pressed) { - // when keycode QMKBEST is pressed - SEND_STRING("QMK is the best thing ever!"); - } else { - // when keycode QMKBEST is released - } - break; - } - return true; -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = { - {QMKBEST, KC_ESC}, - // ... - }, -}; -``` - -What happens here is this: -We first define a new custom keycode in the range not occupied by any other keycodes. -Then we use the `process_record_user` function, which is called whenever a key is pressed or released, to check if our custom keycode has been activated. -If yes, we send the string `"QMK is the best thing ever!"` to the computer via the `SEND_STRING` macro (this is a C preprocessor macro, not to be confused with QMK macros). -We return `true` to indicate to the caller that the key press we just processed should continue to be processed as normal (as we didn't replace or alter the functionality). -Finally, we define the keymap so that the first button activates our macro and the second button is just an escape button. - -?>It is recommended to use the SAFE_RANGE macro as per [Customizing Functionality](custom_quantum_functions.md). - -You might want to add more than one macro. -You can do that by adding another keycode and adding another case to the switch statement, like so: - -```c -enum custom_keycodes { - QMKBEST = SAFE_RANGE, - QMKURL, - MY_OTHER_MACRO, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QMKBEST: - if (record->event.pressed) { - // when keycode QMKBEST is pressed - SEND_STRING("QMK is the best thing ever!"); - } else { - // when keycode QMKBEST is released - } - break; - - case QMKURL: - if (record->event.pressed) { - // when keycode QMKURL is pressed - SEND_STRING("https://qmk.fm/\n"); - } else { - // when keycode QMKURL is released - } - break; - - case MY_OTHER_MACRO: - if (record->event.pressed) { - SEND_STRING(SS_LCTL("ac")); // selects all and copies - } - break; - } - return true; -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = { - {MY_CUSTOM_MACRO, MY_OTHER_MACRO}, - // ... - }, -}; -``` - -?> An enumerated list of custom keycodes (`enum custom_keycodes`) must be declared before `keymaps[]` array, `process_record_user()` and any other function that use the list for the compiler to recognise it. - -#### Advanced Macros - -In addition to the `process_record_user()` function, is the `post_process_record_user()` function. This runs after `process_record` and can be used to do things after a keystroke has been sent. This is useful if you want to have a key pressed before and released after a normal key, for instance. - -In this example, we modify most normal keypresses so that `F22` is pressed before the keystroke is normally sent, and release it __only after__ it's been released. - -```c -static uint8_t f22_tracker; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_A ... KC_F21: //notice how it skips over F22 - case KC_F23 ... KC_EXSEL: //exsel is the last one before the modifier keys - if (record->event.pressed) { - register_code(KC_F22); //this means to send F22 down - f22_tracker++; - register_code(keycode); - return false; - } - break; - } - return true; -} - -void post_process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_A ... KC_F21: //notice how it skips over F22 - case KC_F23 ... KC_EXSL: //exsel is the last one before the modifier keys - if (!record->event.pressed) { - f22_tracker--; - if (!f22_tracker) { - unregister_code(KC_F22); //this means to send F22 up - } - } - break; - } -} -``` - - -#### TAP, DOWN and UP - -You may want to use keys in your macros that you can't write down, such as `Ctrl` or `Home`. -You can send arbitrary keycodes by wrapping them in: - -* `SS_TAP()` presses and releases a key. -* `SS_DOWN()` presses (but does not release) a key. -* `SS_UP()` releases a key. - -For example: - - SEND_STRING(SS_TAP(X_HOME)); - -Would tap `KC_HOME` - note how the prefix is now `X_`, and not `KC_`. You can also combine this with other strings, like this: - - SEND_STRING("VE"SS_TAP(X_HOME)"LO"); - -Which would send "VE" followed by a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline). - -Delays can be also added to the string: - -* `SS_DELAY(msecs)` will delay for the specified number of milliseconds. - -For example: - - SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO"); - -Which would send "VE" followed by a 1-second delay, then a `KC_HOME` tap, and "LO" (spelling "LOVE" if on a newline, but delayed in the middle). - -There's also a couple of mod shortcuts you can use: - -* `SS_LCTL(string)` -* `SS_LSFT(string)` -* `SS_LALT(string)` or `SS_LOPT(string)` -* `SS_LGUI(string)`, `SS_LCMD(string)` or `SS_LWIN(string)` -* `SS_RCTL(string)` -* `SS_RSFT(string)` -* `SS_RALT(string)`, `SS_ROPT(string)` or `SS_ALGR(string)` -* `SS_RGUI(string)`, `SS_RCMD(string)` or `SS_RWIN(string)` - -These press the respective modifier, send the supplied string and then release the modifier. -They can be used like this: - - SEND_STRING(SS_LCTL("a")); - -Which would send Left Control+`a` (Left Control down, `a`, Left Control up) - notice that they take strings (eg `"k"`), and not the `X_K` keycodes. - -#### Alternative Keymaps - -By default, it assumes a US keymap with a QWERTY layout; if you want to change that (e.g. if your OS uses software Colemak), include this somewhere in your keymap: - -```c -#include "sendstring_colemak.h" -``` - -#### Strings in Memory - -If for some reason you're manipulating strings and need to print out something you just generated (instead of being a literal, constant string), you can use `send_string()`, like this: - -```c -char my_str[4] = "ok."; -send_string(my_str); -``` - -The shortcuts defined above won't work with `send_string()`, but you can separate things out to different lines if needed: - -```c -char my_str[4] = "ok."; -SEND_STRING("I said: "); -send_string(my_str); -SEND_STRING(".."SS_TAP(X_END)); -``` - - -### Advanced Macro Functions - -There are some functions you may find useful in macro-writing. Keep in mind that while you can write some fairly advanced code within a macro, if your functionality gets too complex you may want to define a custom keycode instead. Macros are meant to be simple. - -?> You can also use the functions described in [Useful function](ref_functions.md) and [Checking modifier state](feature_advanced_keycodes#checking-modifier-state) for additional functionality. For example, `reset_keyboard()` allows you to reset the keyboard as part of a macro and `get_mods() & MOD_MASK_SHIFT` lets you check for the existence of active shift modifiers. - -#### `record->event.pressed` - -This is a boolean value that can be tested to see if the switch is being pressed or released. An example of this is - -```c - if (record->event.pressed) { - // on keydown - } else { - // on keyup - } -``` - -#### `register_code();` - -This sends the `` keydown event to the computer. Some examples would be `KC_ESC`, `KC_C`, `KC_4`, and even modifiers such as `KC_LSFT` and `KC_LGUI`. - -#### `unregister_code();` - -Parallel to `register_code` function, this sends the `` keyup event to the computer. If you don't use this, the key will be held down until it's sent. - -#### `tap_code();` - -Sends `register_code()` and then `unregister_code()`. This is useful if you want to send both the press and release events ("tap" the key, rather than hold it). - -If `TAP_CODE_DELAY` is defined (default 0), this function waits that many milliseconds before calling `unregister_code()`. This can be useful when you are having issues with taps (un)registering. - -If the keycode is `KC_CAPS`, it waits `TAP_HOLD_CAPS_DELAY` milliseconds instead (default 80), as macOS prevents accidental Caps Lock activation by waiting for the key to be held for a certain amount of time. - -#### `tap_code_delay(, );` - -Like `tap_code()`, but with a `delay` parameter for specifying arbitrary intervals before sending the unregister event. - -#### `register_code16();`, `unregister_code16();`, `tap_code16();` and `tap_code16_delay(, );` - -These functions work similar to their regular counterparts, but allow you to use modded keycodes (with Shift, Alt, Control, and/or GUI applied to them). - -Eg, you could use `register_code16(S(KC_5));` instead of registering the mod, then registering the keycode. - -#### `clear_keyboard();` - -This will clear all mods and keys currently pressed. - -#### `clear_mods();` - -This will clear all mods currently pressed. - -#### `clear_keyboard_but_mods();` - -This will clear all keys besides the mods currently pressed. - -### Advanced Example: - -#### Super ALT↯TAB - -This macro will register `KC_LALT` and tap `KC_TAB`, then wait for 1000ms. If the key is tapped again, it will send another `KC_TAB`; if there is no tap, `KC_LALT` will be unregistered, thus allowing you to cycle through windows. - -```c -bool is_alt_tab_active = false; // ADD this near the beginning of keymap.c -uint16_t alt_tab_timer = 0; // we will be using them soon. - -enum custom_keycodes { // Make sure have the awesome keycode ready - ALT_TAB = SAFE_RANGE, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { // This will do most of the grunt work with the keycodes. - case ALT_TAB: - if (record->event.pressed) { - if (!is_alt_tab_active) { - is_alt_tab_active = true; - register_code(KC_LALT); - } - alt_tab_timer = timer_read(); - register_code(KC_TAB); - } else { - unregister_code(KC_TAB); - } - break; - } - return true; -} - -void matrix_scan_user(void) { // The very important timer. - if (is_alt_tab_active) { - if (timer_elapsed(alt_tab_timer) > 1000) { - unregister_code(KC_LALT); - is_alt_tab_active = false; - } - } -} -``` diff --git a/docs/feature_midi.md b/docs/feature_midi.md deleted file mode 100644 index 59ee0114c8bd..000000000000 --- a/docs/feature_midi.md +++ /dev/null @@ -1,264 +0,0 @@ -# MIDI - -## Usage - -First, enable MIDI by adding the following to your `rules.mk`: - -```make -MIDI_ENABLE = yes -``` - -There are two MIDI systems in QMK: basic and advanced. With basic MIDI you will only be able to send Note On and Note Off messages using the note keycodes, meaning that keycodes like `MI_OCTU` and `MI_OCTD` will not work. Advanced MIDI allows you to do things like octave shifts, channel changes, velocity changes, modulation, and more. - -### Caveats - -MIDI requires 2 USB endpoints and as such may not work on some hardware such as V-USB controllers. - -### Basic MIDI - -To enable basic MIDI, add the following to your `config.h`: - -```c -#define MIDI_BASIC -``` - -### Advanced MIDI - -To enable advanced MIDI, add the following to your `config.h`: - -```c -#define MIDI_ADVANCED -``` - -#### Sending Control Change (CC) Messages - -If you're aiming to emulate the features of something like a Launchpad or other MIDI controller you'll need to access the internal MIDI device directly. - -Because there are so many possible CC messages, not all of them are implemented as keycodes. Additionally, you might need to provide more than just two values that you would get from a keycode (pressed and released) - for example, the analog values from a fader or a potentiometer. So, you will need to implement [custom keycodes](feature_macros.md) if you want to use them in your keymap directly using `process_record_user()`. - - -For reference of all the possible control code numbers see [MIDI Specification](#midi-specification) - -#### Example code for using Generic On Off Switches as per MIDI Specification. -```c -#include QMK_KEYBOARD_H - -extern MidiDevice midi_device; - -// MIDI CC codes for generic on/off switches (80, 81, 82, 83) -// Off: 0-63 -// On: 64-127 - -#define MIDI_CC_OFF 0 -#define MIDI_CC_ON 127 - -enum custom_keycodes { - MIDI_CC80 = SAFE_RANGE, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case MIDI_CC80: - if (record->event.pressed) { - midi_send_cc(&midi_device, midi_config.channel, 80, MIDI_CC_ON); - } else { - midi_send_cc(&midi_device, midi_config.channel, 80, MIDI_CC_OFF); - } - return true; - } - return true; -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - LAYOUT( - // ... - MIDI_CC80, - // ... - ) -}; -``` - -### Keycodes - -|Keycode |Aliases |Description | -|-------------------------------|------------------|---------------------------------| -|`QK_MIDI_ON` |`MI_ON` |Turn MIDI on | -|`QK_MIDI_OFF` |`MI_OFF` |Turn MIDI off | -|`QK_MIDI_TOGGLE` |`MI_TOGG` |Toggle MIDI enabled | -|`QK_MIDI_NOTE_C_0` |`MI_C` |C octave 0 | -|`QK_MIDI_NOTE_C_SHARP_0` |`MI_Cs`, `MI_Db` |C♯/D♭ octave 0 | -|`QK_MIDI_NOTE_D_0` |`MI_D` |D octave 0 | -|`QK_MIDI_NOTE_D_SHARP_0` |`MI_Ds`, `MI_Eb` |D♯/E♭ octave 0 | -|`QK_MIDI_NOTE_E_0` |`MI_E` |E octave 0 | -|`QK_MIDI_NOTE_F_0` |`MI_F` |F octave 0 | -|`QK_MIDI_NOTE_F_SHARP_0` |`MI_Fs`, `MI_Gb` |F♯/G♭ octave 0 | -|`QK_MIDI_NOTE_G_0` |`MI_G` |G octave 0 | -|`QK_MIDI_NOTE_G_SHARP_0` |`MI_Gs`, `MI_Ab` |G♯/A♭ octave 0 | -|`QK_MIDI_NOTE_A_0` |`MI_A` |A octave 0 | -|`QK_MIDI_NOTE_A_SHARP_0` |`MI_As`, `MI_Bb` |A♯/B♭ octave 0 | -|`QK_MIDI_NOTE_B_0` |`MI_B` |B octave 0 | -|`QK_MIDI_NOTE_C_1` |`MI_C1` |C octave 1 | -|`QK_MIDI_NOTE_C_SHARP_1` |`MI_Cs1`, `MI_Db1`|C♯/D♭ octave 1 | -|`QK_MIDI_NOTE_D_1` |`MI_D1` |D octave 1 | -|`QK_MIDI_NOTE_D_SHARP_1` |`MI_Ds1`, `MI_Eb1`|D♯/E♭ octave 1 | -|`QK_MIDI_NOTE_E_1` |`MI_E1` |E octave 1 | -|`QK_MIDI_NOTE_F_1` |`MI_F1` |F octave 1 | -|`QK_MIDI_NOTE_F_SHARP_1` |`MI_Fs1`, `MI_Gb1`|F♯/G♭ octave 1 | -|`QK_MIDI_NOTE_G_1` |`MI_G1` |G octave 1 | -|`QK_MIDI_NOTE_G_SHARP_1` |`MI_Gs1`, `MI_Ab1`|G♯/A♭ octave 1 | -|`QK_MIDI_NOTE_A_1` |`MI_A1` |A octave 1 | -|`QK_MIDI_NOTE_A_SHARP_1` |`MI_As1`, `MI_Bb1`|A♯/B♭ octave 1 | -|`QK_MIDI_NOTE_B_1` |`MI_B1` |B octave 1 | -|`QK_MIDI_NOTE_C_2` |`MI_C2` |C octave 2 | -|`QK_MIDI_NOTE_C_SHARP_2` |`MI_Cs2`, `MI_Db2`|C♯/D♭ octave 2 | -|`QK_MIDI_NOTE_D_2` |`MI_D2` |D octave 2 | -|`QK_MIDI_NOTE_D_SHARP_2` |`MI_Ds2`, `MI_Eb2`|D♯/E♭ octave 2 | -|`QK_MIDI_NOTE_E_2` |`MI_E2` |E octave 2 | -|`QK_MIDI_NOTE_F_2` |`MI_F2` |F octave 2 | -|`QK_MIDI_NOTE_F_SHARP_2` |`MI_Fs2`, `MI_Gb2`|F♯/G♭ octave 2 | -|`QK_MIDI_NOTE_G_2` |`MI_G2` |G octave 2 | -|`QK_MIDI_NOTE_G_SHARP_2` |`MI_Gs2`, `MI_Ab2`|G♯/A♭ octave 2 | -|`QK_MIDI_NOTE_A_2` |`MI_A2` |A octave 2 | -|`QK_MIDI_NOTE_A_SHARP_2` |`MI_As2`, `MI_Bb2`|A♯/B♭ octave 2 | -|`QK_MIDI_NOTE_B_2` |`MI_B2` |B octave 2 | -|`QK_MIDI_NOTE_C_3` |`MI_C3` |C octave 3 | -|`QK_MIDI_NOTE_C_SHARP_3` |`MI_Cs3`, `MI_Db3`|C♯/D♭ octave 3 | -|`QK_MIDI_NOTE_D_3` |`MI_D3` |D octave 3 | -|`QK_MIDI_NOTE_D_SHARP_3` |`MI_Ds3`, `MI_Eb3`|D♯/E♭ octave 3 | -|`QK_MIDI_NOTE_E_3` |`MI_E3` |E octave 3 | -|`QK_MIDI_NOTE_F_3` |`MI_F3` |F octave 3 | -|`QK_MIDI_NOTE_F_SHARP_3` |`MI_Fs3`, `MI_Gb3`|F♯/G♭ octave 3 | -|`QK_MIDI_NOTE_G_3` |`MI_G3` |G octave 3 | -|`QK_MIDI_NOTE_G_SHARP_3` |`MI_Gs3`, `MI_Ab3`|G♯/A♭ octave 3 | -|`QK_MIDI_NOTE_A_3` |`MI_A3` |A octave 3 | -|`QK_MIDI_NOTE_A_SHARP_3` |`MI_As3`, `MI_Bb3`|A♯/B♭ octave 3 | -|`QK_MIDI_NOTE_B_3` |`MI_B3` |B octave 3 | -|`QK_MIDI_NOTE_C_4` |`MI_C4` |C octave 4 | -|`QK_MIDI_NOTE_C_SHARP_4` |`MI_Cs4`, `MI_Db4`|C♯/D♭ octave 4 | -|`QK_MIDI_NOTE_D_4` |`MI_D4` |D octave 4 | -|`QK_MIDI_NOTE_D_SHARP_4` |`MI_Ds4`, `MI_Eb4`|D♯/E♭ octave 4 | -|`QK_MIDI_NOTE_E_4` |`MI_E4` |E octave 4 | -|`QK_MIDI_NOTE_F_4` |`MI_F4` |F octave 4 | -|`QK_MIDI_NOTE_F_SHARP_4` |`MI_Fs4`, `MI_Gb4`|F♯/G♭ octave 4 | -|`QK_MIDI_NOTE_G_4` |`MI_G4` |G octave 4 | -|`QK_MIDI_NOTE_G_SHARP_4` |`MI_Gs4`, `MI_Ab4`|G♯/A♭ octave 4 | -|`QK_MIDI_NOTE_A_4` |`MI_A4` |A octave 4 | -|`QK_MIDI_NOTE_A_SHARP_4` |`MI_As4`, `MI_Bb4`|A♯/B♭ octave 4 | -|`QK_MIDI_NOTE_B_4` |`MI_B4` |B octave 4 | -|`QK_MIDI_NOTE_C_5` |`MI_C5` |C octave 5 | -|`QK_MIDI_NOTE_C_SHARP_5` |`MI_Cs5`, `MI_Db5`|C♯/D♭ octave 5 | -|`QK_MIDI_NOTE_D_5` |`MI_D5` |D octave 5 | -|`QK_MIDI_NOTE_D_SHARP_5` |`MI_Ds5`, `MI_Eb5`|D♯/E♭ octave 5 | -|`QK_MIDI_NOTE_E_5` |`MI_E5` |E octave 5 | -|`QK_MIDI_NOTE_F_5` |`MI_F5` |F octave 5 | -|`QK_MIDI_NOTE_F_SHARP_5` |`MI_Fs5`, `MI_Gb5`|F♯/G♭ octave 5 | -|`QK_MIDI_NOTE_G_5` |`MI_G5` |G octave 5 | -|`QK_MIDI_NOTE_G_SHARP_5` |`MI_Gs5`, `MI_Ab5`|G♯/A♭ octave 5 | -|`QK_MIDI_NOTE_A_5` |`MI_A5` |A octave 5 | -|`QK_MIDI_NOTE_A_SHARP_5` |`MI_As5`, `MI_Bb5`|A♯/B♭ octave 5 | -|`QK_MIDI_NOTE_B_5` |`MI_B5` |B octave 5 | -|`QK_MIDI_OCTAVE_N2` |`MI_OCN2` |Set octave to -2 | -|`QK_MIDI_OCTAVE_N1` |`MI_OCN1` |Set octave to -1 | -|`QK_MIDI_OCTAVE_0` |`MI_OC0` |Set octave to 0 | -|`QK_MIDI_OCTAVE_1` |`MI_OC1` |Set octave to 1 | -|`QK_MIDI_OCTAVE_2` |`MI_OC2` |Set octave to 2 | -|`QK_MIDI_OCTAVE_3` |`MI_OC3` |Set octave to 3 | -|`QK_MIDI_OCTAVE_4` |`MI_OC4` |Set octave to 4 | -|`QK_MIDI_OCTAVE_5` |`MI_OC5` |Set octave to 5 | -|`QK_MIDI_OCTAVE_6` |`MI_OC6` |Set octave to 6 | -|`QK_MIDI_OCTAVE_7` |`MI_OC7` |Set octave to 7 | -|`QK_MIDI_OCTAVE_DOWN` |`MI_OCTD` |Move down an octave | -|`QK_MIDI_OCTAVE_UP` |`MI_OCTU` |Move up an octave | -|`QK_MIDI_TRANSPOSE_N6` |`MI_TRN6` |Set transposition to -6 semitones| -|`QK_MIDI_TRANSPOSE_N5` |`MI_TRN5` |Set transposition to -5 semitones| -|`QK_MIDI_TRANSPOSE_N4` |`MI_TRN4` |Set transposition to -4 semitones| -|`QK_MIDI_TRANSPOSE_N3` |`MI_TRN3` |Set transposition to -3 semitones| -|`QK_MIDI_TRANSPOSE_N2` |`MI_TRN2` |Set transposition to -2 semitones| -|`QK_MIDI_TRANSPOSE_N1` |`MI_TRN1` |Set transposition to -1 semitone | -|`QK_MIDI_TRANSPOSE_0` |`MI_TR0` |No transposition | -|`QK_MIDI_TRANSPOSE_1` |`MI_TR1` |Set transposition to +1 semitone | -|`QK_MIDI_TRANSPOSE_2` |`MI_TR2` |Set transposition to +2 semitones| -|`QK_MIDI_TRANSPOSE_3` |`MI_TR3` |Set transposition to +3 semitones| -|`QK_MIDI_TRANSPOSE_4` |`MI_TR4` |Set transposition to +4 semitones| -|`QK_MIDI_TRANSPOSE_5` |`MI_TR5` |Set transposition to +5 semitones| -|`QK_MIDI_TRANSPOSE_6` |`MI_TR6` |Set transposition to +6 semitones| -|`QK_MIDI_TRANSPOSE_DOWN` |`MI_TRSD` |Decrease transposition | -|`QK_MIDI_TRANSPOSE_UP` |`MI_TRSU` |Increase transposition | -|`QK_MIDI_VELOCITY_0` |`MI_VL0` |Set velocity to 0 | -|`QK_MIDI_VELOCITY_1` |`MI_VL1` |Set velocity to 12 | -|`QK_MIDI_VELOCITY_2` |`MI_VL2` |Set velocity to 25 | -|`QK_MIDI_VELOCITY_3` |`MI_VL3` |Set velocity to 38 | -|`QK_MIDI_VELOCITY_4` |`MI_VL4` |Set velocity to 51 | -|`QK_MIDI_VELOCITY_5` |`MI_VL5` |Set velocity to 64 | -|`QK_MIDI_VELOCITY_6` |`MI_VL6` |Set velocity to 76 | -|`QK_MIDI_VELOCITY_7` |`MI_VL7` |Set velocity to 89 | -|`QK_MIDI_VELOCITY_8` |`MI_VL8` |Set velocity to 102 | -|`QK_MIDI_VELOCITY_9` |`MI_VL9` |Set velocity to 114 | -|`QK_MIDI_VELOCITY_10` |`MI_VL10` |Set velocity to 127 | -|`QK_MIDI_VELOCITY_DOWN` |`MI_VELD` |Decrease velocity | -|`QK_MIDI_VELOCITY_UP` |`MI_VELU` |Increase velocity | -|`QK_MIDI_CHANNEL_1` |`MI_CH1` |Set channel to 1 | -|`QK_MIDI_CHANNEL_2` |`MI_CH2` |Set channel to 2 | -|`QK_MIDI_CHANNEL_3` |`MI_CH3` |Set channel to 3 | -|`QK_MIDI_CHANNEL_4` |`MI_CH4` |Set channel to 4 | -|`QK_MIDI_CHANNEL_5` |`MI_CH5` |Set channel to 5 | -|`QK_MIDI_CHANNEL_6` |`MI_CH6` |Set channel to 6 | -|`QK_MIDI_CHANNEL_7` |`MI_CH7` |Set channel to 7 | -|`QK_MIDI_CHANNEL_8` |`MI_CH8` |Set channel to 8 | -|`QK_MIDI_CHANNEL_9` |`MI_CH9` |Set channel to 9 | -|`QK_MIDI_CHANNEL_10` |`MI_CH10` |Set channel to 10 | -|`QK_MIDI_CHANNEL_11` |`MI_CH11` |Set channel to 11 | -|`QK_MIDI_CHANNEL_12` |`MI_CH12` |Set channel to 12 | -|`QK_MIDI_CHANNEL_13` |`MI_CH13` |Set channel to 13 | -|`QK_MIDI_CHANNEL_14` |`MI_CH14` |Set channel to 14 | -|`QK_MIDI_CHANNEL_15` |`MI_CH15` |Set channel to 15 | -|`QK_MIDI_CHANNEL_16` |`MI_CH16` |Set channel to 16 | -|`QK_MIDI_CHANNEL_DOWN` |`MI_CHND` |Decrease channel | -|`QK_MIDI_CHANNEL_UP` |`MI_CHNU` |Increase channel | -|`QK_MIDI_ALL_NOTES_OFF` |`MI_AOFF` |Stop all notes | -|`QK_MIDI_SUSTAIN` |`MI_SUST` |Sustain | -|`QK_MIDI_PORTAMENTO` |`MI_PORT` |Portmento | -|`QK_MIDI_SOSTENUTO` |`MI_SOST` |Sostenuto | -|`QK_MIDI_SOFT` |`MI_SOFT` |Soft Pedal | -|`QK_MIDI_LEGATO` |`MI_LEG` |Legato | -|`QK_MIDI_MODULATION` |`MI_MOD` |Modulation | -|`QK_MIDI_MODULATION_SPEED_DOWN`|`MI_MODD` |Decrease modulation speed | -|`QK_MIDI_MODULATION_SPEED_UP` |`MI_MODU` |Increase modulation speed | -|`QK_MIDI_PITCH_BEND_DOWN` |`MI_BNDD` |Bend pitch down | -|`QK_MIDI_PITCH_BEND_UP` |`MI_BNDU` |Bend pitch up | - -### Configuration - -Certain values are stored in the `midi_config` struct. This configuration is not persisted to EEPROM. By default, these values are: - -|Configuration |Value|Comments | -|-------------------|-----|-----------------------| -|Octave |`4` |Corresponds to `MI_OC2`| -|Transposition |`0` | | -|Velocity |`127`| | -|Channel |`0` | | -|Modulation Interval|`8` | | - -For the above, the `MI_C` keycode will produce a C3 (note number 48), and so on. - -### References -#### MIDI Specification - - * [MIDI.org](https://www.midi.org/specifications-old/item/table-1-summary-of-midi-message) - * [CMU MIDI Programmer's Reference](https://www.cs.cmu.edu/~music/cmsip/readings/MIDI%20tutorial%20for%20programmers.html) -#### QMK C Files - - * `quantum/process_keycode/process_midi.c` - * `quantum/quantum_keycodes.h` - * `quantum/midi/midi.h` - * `quantum/midi/midi.c` - * `quantum/midi/qmk_midi.c` - * `quantum/midi/midi_device.h` - - diff --git a/docs/feature_mouse_keys.md b/docs/feature_mouse_keys.md deleted file mode 100644 index eed4f4f4aaaf..000000000000 --- a/docs/feature_mouse_keys.md +++ /dev/null @@ -1,207 +0,0 @@ -# Mouse keys - -Mouse keys is a feature that allows you to emulate a mouse using your keyboard. You can move the pointer at different speeds, press 5 buttons and scroll in 8 directions. - -## Adding mouse keys to your keyboard - -To use mouse keys, you must at least enable mouse keys support and map mouse actions to keys on your keyboard. - -### Enabling mouse keys - -To enable mouse keys, add the following line to your keymap’s `rules.mk`: - -```c -MOUSEKEY_ENABLE = yes -``` - -### Mapping mouse actions - -In your keymap you can use the following keycodes to map key presses to mouse actions: - -|Key |Aliases |Description | -|----------------|---------|-----------------| -|`KC_MS_UP` |`KC_MS_U`|Move cursor up | -|`KC_MS_DOWN` |`KC_MS_D`|Move cursor down | -|`KC_MS_LEFT` |`KC_MS_L`|Move cursor left | -|`KC_MS_RIGHT` |`KC_MS_R`|Move cursor right| -|`KC_MS_BTN1` |`KC_BTN1`|Press button 1 | -|`KC_MS_BTN2` |`KC_BTN2`|Press button 2 | -|`KC_MS_BTN3` |`KC_BTN3`|Press button 3 | -|`KC_MS_BTN4` |`KC_BTN4`|Press button 4 | -|`KC_MS_BTN5` |`KC_BTN5`|Press button 5 | -|`KC_MS_BTN6` |`KC_BTN6`|Press button 6 | -|`KC_MS_BTN7` |`KC_BTN7`|Press button 7 | -|`KC_MS_BTN8` |`KC_BTN8`|Press button 8 | -|`KC_MS_WH_UP` |`KC_WH_U`|Move wheel up | -|`KC_MS_WH_DOWN` |`KC_WH_D`|Move wheel down | -|`KC_MS_WH_LEFT` |`KC_WH_L`|Move wheel left | -|`KC_MS_WH_RIGHT`|`KC_WH_R`|Move wheel right | -|`KC_MS_ACCEL0` |`KC_ACL0`|Set speed to 0 | -|`KC_MS_ACCEL1` |`KC_ACL1`|Set speed to 1 | -|`KC_MS_ACCEL2` |`KC_ACL2`|Set speed to 2 | - -## Configuring mouse keys - -Mouse keys supports three different modes to move the cursor: - -* **Accelerated (default):** Holding movement keys accelerates the cursor until it reaches its maximum speed. -* **Kinetic:** Holding movement keys accelerates the cursor with its speed following a quadratic curve until it reaches its maximum speed. -* **Constant:** Holding movement keys moves the cursor at constant speeds. -* **Combined:** Holding movement keys accelerates the cursor until it reaches its maximum speed, but holding acceleration and movement keys simultaneously moves the cursor at constant speeds. -* **Inertia:** Cursor accelerates when key held, and decelerates after key release. Tracks X and Y velocity separately for more nuanced movements. Applies to cursor only, not scrolling. - -The same principle applies to scrolling, in most modes. - -Configuration options that are times, intervals or delays are given in milliseconds. Scroll speed is given as multiples of the default scroll step. For example, a scroll speed of 8 means that each scroll action covers 8 times the length of the default scroll step as defined by your operating system or application. - -### Accelerated mode - -This is the default mode. You can adjust the cursor and scrolling acceleration using the following settings in your keymap’s `config.h` file: - -|Define |Default|Description | -|----------------------------|-------|---------------------------------------------------------| -|`MOUSEKEY_DELAY` |10 |Delay between pressing a movement key and cursor movement| -|`MOUSEKEY_INTERVAL` |20 |Time between cursor movements in milliseconds | -|`MOUSEKEY_MOVE_DELTA` |8 |Step size | -|`MOUSEKEY_MAX_SPEED` |10 |Maximum cursor speed at which acceleration stops | -|`MOUSEKEY_TIME_TO_MAX` |30 |Time until maximum cursor speed is reached | -|`MOUSEKEY_WHEEL_DELAY` |10 |Delay between pressing a wheel key and wheel movement | -|`MOUSEKEY_WHEEL_INTERVAL` |80 |Time between wheel movements | -|`MOUSEKEY_WHEEL_MAX_SPEED` |8 |Maximum number of scroll steps per scroll action | -|`MOUSEKEY_WHEEL_TIME_TO_MAX`|40 |Time until maximum scroll speed is reached | - -Tips: - -* Setting `MOUSEKEY_DELAY` too low makes the cursor unresponsive. Setting it too high makes small movements difficult. -* For smoother cursor movements, lower the value of `MOUSEKEY_INTERVAL`. If the refresh rate of your display is 60Hz, you could set it to `16` (1/60). As this raises the cursor speed significantly, you may want to lower `MOUSEKEY_MAX_SPEED`. -* Setting `MOUSEKEY_TIME_TO_MAX` or `MOUSEKEY_WHEEL_TIME_TO_MAX` to `0` will disable acceleration for the cursor or scrolling respectively. This way you can make one of them constant while keeping the other accelerated, which is not possible in constant speed mode. -* Setting `MOUSEKEY_WHEEL_INTERVAL` too low will make scrolling too fast. Setting it too high will make scrolling too slow when the wheel key is held down. - -Cursor acceleration uses the same algorithm as the X Window System MouseKeysAccel feature. You can read more about it [on Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys). - -### Kinetic Mode - -This is an extension of the accelerated mode. The kinetic mode uses a quadratic curve on the cursor speed which allows precise movements at the beginning and allows to cover large distances by increasing cursor speed quickly thereafter. You can adjust the cursor and scrolling acceleration using the following settings in your keymap’s `config.h` file: - -|Define |Default |Description | -|--------------------------------------|---------|---------------------------------------------------------------| -|`MK_KINETIC_SPEED` |undefined|Enable kinetic mode | -|`MOUSEKEY_DELAY` |5 |Delay between pressing a movement key and cursor movement | -|`MOUSEKEY_INTERVAL` |10 |Time between cursor movements in milliseconds | -|`MOUSEKEY_MOVE_DELTA` |16 |Step size for accelerating from initial to base speed | -|`MOUSEKEY_INITIAL_SPEED` |100 |Initial speed of the cursor in pixel per second | -|`MOUSEKEY_BASE_SPEED` |5000 |Maximum cursor speed at which acceleration stops | -|`MOUSEKEY_DECELERATED_SPEED` |400 |Decelerated cursor speed | -|`MOUSEKEY_ACCELERATED_SPEED` |3000 |Accelerated cursor speed | -|`MOUSEKEY_WHEEL_INITIAL_MOVEMENTS` |16 |Initial number of movements of the mouse wheel | -|`MOUSEKEY_WHEEL_BASE_MOVEMENTS` |32 |Maximum number of movements at which acceleration stops | -|`MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS`|48 |Accelerated wheel movements | -|`MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS`|8 |Decelerated wheel movements | - -Tips: - -* The smoothness of the cursor movement depends on the `MOUSEKEY_INTERVAL` setting. The shorter the interval is set the smoother the movement will be. Setting the value too low makes the cursor unresponsive. Lower settings are possible if the micro processor is fast enough. For example: At an interval of `8` milliseconds, `125` movements per second will be initiated. With a base speed of `1000` each movement will move the cursor by `8` pixels. -* Mouse wheel movements are implemented differently from cursor movements. While it's okay for the cursor to move multiple pixels at once for the mouse wheel this would lead to jerky movements. Instead, the mouse wheel operates at step size `2`. Setting mouse wheel speed is done by adjusting the number of wheel movements per second. - -### Constant mode - -In this mode you can define multiple different speeds for both the cursor and the mouse wheel. There is no acceleration. `KC_ACL0`, `KC_ACL1` and `KC_ACL2` change the cursor and scroll speed to their respective setting. - -You can choose whether speed selection is momentary or tap-to-select: - -* **Momentary:** The chosen speed is only active while you hold the respective key. When the key is raised, mouse keys returns to the unmodified speed. -* **Tap-to-select:** The chosen speed is activated when you press the respective key and remains active even after the key has been raised. The default speed is that of `KC_ACL1`. There is no unmodified speed. - -The default speeds from slowest to fastest are as follows: - -* **Momentary:** `KC_ACL0` < `KC_ACL1` < *unmodified* < `KC_ACL2` -* **Tap-to-select:** `KC_ACL0` < `KC_ACL1` < `KC_ACL2` - -To use constant speed mode, you must at least define `MK_3_SPEED` in your keymap’s `config.h` file: - -```c -#define MK_3_SPEED -``` - -To enable momentary mode, also define `MK_MOMENTARY_ACCEL`: - -```c -#define MK_MOMENTARY_ACCEL -``` - -Use the following settings if you want to adjust cursor movement or scrolling: - -|Define |Default |Description | -|---------------------|-------------|-------------------------------------------| -|`MK_3_SPEED` |*Not defined*|Enable constant cursor speeds | -|`MK_MOMENTARY_ACCEL` |*Not defined*|Enable momentary speed selection | -|`MK_C_OFFSET_UNMOD` |16 |Cursor offset per movement (unmodified) | -|`MK_C_INTERVAL_UNMOD`|16 |Time between cursor movements (unmodified) | -|`MK_C_OFFSET_0` |1 |Cursor offset per movement (`KC_ACL0`) | -|`MK_C_INTERVAL_0` |32 |Time between cursor movements (`KC_ACL0`) | -|`MK_C_OFFSET_1` |4 |Cursor offset per movement (`KC_ACL1`) | -|`MK_C_INTERVAL_1` |16 |Time between cursor movements (`KC_ACL1`) | -|`MK_C_OFFSET_2` |32 |Cursor offset per movement (`KC_ACL2`) | -|`MK_C_INTERVAL_2` |16 |Time between cursor movements (`KC_ACL2`) | -|`MK_W_OFFSET_UNMOD` |1 |Scroll steps per scroll action (unmodified)| -|`MK_W_INTERVAL_UNMOD`|40 |Time between scroll steps (unmodified) | -|`MK_W_OFFSET_0` |1 |Scroll steps per scroll action (`KC_ACL0`) | -|`MK_W_INTERVAL_0` |360 |Time between scroll steps (`KC_ACL0`) | -|`MK_W_OFFSET_1` |1 |Scroll steps per scroll action (`KC_ACL1`) | -|`MK_W_INTERVAL_1` |120 |Time between scroll steps (`KC_ACL1`) | -|`MK_W_OFFSET_2` |1 |Scroll steps per scroll action (`KC_ACL2`) | -|`MK_W_INTERVAL_2` |20 |Time between scroll steps (`KC_ACL2`) | - -### Combined mode - -This mode functions like **Accelerated** mode, however, you can hold `KC_ACL0`, `KC_ACL1` and `KC_ACL2` -to momentarily (while held) set the cursor and scroll speeds to constant speeds. When no acceleration -keys are held, this mode is identical to **Accelerated** mode, and can be modified using all of the -relevant settings. - -* **KC_ACL0:** This acceleration sets your cursor to the slowest possible speed. This is useful for very -small and detailed movements of the cursor. -* **KC_ACL1:** This acceleration sets your cursor to half the maximum (user defined) speed. -* **KC_ACL2:** This acceleration sets your cursor to the maximum (computer defined) speed. This is -useful for moving the cursor large distances without much accuracy. - -To use combined speed mode, you must at least define `MK_COMBINED` in your keymap’s `config.h` file: - -```c -#define MK_COMBINED -``` - -### Inertia mode - -This mode provides smooth motion, like sliding on ice. The cursor accelerates -along a quadratic curve while a key is held, then glides to a stop after the -key is released. Vertical and horizontal movements are tracked independently, -so the cursor can move in many directions and make curves. - -Cannot be used at the same time as Kinetic mode, Constant mode, or Combined mode. - -Recommended settings in your keymap’s `config.h` file: - -|Define |Default |Description | -|----------------------------|---------|-----------------------------------------------------------| -|`MOUSEKEY_INERTIA` |undefined|Enable Inertia mode | -|`MOUSEKEY_DELAY` |150 |Delay between pressing a movement key and cursor movement | -|`MOUSEKEY_INTERVAL` |16 |Time between cursor movements in milliseconds (16 = 60fps) | -|`MOUSEKEY_MAX_SPEED` |32 |Maximum cursor speed at which acceleration stops | -|`MOUSEKEY_TIME_TO_MAX` |32 |Number of frames until maximum cursor speed is reached | -|`MOUSEKEY_FRICTION` |24 |How quickly the cursor stops after releasing a key | -|`MOUSEKEY_MOVE_DELTA` |1 |How much to move on first frame (1 strongly recommended) | - -Tips: - -* Set `MOUSEKEY_DELAY` to roughly the same value as your host computer's key repeat delay, in ms. Recommended values are 100 to 300. -* Set `MOUSEKEY_INTERVAL` to a value of 1000 / your monitor's FPS. For 60 FPS, 1000/60 = 16. -* Set `MOUSEKEY_MAX_SPEED` based on your screen resolution and refresh rate, like Width / FPS. For example, 1920 pixels / 60 FPS = 32 pixels per frame. -* Set `MOUSEKEY_TIME_TO_MAX` to a value of approximately FPS / 2, to make it reach full speed in half a second (or so). -* Set `MOUSEKEY_FRICTION` to something between 1 and 255. Lower makes the cursor glide longer. Values from 8 to 40 are the most effective. -* Keep `MOUSEKEY_MOVE_DELTA` at 1. This allows precise movements before the gliding effect starts. -* Mouse wheel options are the same as the default accelerated mode, and do not use inertia. - -## Use with PS/2 Mouse and Pointing Device - -Mouse keys button state is shared with [PS/2 mouse](feature_ps2_mouse.md) and [pointing device](feature_pointing_device.md) so mouse keys button presses can be used for clicks and drags. diff --git a/docs/feature_oled_driver.md b/docs/feature_oled_driver.md deleted file mode 100644 index a62294b23a62..000000000000 --- a/docs/feature_oled_driver.md +++ /dev/null @@ -1,460 +0,0 @@ -# OLED Driver - -## Supported Hardware - -OLED modules using SSD1306, SH1106 or SH1107 driver ICs, communicating over I2C or SPI. -Tested combinations: - -|IC |Size |Platform|Notes | -|---------|-------|--------|------------------------| -|SSD1306 |128x32 |AVR |Primary support | -|SSD1306 |128x64 |AVR |Verified working | -|SSD1306 |128x32 |Arm | | -|SH1106 |128x64 |AVR |No scrolling | -|SH1107 |64x128 |AVR |No scrolling | -|SH1107 |64x128 |Arm |No scrolling | -|SH1107 |128x128|Arm |No scrolling | - -Hardware configurations using Arm-based microcontrollers or different sizes of OLED modules may be compatible, but are untested. - -## Usage - -To enable the OLED feature, there are two steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`: - -```make -OLED_ENABLE = yes -``` - -## OLED type - -|OLED Driver |Supported Device | -|-------------------|------------------------------------| -|SSD1306 (default) |For both SSD1306, SH1106, and SH1107| - -e.g. -```make -OLED_DRIVER = SSD1306 -``` - -|OLED Transport | | -|---------------|------------------------------------------------| -|i2c (default) | Uses I2C for communication with the OLED panel | -|spi | Uses SPI for communication with the OLED panel | - -e.g. -```make -OLED_TRANSPORT = i2c -``` - -Then in your `keymap.c` file, implement the OLED task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`: - -```c -#ifdef OLED_ENABLE -bool oled_task_user(void) { - // Host Keyboard Layer Status - oled_write_P(PSTR("Layer: "), false); - - switch (get_highest_layer(layer_state)) { - case _QWERTY: - oled_write_P(PSTR("Default\n"), false); - break; - case _FN: - oled_write_P(PSTR("FN\n"), false); - break; - case _ADJ: - oled_write_P(PSTR("ADJ\n"), false); - break; - default: - // Or use the write_ln shortcut over adding '\n' to the end of your string - oled_write_ln_P(PSTR("Undefined"), false); - } - - // Host Keyboard LED Status - led_t led_state = host_keyboard_led_state(); - oled_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); - oled_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false); - oled_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false); - - return false; -} -#endif -``` - -## Logo Example - -In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the OLED screen, use the following code example: - -```c -static void render_logo(void) { - static const char PROGMEM qmk_logo[] = { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 - }; - - oled_write_P(qmk_logo, false); -} - -bool oled_task_user(void) { - render_logo(); - return false; -} -``` - -?> The default font file is located at `drivers/oled/glcdfont.c` and its location can be overwritten with the `OLED_FONT_H` configuration option. Font file content can be edited with external tools such as [Helix Font Editor](https://helixfonteditor.netlify.app/) and [Logo Editor](https://joric.github.io/qle/). - -## Buffer Read Example -For some purposes, you may need to read the current state of the OLED display -buffer. The `oled_read_raw` function can be used to safely read bytes from the -buffer. - -In this example, calling `fade_display` in the `oled_task_user` function will -slowly fade away whatever is on the screen by turning random pixels black over -time. -```c -//Setup some mask which can be or'd with bytes to turn off pixels -const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254}; - -static void fade_display(void) { - //Define the reader structure - oled_buffer_reader_t reader; - uint8_t buff_char; - if (random() % 30 == 0) { - srand(timer_read()); - // Fetch a pointer for the buffer byte at index 0. The return structure - // will have the pointer and the number of bytes remaining from this - // index position if we want to perform a sequential read by - // incrementing the buffer pointer - reader = oled_read_raw(0); - //Loop over the remaining buffer and erase pixels as we go - for (uint16_t i = 0; i < reader.remaining_element_count; i++) { - //Get the actual byte in the buffer by dereferencing the pointer - buff_char = *reader.current_element; - if (buff_char != 0) { - oled_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i); - } - //increment the pointer to fetch a new byte during the next loop - reader.current_element++; - } - } -} -``` - -## Other Examples - -In split keyboards, it is very common to have two OLED displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g: - -```c -#ifdef OLED_ENABLE -oled_rotation_t oled_init_user(oled_rotation_t rotation) { - if (!is_keyboard_master()) { - return OLED_ROTATION_180; // flips the display 180 degrees if offhand - } - - return rotation; -} - -bool oled_task_user(void) { - if (is_keyboard_master()) { - render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc) - } else { - render_logo(); // Renders a static logo - oled_scroll_left(); // Turns on scrolling - } - return false; -} -#endif -``` - -## Basic Configuration - -These configuration options should be placed in `config.h`. Example: -```c -#define OLED_BRIGHTNESS 128 -``` - -|Define |Default |Description | -|---------------------------|-------------------------------|---------------------------------------------------------------------------------------------------------------------| -|`OLED_BRIGHTNESS` |`255` |The default brightness level of the OLED, from 0 to 255. | -|`OLED_COLUMN_OFFSET` |`0` |Shift output to the right this many pixels.
Useful for 128x64 displays centered on a 132x64 SH1106 IC. | -|`OLED_DISPLAY_CLOCK` |`0x80` |Set the display clock divide ratio/oscillator frequency. | -|`OLED_FONT_H` |`"glcdfont.c"` |The font code file to use for custom fonts | -|`OLED_FONT_START` |`0` |The starting character index for custom fonts | -|`OLED_FONT_END` |`223` |The ending character index for custom fonts | -|`OLED_FONT_WIDTH` |`6` |The font width | -|`OLED_FONT_HEIGHT` |`8` |The font height (untested) | -|`OLED_IC` |`OLED_IC_SSD1306` |Set to `OLED_IC_SH1106` or `OLED_IC_SH1107` if the corresponding controller chip is used. | -|`OLED_FADE_OUT` |*Not defined* |Enables fade out animation. Use together with `OLED_TIMEOUT`. | -|`OLED_FADE_OUT_INTERVAL` |`0` |The speed of fade out animation, from 0 to 15. Larger values are slower. | -|`OLED_SCROLL_TIMEOUT` |`0` |Scrolls the OLED screen after 0ms of OLED inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. | -|`OLED_SCROLL_TIMEOUT_RIGHT`|*Not defined* |Scroll timeout direction is right when defined, left when undefined. | -|`OLED_TIMEOUT` |`60000` |Turns off the OLED screen after 60000ms of screen update inactivity. Helps reduce OLED Burn-in. Set to 0 to disable. | -|`OLED_UPDATE_INTERVAL` |`0` (`50` for split keyboards) |Set the time interval for updating the OLED display in ms. This will improve the matrix scan rate. | -|`OLED_UPDATE_PROCESS_LIMIT'|`1` |Set the number of dirty blocks to render per loop. Increasing may degrade performance. | - -### I2C Configuration -|Define |Default |Description | -|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------| -|`OLED_DISPLAY_ADDRESS` |`0x3C` |The i2c address of the OLED Display | - -### SPI Configuration - -|Define |Default |Description | -|---------------------------|-----------------|--------------------------------------------------------------------------------------------------------------------------| -|`OLED_DC_PIN` | Required |The pin used for the DC connection of the OLED Display. | -|`OLED_CS_PIN` | Required |The pin used for the CS connection of the OLED Display. | -|`OLED_RST_PIN` | *Not defined* |The pin used for the RST connection of the OLED Display (may be left undefined if the RST pin is not connected). | -|`OLED_SPI_MODE` |`3` (default) |The SPI Mode for the OLED Display (not typically changed). | -|`OLED_SPI_DIVISOR` |`2` (default) |The SPI Multiplier to use for the OLED Display. | - -## 128x64 & Custom sized OLED Displays - - The default display size for this feature is 128x32, and the defaults are set with that in mind. However, there are a number of additional presets for common sizes that we have added. You can define one of these values to use the presets. If your display doesn't match one of these presets, you can define `OLED_DISPLAY_CUSTOM` to manually specify all of the values. - -|Define |Default |Description | -|----------------------|---------------|---------------------------------------------------------------------------------------------------------------------------------------| -|`OLED_DISPLAY_128X64` |*Not defined* |Changes the display defines for use with 128x64 displays. | -|`OLED_DISPLAY_64X32` |*Not defined* |Changes the display defines for use with 64x32 displays. | -|`OLED_DISPLAY_64X48` |*Not defined* |Changes the display defines for use with 64x48 displays. | -|`OLED_DISPLAY_64X128` |*Not defined* |Changes the display defines for use with 64x128 displays. | -|`OLED_DISPLAY_128X128`|*Not defined* |Changes the display defines for use with 128x128 displays. | -|`OLED_DISPLAY_CUSTOM` |*Not defined* |Changes the display defines for use with custom displays.
Requires user to implement the below defines. | - -!> 64x128 and 128x128 displays default to the SH1107 IC type, as these heights are not supported by the other IC types. - -|Define |Default |Description | -| --------------------|---------------|----------------------------------------------------------------------------------------------------------------------------------------| -|`OLED_DISPLAY_WIDTH` |`128` |The width of the OLED display. | -|`OLED_DISPLAY_HEIGHT`|`32` |The height of the OLED display. | -|`OLED_MATRIX_SIZE` |`512` |The local buffer size to allocate.
`(OLED_DISPLAY_HEIGHT / 8 * OLED_DISPLAY_WIDTH)`. | -|`OLED_BLOCK_TYPE` |`uint16_t` |The unsigned integer type to use for dirty rendering. | -|`OLED_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.
`(sizeof(OLED_BLOCK_TYPE) * 8)`. | -|`OLED_BLOCK_SIZE` |`32` |The size of each block for dirty rendering
`(OLED_MATRIX_SIZE / OLED_BLOCK_COUNT)`. | -|`OLED_COM_PINS` |`COM_PINS_SEQ` |How the SSD1306 chip maps it's memory to display.
Options are `COM_PINS_SEQ`, `COM_PINS_ALT`, `COM_PINS_SEQ_LR`, & `COM_PINS_ALT_LR`.| -|`OLED_COM_PIN_COUNT` |*Not defined* |Number of COM pins supported by the controller.
If not defined, the value appropriate for the defined `OLED_IC` is used. | -|`OLED_COM_PIN_OFFSET`|`0` |Number of the first COM pin used by the OLED matrix. | -|`OLED_SOURCE_MAP` |`{ 0, ... N }` |Precalculated source array to use for mapping source buffer to target OLED memory in 90 degree rendering. | -|`OLED_TARGET_MAP` |`{ 24, ... N }`|Precalculated target array to use for mapping source buffer to target OLED memory in 90 degree rendering. | - -### 90 Degree Rotation - Technical Mumbo Jumbo - -```c -// OLED Rotation enum values are flags -typedef enum { - OLED_ROTATION_0 = 0, - OLED_ROTATION_90 = 1, - OLED_ROTATION_180 = 2, - OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180 -} oled_rotation_t; -``` - -OLED displays driven by SSD1306, SH1106 or SH1107 drivers only natively support in hardware 0 degree and 180 degree rendering. This feature is done in software and not free. Using this feature will increase the time to calculate what data to send over i2c to the OLED. If you are strapped for cycles, this can cause keycodes to not register. In testing however, the rendering time on an ATmega32U4 board only went from 2ms to 5ms and keycodes not registering was only noticed once we hit 15ms. - -90 degree rotation is achieved by using bitwise operations to rotate each 8 block of memory and uses two precalculated arrays to remap buffer memory to OLED memory. The memory map defines are precalculated for remap performance and are calculated based on the display height, width, and block size. For example, in the 128x32 implementation with a `uint8_t` block type, we have a 64 byte block size. This gives us eight 8 byte blocks that need to be rotated and rendered. The OLED renders horizontally two 8 byte blocks before moving down a page, e.g: - -| | | | | | | -|---|---|---|---|---|---| -| 0 | 1 | | | | | -| 2 | 3 | | | | | -| 4 | 5 | | | | | -| 6 | 7 | | | | | - -However the local buffer is stored as if it was Height x Width display instead of Width x Height, e.g: - -| | | | | | | -|---|---|---|---|---|---| -| 3 | 7 | | | | | -| 2 | 6 | | | | | -| 1 | 5 | | | | | -| 0 | 4 | | | | | - -So those precalculated arrays just index the memory offsets in the order in which each one iterates its data. - -Rotation on SH1106 and SH1107 is noticeably less efficient than on SSD1306, because these controllers do not support the “horizontal addressing mode”, which allows transferring the data for the whole rotated block at once; instead, separate address setup commands for every page in the block are required. The screen refresh time for SH1107 is therefore about 45% higher than for a same size screen with SSD1306 when using STM32 MCUs (on AVR the slowdown is about 20%, because the code which actually rotates the bitmap consumes more time). - -## OLED API - -```c -// OLED rotation enum values are flags -typedef enum { - OLED_ROTATION_0 = 0, - OLED_ROTATION_90 = 1, - OLED_ROTATION_180 = 2, - OLED_ROTATION_270 = 3, // OLED_ROTATION_90 | OLED_ROTATION_180 -} oled_rotation_t; - -// Initialize the OLED display, rotating the rendered output based on the define passed in. -// Returns true if the OLED was initialized successfully -bool oled_init(oled_rotation_t rotation); - -// Called at the start of oled_init, weak function overridable by the user -// rotation - the value passed into oled_init -// Return new oled_rotation_t if you want to override default rotation -oled_rotation_t oled_init_kb(oled_rotation_t rotation); -oled_rotation_t oled_init_user(oled_rotation_t rotation); - -// Send commands/data to screen -bool oled_send_cmd(const uint8_t *data, uint16_t size); -bool oled_send_cmd_P(const uint8_t *data, uint16_t size); -bool oled_send_data(const uint8_t *data, uint16_t size); - -// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering -void oled_clear(void); - -// Renders the dirty chunks of the buffer to OLED display -void oled_render(void); - -// Moves cursor to character position indicated by column and line, wraps if out of bounds -// Max column denoted by 'oled_max_chars()' and max lines by 'oled_max_lines()' functions -void oled_set_cursor(uint8_t col, uint8_t line); - -// Advances the cursor to the next page, writing ' ' if true -// Wraps to the beginning when out of bounds -void oled_advance_page(bool clearPageRemainder); - -// Moves the cursor forward 1 character length -// Advance page if there is not enough room for the next character -// Wraps to the beginning when out of bounds -void oled_advance_char(void); - -// Writes a single character to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Main handler that writes character data to the display buffer -void oled_write_char(const char data, bool invert); - -// Writes a string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -void oled_write(const char *data, bool invert); - -// Writes a string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Advances the cursor to the next page, wiring ' ' to the remainder of the current page -void oled_write_ln(const char *data, bool invert); - -// Pans the buffer to the right (or left by passing true) by moving contents of the buffer -// Useful for moving the screen in preparation for new drawing -// oled_scroll_left or oled_scroll_right should be preferred for all cases of moving a static -// image such as a logo or to avoid burn-in as it's much, much less cpu intensive -void oled_pan(bool left); - -// Returns a pointer to the requested start index in the buffer plus remaining -// buffer length as struct -oled_buffer_reader_t oled_read_raw(uint16_t start_index); - -// Writes a string to the buffer at current cursor position -void oled_write_raw(const char *data, uint16_t size); - -// Writes a single byte into the buffer at the specified index -void oled_write_raw_byte(const char data, uint16_t index); - -// Sets a specific pixel on or off -// Coordinates start at top-left and go right and down for positive x and y -void oled_write_pixel(uint8_t x, uint8_t y, bool on); - -// Writes a PROGMEM string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Remapped to call 'void oled_write(const char *data, bool invert);' on ARM -void oled_write_P(const char *data, bool invert); - -// Writes a PROGMEM string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Advances the cursor to the next page, wiring ' ' to the remainder of the current page -// Remapped to call 'void oled_write_ln(const char *data, bool invert);' on ARM -void oled_write_ln_P(const char *data, bool invert); - -// Writes a PROGMEM string to the buffer at current cursor position -void oled_write_raw_P(const char *data, uint16_t size); - -// Can be used to manually turn on the screen if it is off -// Returns true if the screen was on or turns on -bool oled_on(void); - -// Can be used to manually turn off the screen if it is on -// Returns true if the screen was off or turns off -bool oled_off(void); - -// Returns true if the oled is currently on, false if it is -// not -bool is_oled_on(void); - -// Sets the brightness level of the display -uint8_t oled_set_brightness(uint8_t level); - -// Gets the current brightness level of the display -uint8_t oled_get_brightness(void); - -// Basically it's oled_render, but with timeout management and oled_task_user calling! -void oled_task(void); - -// Called at the start of oled_task, weak function overridable by the user -bool oled_task_kb(void); -bool oled_task_user(void); - -// Set the specific 8 lines rows of the screen to scroll. -// 0 is the default for start, and 7 for end, which is the entire -// height of the screen. For 128x32 screens, rows 4-7 are not used. -void oled_scroll_set_area(uint8_t start_line, uint8_t end_line); - -// Sets scroll speed, 0-7, fastest to slowest. Default is three. -// Does not take effect until scrolling is either started or restarted -// the ssd1306 supports 8 speeds with the delay -// listed below betwen each frame of the scrolling effect -// 0=2, 1=3, 2=4, 3=5, 4=25, 5=64, 6=128, 7=256 -void oled_scroll_set_speed(uint8_t speed); - -// Begin scrolling the entire display right -// Returns true if the screen was scrolling or starts scrolling -// NOTE: display contents cannot be changed while scrolling -bool oled_scroll_right(void); - -// Begin scrolling the entire display left -// Returns true if the screen was scrolling or starts scrolling -// NOTE: display contents cannot be changed while scrolling -bool oled_scroll_left(void); - -// Turns off display scrolling -// Returns true if the screen was not scrolling or stops scrolling -bool oled_scroll_off(void); - -// Returns true if the oled is currently scrolling, false if it is -// not -bool is_oled_scrolling(void); - -// Inverts the display -// Returns true if the screen was or is inverted -bool oled_invert(bool invert); - -// Returns the maximum number of characters that will fit on a line -uint8_t oled_max_chars(void); - -// Returns the maximum number of lines that will fit on the OLED -uint8_t oled_max_lines(void); -``` - -!> Scrolling is unsupported on the SH1106 and SH1107. - -!> Scrolling does not work properly on the SSD1306 if the display width is smaller than 128. - -## SSD1306.h Driver Conversion Guide - -|Old API |Recommended New API | -|-------------------------|---------------------------------| -|`struct CharacterMatrix` |*removed - delete all references*| -|`iota_gfx_init` |`oled_init` | -|`iota_gfx_on` |`oled_on` | -|`iota_gfx_off` |`oled_off` | -|`iota_gfx_flush` |`oled_render` | -|`iota_gfx_write_char` |`oled_write_char` | -|`iota_gfx_write` |`oled_write` | -|`iota_gfx_write_P` |`oled_write_P` | -|`iota_gfx_clear_screen` |`oled_clear` | -|`matrix_clear` |*removed - delete all references*| -|`matrix_write_char_inner`|`oled_write_char` | -|`matrix_write_char` |`oled_write_char` | -|`matrix_write` |`oled_write` | -|`matrix_write_ln` |`oled_write_ln` | -|`matrix_write_P` |`oled_write_P` | -|`matrix_write_ln_P` |`oled_write_ln_P` | -|`matrix_render` |`oled_render` | -|`iota_gfx_task` |`oled_task` | -|`iota_gfx_task_user` |`oled_task_user` | diff --git a/docs/feature_os_detection.md b/docs/feature_os_detection.md deleted file mode 100644 index f32e419807f7..000000000000 --- a/docs/feature_os_detection.md +++ /dev/null @@ -1,77 +0,0 @@ -# OS Detection - -This feature makes a best guess at the host OS based on OS specific behavior during USB setup. It may not always get the correct OS, and shouldn't be relied on as for critical functionality. - -Using it you can have OS specific key mappings or combos which work differently on different devices. - -It is available for keyboards which use ChibiOS, LUFA and V-USB. - -## Usage - -In your `rules.mk` add: - -```make -OS_DETECTION_ENABLE = yes -``` - -Include `"os_detection.h"` in your `keymap.c`. -It declares `os_variant_t detected_host_os(void);` which you can call to get detected OS. - -It returns one of the following values: - -```c -enum { - OS_UNSURE, - OS_LINUX, - OS_WINDOWS, - OS_MACOS, - OS_IOS, -} os_variant_t; -``` - -?> Note that it takes some time after firmware is booted to detect the OS. -This time is quite short, probably hundreds of milliseconds, but this data may be not ready in keyboard and layout setup functions which run very early during firmware startup. - -## Debug - -If OS is guessed incorrectly, you may want to collect data about USB setup packets to refine the detection logic. - -To do so in your `rules.mk` add: - -```make -OS_DETECTION_DEBUG_ENABLE = yes -CONSOLE_ENABLE = yes -``` - -And also include `"os_detection.h"` in your `keymap.c`. - -Then you can define custom keycodes to store data about USB setup packets in EEPROM (persistent memory) and to print it later on host where you can run `qmk console`: - -```c -enum custom_keycodes { - STORE_SETUPS = SAFE_RANGE, - PRINT_SETUPS, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case STORE_SETUPS: - if (record->event.pressed) { - store_setups_in_eeprom(); - } - return false; - case PRINT_SETUPS: - if (record->event.pressed) { - print_stored_setups(); - } - return false; - } -} -``` - -Then please open an issue on Github with this information and tell what OS was not detected correctly and if you have any intermediate devices between keyboard and your computer. - - -## Credits - -Original idea is coming from [FingerprintUSBHost](https://github.com/keyboardio/FingerprintUSBHost) project. diff --git a/docs/feature_pointing_device.md b/docs/feature_pointing_device.md deleted file mode 100644 index 909eff826de1..000000000000 --- a/docs/feature_pointing_device.md +++ /dev/null @@ -1,824 +0,0 @@ -# Pointing Device :id=pointing-device - -Pointing Device is a generic name for a feature intended to be generic: moving the system pointer around. There are certainly other options for it - like mousekeys - but this aims to be easily modifiable and hardware driven. You can implement custom keys to control functionality, or you can gather information from other peripherals and insert it directly here - let QMK handle the processing for you. - -To enable Pointing Device, add the following line in your rules.mk and specify one of the driver options below. - -```make -POINTING_DEVICE_ENABLE = yes -``` - -## Sensor Drivers - -There are a number of sensors that are supported by default. Note that only one sensor can be enabled by `POINTING_DEVICE_DRIVER` at a time. If you need to enable more than one sensor, then you need to implement it manually, using the `custom` driver. - -### ADNS 5050 Sensor - -To use the ADNS 5050 sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = adns5050 -``` - -The ADNS 5050 sensor uses a serial type protocol for communication, and requires an additional light source. - -| Setting (`config.h`) | Description | Default | -| -------------------- | ------------------------------------------------------------------ | -------------------------- | -| `ADNS5050_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` | -| `ADNS5050_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` | -| `ADNS5050_CS_PIN` | (Required) The pin connected to the Chip Select pin of the sensor. | `POINTING_DEVICE_CS_PIN` | - - - -The CPI range is 125-1375, in increments of 125. Defaults to 500 CPI. - -### ADNS 9800 Sensor - -To use the ADNS 9800 sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = adns9800 -``` - -The ADNS 9800 is an SPI driven optical sensor, that uses laser output for surface tracking. - -| Setting (`config.h`) | Description | Default | -| ----------------------- | ---------------------------------------------------------------------- | ------------------------ | -| `ADNS9800_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` | -| `ADNS9800_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` | -| `ADNS9800_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `3` | -| `ADNS9800_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | -| `ADNS9800_CS_PIN` | (Required) Sets the Chip Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` | - - -The CPI range is 800-8200, in increments of 200. Defaults to 1800 CPI. - -### Analog Joystick - -To use an analog joystick to control the pointer, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = analog_joystick -``` - -The Analog Joystick is an analog (ADC) driven sensor. There are a variety of joysticks that you can use for this. - -| Setting (`config.h`) | Description | Default | -| --------------------------------- | -------------------------------------------------------------------------- | ------------- | -| `ANALOG_JOYSTICK_X_AXIS_PIN` | (Required) The pin used for the vertical/X axis. | _not defined_ | -| `ANALOG_JOYSTICK_Y_AXIS_PIN` | (Required) The pin used for the horizontal/Y axis. | _not defined_ | -| `ANALOG_JOYSTICK_AXIS_MIN` | (Optional) Sets the lower range to be considered movement. | `0` | -| `ANALOG_JOYSTICK_AXIS_MAX` | (Optional) Sets the upper range to be considered movement. | `1023` | -| `ANALOG_JOYSTICK_SPEED_REGULATOR` | (Optional) The divisor used to slow down movement. (lower makes it faster) | `20` | -| `ANALOG_JOYSTICK_READ_INTERVAL` | (Optional) The interval in milliseconds between reads. | `10` | -| `ANALOG_JOYSTICK_SPEED_MAX` | (Optional) The maximum value used for motion. | `2` | -| `ANALOG_JOYSTICK_CLICK_PIN` | (Optional) The pin wired up to the press switch of the analog stick. | _not defined_ | - -### Cirque Trackpad - -To use the Cirque Trackpad sensor, add this to your `rules.mk`: - -```make -POINTING_DEVICE_DRIVER = cirque_pinnacle_i2c -``` - -or - -```make -POINTING_DEVICE_DRIVER = cirque_pinnacle_spi -``` - - -This supports the Cirque Pinnacle 1CA027 Touch Controller, which is used in the TM040040, TM035035 and the TM023023 trackpads. These are I2C or SPI compatible, and both configurations are supported. - -#### Common settings - -| Setting | Description | Default | -| -------------------------------- | ---------------------------------------------------------- | ------------------------------------------- | -| `CIRQUE_PINNACLE_DIAMETER_MM` | (Optional) Diameter of the trackpad sensor in millimeters. | `40` | -| `CIRQUE_PINNACLE_ATTENUATION` | (Optional) Sets the attenuation of the sensor data. | `EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_4X` | -| `CIRQUE_PINNACLE_CURVED_OVERLAY` | (Optional) Applies settings tuned for curved overlay. | _not defined_ | -| `CIRQUE_PINNACLE_POSITION_MODE` | (Optional) Mode of operation. | _not defined_ | - -**`CIRQUE_PINNACLE_ATTENUATION`** is a measure of how much data is suppressed in regards to sensitivity. The higher the attenuation, the less sensitive the touchpad will be. - -Default attenuation is set to 4X, although if you are using a thicker overlay (such as the curved overlay) you will want a lower attenuation such as 2X. The possible values are: -* `EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_4X`: Least sensitive -* `EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_3X` -* `EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_2X` -* `EXTREG__TRACK_ADCCONFIG__ADC_ATTENUATE_1X`: Most sensitive - -**`CIRQUE_PINNACLE_POSITION_MODE`** can be `CIRQUE_PINNACLE_ABSOLUTE_MODE` or `CIRQUE_PINNACLE_RELATIVE_MODE`. Modes differ in supported features/gestures. - -* `CIRQUE_PINNACLE_ABSOLUTE_MODE`: Reports absolute x, y, z (touch pressure) coordinates and up to 5 hw buttons connected to the trackpad -* `CIRQUE_PINNACLE_RELATIVE_MODE`: Reports x/y deltas, scroll and up to 3 buttons (2 of them can be from taps, see gestures) connected to trackpad. Supports taps on secondary side of split. Saves about 2k of flash compared to absolute mode with all features. - -| I2C Setting | Description | Default | -| ------------------------- | ------------------------------------------------------------------------------- | ------- | -| `CIRQUE_PINNACLE_ADDR` | (Required) Sets the I2C Address for the Cirque Trackpad | `0x2A` | -| `CIRQUE_PINNACLE_TIMEOUT` | (Optional) The timeout for i2c communication with the trackpad in milliseconds. | `20` | - -| SPI Setting | Description | Default | -| ------------------------------ | ---------------------------------------------------------------------- | ------------------------ | -| `CIRQUE_PINNACLE_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `1000000` | -| `CIRQUE_PINNACLE_SPI_LSBFIRST` | (Optional) Sets the Least/Most Significant Byte First setting for SPI. | `false` | -| `CIRQUE_PINNACLE_SPI_MODE` | (Optional) Sets the SPI Mode for the sensor. | `1` | -| `CIRQUE_PINNACLE_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | -| `CIRQUE_PINNACLE_SPI_CS_PIN` | (Required) Sets the Chip Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` | - -Default Scaling is 1024. Actual CPI depends on trackpad diameter. - -Also see the `POINTING_DEVICE_TASK_THROTTLE_MS`, which defaults to 10ms when using Cirque Pinnacle, which matches the internal update rate of the position registers (in standard configuration). Advanced configuration for pen/stylus usage might require lower values. - -#### Absolute mode settings - -| Setting | Description | Default | -| -------------------------------- | ---------------------------------------------------------- | ------------------ | -| `CIRQUE_PINNACLE_X_LOWER` | (Optional) The minimum reachable X value on the sensor. | `127` | -| `CIRQUE_PINNACLE_X_UPPER` | (Optional) The maximum reachable X value on the sensor. | `1919` | -| `CIRQUE_PINNACLE_Y_LOWER` | (Optional) The minimum reachable Y value on the sensor. | `63` | -| `CIRQUE_PINNACLE_Y_UPPER` | (Optional) The maximum reachable Y value on the sensor. | `1471` | - -#### Absolute mode gestures - -| Gesture Setting | Description | Default | -| ---------------------------------------------- | ------------------------------------------------------------------------------ | -------------------- | -| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to click. This currently only works on the master side. | _not defined_ | -| `CIRQUE_PINNACLE_TAPPING_TERM` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | -| `CIRQUE_PINNACLE_TOUCH_DEBOUNCE` | (Optional) Length of time that a touch can be to be considered a tap. | `TAPPING_TERM`/`200` | - -`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables circular scroll. Touch originating in outer ring can trigger scroll by moving along the perimeter. Near side triggers vertical scroll and far side triggers horizontal scroll. - -Additionally, `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` is supported in this mode. - -#### Relative mode gestures - -| Gesture Setting (`config.h`) | Description | Default | -| -------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `CIRQUE_PINNACLE_TAP_ENABLE` | (Optional) Enable tap to "left click". Works on both sides of a split keyboard. | _not defined_ | -| `CIRQUE_PINNACLE_SECONDARY_TAP_ENABLE` | (Optional) Tap in upper right corner (half of the finger needs to be outside of the trackpad) of the trackpad will result in "right click". `CIRQUE_PINNACLE_TAP_ENABLE` must be enabled. | _not defined_ | - -Tapping term and debounce are not configurable in this mode since it's handled by trackpad internally. - -`POINTING_DEVICE_GESTURES_SCROLL_ENABLE` in this mode enables side scroll. Touch originating on the right side can trigger vertical scroll (IntelliSense trackpad style). - -### PAW 3204 Sensor - -To use the paw 3204 sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = paw3204 -``` - -The paw 3204 sensor uses a serial type protocol for communication, and requires an additional light source. - -| Setting (`config.h`) | Description | Default | -| -------------------- |--------------------------------------------------------------- | -------------------------- | -| `PAW3204_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` | -| `PAW3204_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` | - -The CPI range is 400-1600, with supported values of (400, 500, 600, 800, 1000, 1200 and 1600). Defaults to 1000 CPI. - -### Pimoroni Trackball - -To use the Pimoroni Trackball module, add this to your `rules.mk`: - -```make -POINTING_DEVICE_DRIVER = pimoroni_trackball -``` - -The Pimoroni Trackball module is a I2C based breakout board with an RGB enable trackball. - -| Setting (`config.h`) | Description | Default | -| ------------------------------------ | ---------------------------------------------------------------------------------- | ------- | -| `PIMORONI_TRACKBALL_ADDRESS` | (Required) Sets the I2C Address for the Pimoroni Trackball. | `0x0A` | -| `PIMORONI_TRACKBALL_TIMEOUT` | (Optional) The timeout for i2c communication with the trackball in milliseconds. | `100` | -| `PIMORONI_TRACKBALL_SCALE` | (Optional) The multiplier used to generate reports from the sensor. | `5` | -| `PIMORONI_TRACKBALL_DEBOUNCE_CYCLES` | (Optional) The number of scan cycles used for debouncing on the ball press. | `20` | -| `PIMORONI_TRACKBALL_ERROR_COUNT` | (Optional) Specifies the number of read/write errors until the sensor is disabled. | `10` | - -### PMW3320 Sensor - -To use the PMW3320 sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = pmw3320 -``` - -The PMW3320 sensor uses a serial type protocol for communication, and requires an additional light source (it could work without one, but expect it to be out of service early). - -| Setting | Description | Default | -| ------------------- | ------------------------------------------------------------------- | -------------------------- | -| `PMW3320_SCLK_PIN` | (Required) The pin connected to the clock pin of the sensor. | `POINTING_DEVICE_SCLK_PIN` | -| `PMW3320_SDIO_PIN` | (Required) The pin connected to the data pin of the sensor. | `POINTING_DEVICE_SDIO_PIN` | -| `PMW3320_CS_PIN` | (Required) The pin connected to the cable select pin of the sensor. | `POINTING_DEVICE_CS_PIN` | - -The CPI range is 500-3500, in increments of 250. Defaults to 1000 CPI. - -### PMW 3360 and PMW 3389 Sensor - -This drivers supports both the PMW 3360 and PMW 3389 sensor as well as multiple sensors of the same type _per_ controller, so 2 can be attached at the same side for split keyboards (or unsplit keyboards). - -To use the **PMW 3360** sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = pmw3360 -``` - -The CPI range is 100-12000, in increments of 100. Defaults to 1600 CPI. - -To use the **PMW 3389** sensor, add this to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = pmw3389 -``` - -The CPI range is 50-16000, in increments of 50. Defaults to 2000 CPI. - -Both PMW 3360 and PMW 3389 are SPI driven optical sensors, that use a built in IR LED for surface tracking. -If you have different CS wiring on each half you can use `PMW33XX_CS_PIN_RIGHT` or `PMW33XX_CS_PINS_RIGHT` in combination with `PMW33XX_CS_PIN` or `PMW33XX_CS_PINS` to configure both sides independently. If `_RIGHT` values aren't provided, they default to be the same as the left ones. - -| Setting (`config.h`) | Description | Default | -| ---------------------------- | ------------------------------------------------------------------------------------------- | ------------------------ | -| `PMW33XX_CS_PIN` | (Required) Sets the Chip Select pin connected to the sensor. | `POINTING_DEVICE_CS_PIN` | -| `PMW33XX_CS_PINS` | (Alternative) Sets the Chip Select pins connected to multiple sensors. | `{PMW33XX_CS_PIN}` | -| `PMW33XX_CS_PIN_RIGHT` | (Optional) Sets the Chip Select pin connected to the sensor on the right half. | `PMW33XX_CS_PIN` | -| `PMW33XX_CS_PINS_RIGHT` | (Optional) Sets the Chip Select pins connected to multiple sensors on the right half. | `{PMW33XX_CS_PIN_RIGHT}` | -| `PMW33XX_CPI` | (Optional) Sets counts per inch sensitivity of the sensor. | _varies_ | -| `PMW33XX_CLOCK_SPEED` | (Optional) Sets the clock speed that the sensor runs at. | `2000000` | -| `PMW33XX_SPI_DIVISOR` | (Optional) Sets the SPI Divisor used for SPI communication. | _varies_ | -| `PMW33XX_LIFTOFF_DISTANCE` | (Optional) Sets the lift off distance at run time | `0x02` | -| `ROTATIONAL_TRANSFORM_ANGLE` | (Optional) Allows for the sensor data to be rotated +/- 127 degrees directly in the sensor. | `0` | - -To use multiple sensors, instead of setting `PMW33XX_CS_PIN` you need to set `PMW33XX_CS_PINS` and also handle and merge the read from this sensor in user code. -Note that different (per sensor) values of CPI, speed liftoff, rotational angle or flipping of X/Y is not currently supported. - -```c -// in config.h: -#define PMW33XX_CS_PINS { B5, B6 } -// in keyboard.c: -#ifdef POINTING_DEVICE_ENABLE -void pointing_device_init_kb(void) { - pmw33xx_init(1); // index 1 is the second device. - pmw33xx_set_cpi(0, 800); // applies to first sensor - pmw33xx_set_cpi(1, 800); // applies to second sensor - pointing_device_init_user(); -} - -// Contains report from sensor #0 already, need to merge in from sensor #1 -report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { - pmw33xx_report_t report = pmw33xx_read_burst(1); - if (!report.motion.b.is_lifted && report.motion.b.is_motion) { -// From quantum/pointing_device_drivers.c -#define constrain_hid(amt) ((amt) < -127 ? -127 : ((amt) > 127 ? 127 : (amt))) - mouse_report.x = constrain_hid(mouse_report.x + report.delta_x); - mouse_report.y = constrain_hid(mouse_report.y + report.delta_y); - } - return pointing_device_task_user(mouse_report); -} -#endif - -``` - -### Custom Driver - -If you have a sensor type that isn't supported above, a custom option is available by adding the following to your `rules.mk` - -```make -POINTING_DEVICE_DRIVER = custom -``` - -Using the custom driver will require implementing the following functions: - -```c -void pointing_device_driver_init(void) {} -report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) { return mouse_report; } -uint16_t pointing_device_driver_get_cpi(void) { return 0; } -void pointing_device_driver_set_cpi(uint16_t cpi) {} -``` - -!> Ideally, new sensor hardware should be added to `drivers/sensors/` and `quantum/pointing_device_drivers.c`, but there may be cases where it's very specific to the hardware. So these functions are provided, just in case. - -## Common Configuration - -| Setting | Description | Default | -| ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | ------------- | -| `MOUSE_EXTENDED_REPORT` | (Optional) Enables support for extended mouse reports. (-32767 to 32767, instead of just -127 to 127). | _not defined_ | -| `POINTING_DEVICE_ROTATION_90` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_180` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_270` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | -| `POINTING_DEVICE_INVERT_X` | (Optional) Inverts the X axis report. | _not defined_ | -| `POINTING_DEVICE_INVERT_Y` | (Optional) Inverts the Y axis report. | _not defined_ | -| `POINTING_DEVICE_MOTION_PIN` | (Optional) If supported, will only read from sensor if pin is active. | _not defined_ | -| `POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW` | (Optional) If defined then the motion pin is active-low. | _varies_ | -| `POINTING_DEVICE_TASK_THROTTLE_MS` | (Optional) Limits the frequency that the sensor is polled for motion. | _not defined_ | -| `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE` | (Optional) Enable inertial cursor. Cursor continues moving after a flick gesture and slows down by kinetic friction. | _not defined_ | -| `POINTING_DEVICE_GESTURES_SCROLL_ENABLE` | (Optional) Enable scroll gesture. The gesture that activates the scroll is device dependent. | _not defined_ | -| `POINTING_DEVICE_CS_PIN` | (Optional) Provides a default CS pin, useful for supporting multiple sensor configs. | _not defined_ | -| `POINTING_DEVICE_SDIO_PIN` | (Optional) Provides a default SDIO pin, useful for supporting multiple sensor configs. | _not defined_ | -| `POINTING_DEVICE_SCLK_PIN` | (Optional) Provides a default SCLK pin, useful for supporting multiple sensor configs. | _not defined_ | - -!> When using `SPLIT_POINTING_ENABLE` the `POINTING_DEVICE_MOTION_PIN` functionality is not supported and `POINTING_DEVICE_TASK_THROTTLE_MS` will default to `1`. Increasing this value will increase transport performance at the cost of possible mouse responsiveness. - -The `POINTING_DEVICE_CS_PIN`, `POINTING_DEVICE_SDIO_PIN`, and `POINTING_DEVICE_SCLK_PIN` provide a convenient way to define a single pin that can be used for an interchangeable sensor config. This allows you to have a single config, without defining each device. Each sensor allows for this to be overridden with their own defines. - -!> Any pointing device with a lift/contact status can integrate inertial cursor feature into its driver, controlled by `POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE`. e.g. PMW3360 can use Lift_Stat from Motion register. Note that `POINTING_DEVICE_MOTION_PIN` cannot be used with this feature; continuous polling of `get_report()` is needed to generate glide reports. - -## Split Keyboard Configuration - -The following configuration options are only available when using `SPLIT_POINTING_ENABLE` see [data sync options](feature_split_keyboard.md?id=data-sync-options). The rotation and invert `*_RIGHT` options are only used with `POINTING_DEVICE_COMBINED`. If using `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` use the common configuration above to configure your pointing device. - -| Setting | Description | Default | -| ------------------------------------ | ----------------------------------------------------------------------------------------------------- | ------------- | -| `POINTING_DEVICE_LEFT` | Pointing device on the left side (Required - pick one only) | _not defined_ | -| `POINTING_DEVICE_RIGHT` | Pointing device on the right side (Required - pick one only) | _not defined_ | -| `POINTING_DEVICE_COMBINED` | Pointing device on both sides (Required - pick one only) | _not defined_ | -| `POINTING_DEVICE_ROTATION_90_RIGHT` | (Optional) Rotates the X and Y data by 90 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_180_RIGHT` | (Optional) Rotates the X and Y data by 180 degrees. | _not defined_ | -| `POINTING_DEVICE_ROTATION_270_RIGHT` | (Optional) Rotates the X and Y data by 270 degrees. | _not defined_ | -| `POINTING_DEVICE_INVERT_X_RIGHT` | (Optional) Inverts the X axis report. | _not defined_ | -| `POINTING_DEVICE_INVERT_Y_RIGHT` | (Optional) Inverts the Y axis report. | _not defined_ | - -!> If there is a `_RIGHT` configuration option or callback, the [common configuration](feature_pointing_device.md?id=common-configuration) option will work for the left. For correct left/right detection you should setup a [handedness option](feature_split_keyboard?id=setting-handedness), `EE_HANDS` is usually a good option for an existing board that doesn't do handedness by hardware. - - -## Callbacks and Functions - -| Function | Description | -| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | -| `pointing_device_init_kb(void)` | Callback to allow for keyboard level initialization. Useful for additional hardware sensors. | -| `pointing_device_init_user(void)` | Callback to allow for user level initialization. Useful for additional hardware sensors. | -| `pointing_device_task_kb(mouse_report)` | Callback that sends sensor data, so keyboard code can intercept and modify the data. Returns a mouse report. | -| `pointing_device_task_user(mouse_report)` | Callback that sends sensor data, so user code can intercept and modify the data. Returns a mouse report. | -| `pointing_device_handle_buttons(buttons, pressed, button)` | Callback to handle hardware button presses. Returns a `uint8_t`. | -| `pointing_device_get_cpi(void)` | Gets the current CPI/DPI setting from the sensor, if supported. | -| `pointing_device_set_cpi(uint16_t)` | Sets the CPI/DPI, if supported. | -| `pointing_device_get_report(void)` | Returns the current mouse report (as a `report_mouse_t` data structure). | -| `pointing_device_set_report(mouse_report)` | Sets the mouse report to the assigned `report_mouse_t` data structured passed to the function. | -| `pointing_device_send(void)` | Sends the current mouse report to the host system. Function can be replaced. | -| `has_mouse_report_changed(new_report, old_report)` | Compares the old and new `report_mouse_t` data and returns true only if it has changed. | -| `pointing_device_adjust_by_defines(mouse_report)` | Applies rotations and invert configurations to a raw mouse report. | - - -## Split Keyboard Callbacks and Functions - -The combined functions below are only available when using `SPLIT_POINTING_ENABLE` and `POINTING_DEVICE_COMBINED`. The 2 callbacks `pointing_device_task_combined_*` replace the single sided equivalents above. See the [combined pointing devices example](feature_pointing_device.md?id=combined-pointing-devices) - -| Function | Description | -| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | -| `pointing_device_set_shared_report(mouse_report)` | Sets the shared mouse report to the assigned `report_mouse_t` data structured passed to the function. | -| `pointing_device_set_cpi_on_side(bool, uint16_t)` | Sets the CPI/DPI of one side, if supported. Passing `true` will set the left and `false` the right | -| `pointing_device_combine_reports(left_report, right_report)` | Returns a combined mouse_report of left_report and right_report (as a `report_mouse_t` data structure) | -| `pointing_device_task_combined_kb(left_report, right_report)` | Callback, so keyboard code can intercept and modify the data. Returns a combined mouse report. | -| `pointing_device_task_combined_user(left_report, right_report)` | Callback, so user code can intercept and modify. Returns a combined mouse report using `pointing_device_combine_reports` | -| `pointing_device_adjust_by_defines_right(mouse_report)` | Applies right side rotations and invert configurations to a raw mouse report. | - - -# Manipulating Mouse Reports - -The report_mouse_t (here "mouseReport") has the following properties: - -* `mouseReport.x` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ to the right, - to the left) on the x axis. -* `mouseReport.y` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing movement (+ upward, - downward) on the y axis. -* `mouseReport.v` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing vertical scrolling (+ upward, - downward). -* `mouseReport.h` - this is a signed int from -127 to 127 (not 128, this is defined in USB HID spec) representing horizontal scrolling (+ right, - left). -* `mouseReport.buttons` - this is a uint8_t in which all 8 bits are used. These bits represent the mouse button state - bit 0 is mouse button 1, and bit 7 is mouse button 8. - -To manually manipulate the mouse reports outside of the `pointing_device_task_*` functions, you can use: - -* `pointing_device_get_report()` - Returns the current report_mouse_t that represents the information sent to the host computer -* `pointing_device_set_report(report_mouse_t mouse_report)` - Overrides and saves the report_mouse_t to be sent to the host computer -* `pointing_device_send()` - Sends the mouse report to the host and zeroes out the report. - -When the mouse report is sent, the x, y, v, and h values are set to 0 (this is done in `pointing_device_send()`, which can be overridden to avoid this behavior). This way, button states persist, but movement will only occur once. For further customization, both `pointing_device_init` and `pointing_device_task` can be overridden. - -Additionally, by default, `pointing_device_send()` will only send a report when the report has actually changed. This prevents it from continuously sending mouse reports, which will keep the host system awake. This behavior can be changed by creating your own `pointing_device_send()` function. - -Also, you use the `has_mouse_report_changed(new_report, old_report)` function to check to see if the report has changed. - -## Examples - -### Custom Mouse Keycode - -In this example, a custom key is used to click the mouse and scroll 127 units vertically and horizontally, then undo all of that when released - because that's a totally useful function. - -```c -case MS_SPECIAL: - report_mouse_t currentReport = pointing_device_get_report(); - if (record->event.pressed) { - currentReport.v = 127; - currentReport.h = 127; - currentReport.buttons |= MOUSE_BTN1; // this is defined in report.h - } else { - currentReport.v = -127; - currentReport.h = -127; - currentReport.buttons &= ~MOUSE_BTN1; - } - pointing_device_set_report(currentReport); - pointing_device_send(); - break; -``` - -Recall that the mouse report is set to zero (except the buttons) whenever it is sent, so the scrolling would only occur once in each case. - -### Drag Scroll or Mouse Scroll - -A very common implementation is to use the mouse movement to scroll instead of moving the cursor on the system. This uses the `pointing_device_task_user` callback to intercept and modify the mouse report before it's sent to the host system. - -```c -enum custom_keycodes { - DRAG_SCROLL = SAFE_RANGE, -}; - -bool set_scrolling = false; - -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { - if (set_scrolling) { - mouse_report.h = mouse_report.x; - mouse_report.v = mouse_report.y; - mouse_report.x = 0; - mouse_report.y = 0; - } - return mouse_report; -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - if (keycode == DRAG_SCROLL && record->event.pressed) { - set_scrolling = !set_scrolling; - } - return true; -} -``` - -This allows you to toggle between scrolling and cursor movement by pressing the DRAG_SCROLL key. - -### Advanced Drag Scroll - -Sometimes, like with the Cirque trackpad, you will run into issues where the scrolling may be too fast. - -Here is a slightly more advanced example of drag scrolling. You will be able to change the scroll speed based on the values in set in `SCROLL_DIVISOR_H` and `SCROLL_DIVISOR_V`. This bit of code is also set up so that instead of toggling the scrolling state with set_scrolling = !set_scrolling, the set_scrolling variable is set directly to record->event.pressed. This way, the drag scrolling will only be active while the DRAG_SCROLL button is held down. - -```c -enum custom_keycodes { - DRAG_SCROLL = SAFE_RANGE, -}; - -bool set_scrolling = false; - -// Modify these values to adjust the scrolling speed -#define SCROLL_DIVISOR_H 8.0 -#define SCROLL_DIVISOR_V 8.0 - -// Variables to store accumulated scroll values -float scroll_accumulated_h = 0; -float scroll_accumulated_v = 0; - -// Function to handle mouse reports and perform drag scrolling -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { - // Check if drag scrolling is active - if (set_scrolling) { - // Calculate and accumulate scroll values based on mouse movement and divisors - scroll_accumulated_h += (float)mouse_report.x / SCROLL_DIVISOR_H; - scroll_accumulated_v += (float)mouse_report.y / SCROLL_DIVISOR_V; - - // Assign integer parts of accumulated scroll values to the mouse report - mouse_report.h = (int8_t)scroll_accumulated_h; - mouse_report.v = (int8_t)scroll_accumulated_v; - - // Update accumulated scroll values by subtracting the integer parts - scroll_accumulated_h -= (int8_t)scroll_accumulated_h; - scroll_accumulated_v -= (int8_t)scroll_accumulated_v; - - // Clear the X and Y values of the mouse report - mouse_report.x = 0; - mouse_report.y = 0; - } - return mouse_report; -} - -// Function to handle key events and enable/disable drag scrolling -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case DRAG_SCROLL: - // Toggle set_scrolling when DRAG_SCROLL key is pressed or released - set_scrolling = record->event.pressed; - break; - default: - break; - } - return true; -} - -// Function to handle layer changes and disable drag scrolling when not in AUTO_MOUSE_DEFAULT_LAYER -layer_state_t layer_state_set_user(layer_state_t state) { - // Disable set_scrolling if the current layer is not the AUTO_MOUSE_DEFAULT_LAYER - if (get_highest_layer(state) != AUTO_MOUSE_DEFAULT_LAYER) { - set_scrolling = false; - } - return state; -} - -``` - - -## Split Examples - -The following examples make use the `SPLIT_POINTING_ENABLE` functionality and show how to manipulate the mouse report for a scrolling mode. - -### Single Pointing Device - -The following example will work with either `POINTING_DEVICE_LEFT` or `POINTING_DEVICE_RIGHT` and enables scrolling mode while on a particular layer. - -```c - -static bool scrolling_mode = false; - -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: // If we're on the _RAISE layer enable scrolling mode - scrolling_mode = true; - pointing_device_set_cpi(2000); - break; - default: - if (scrolling_mode) { // check if we were scrolling before and set disable if so - scrolling_mode = false; - pointing_device_set_cpi(8000); - } - break; - } - return state; -} - -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { - if (scrolling_mode) { - mouse_report.h = mouse_report.x; - mouse_report.v = mouse_report.y; - mouse_report.x = 0; - mouse_report.y = 0; - } - return mouse_report; -} -``` - -### Combined Pointing Devices - -The following example requires `POINTING_DEVICE_COMBINED` and sets the left side pointing device to scroll only. - -```c -void keyboard_post_init_user(void) { - pointing_device_set_cpi_on_side(true, 1000); //Set cpi on left side to a low value for slower scrolling. - pointing_device_set_cpi_on_side(false, 8000); //Set cpi on right side to a reasonable value for mousing. -} - -report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { - left_report.h = left_report.x; - left_report.v = left_report.y; - left_report.x = 0; - left_report.y = 0; - return pointing_device_combine_reports(left_report, right_report); -} -``` - -# Troubleshooting - -If you are having issues with pointing device drivers debug messages can be enabled that will give you insights in the inner workings. To enable these add to your keyboards `config.h` file: - -```c -#define POINTING_DEVICE_DEBUG -``` - -?> The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md). - - ---- -# Automatic Mouse Layer :id=pointing-device-auto-mouse - -When using a pointing device combined with a keyboard the mouse buttons are often kept on a separate layer from the default keyboard layer, which requires pressing or holding a key to change layers before using the mouse. To make this easier and more efficient an additional pointing device feature may be enabled that will automatically activate a target layer as soon as the pointing device is active _(in motion, mouse button pressed etc.)_ and deactivate the target layer after a set time. - -Additionally if any key that is defined as a mouse key is pressed then the layer will be held as long as the key is pressed and the timer will be reset on key release. When a non-mouse key is pressed then the layer is deactivated early _(with some exceptions see below)_. Mod, mod tap, and one shot mod keys are ignored _(i.e. don't hold or activate layer but do not deactivate the layer either)_ when sending a modifier keycode _(e.g. hold for mod tap)_ allowing for mod keys to be used with the mouse without activating the target layer when typing. - -All of the standard layer keys (tap toggling, toggle, toggle on, one_shot, layer tap, layer mod) that activate the current target layer are uniquely handled to ensure they behave as expected _(see layer key table below)_. The target layer that can be changed at any point during by calling the `set_auto_mouse_layer();` function. - -### Behaviour of Layer keys that activate the target layer -| Layer key as in `keymap.c` | Auto Mouse specific behaviour | -| -------------------------- | --------------------------------------------------------------------------------------------------------------------- | -| `MO()` | Treated as a mouse key holding the layer while pressed | -| `LT()` | When tapped will be treated as non mouse key and mouse key when held | -| `LM()` | Treated as a mouse key | -| `TG()` | Will set flag preventing target layer deactivation or removal until pressed again | -| `TO()` | Same as `TG()` | -| `TT()` | Treated as a mouse key when `tap.count < TAPPING_TOGGLE` and as `TG` when `tap.count == TAPPING_TOGGLE` | -| `DF()` | Skips auto mouse key processing similar to mod keys | -| `OSL()` | Skips, but if current one shot layer is the target layer then it will prevent target layer deactivation or removal | - - -## How to enable: - -```c -// in config.h: -#define POINTING_DEVICE_AUTO_MOUSE_ENABLE -// only required if not setting mouse layer elsewhere -#define AUTO_MOUSE_DEFAULT_LAYER - -// in keymap.c: -void pointing_device_init_user(void) { - set_auto_mouse_layer(); // only required if AUTO_MOUSE_DEFAULT_LAYER is not set to index of - set_auto_mouse_enable(true); // always required before the auto mouse feature will work -} -``` - -Because the auto mouse feature can be disabled/enabled during runtime and starts as disabled by default it must be enabled by calling `set_auto_mouse_enable(true);` somewhere in firmware before the feature will work. -_Note: for setting the target layer during initialization either setting `AUTO_MOUSE_DEFAULT_LAYER` in `config.h` or calling `set_auto_mouse_layer()` can be used._ - - -## How to Customize: - -There are a few ways to control the auto mouse feature with both `config.h` options and functions for controlling it during runtime. - -### `config.h` Options: -| Define | Description | Range | Units | Default | -| ----------------------------------- | --------------------------------------------------------------------- | :------------------: | :---------: | -------------------------: | -| `POINTING_DEVICE_AUTO_MOUSE_ENABLE` | (Required) Enables auto mouse layer feature | | _None_ | _Not defined_ | -| `AUTO_MOUSE_DEFAULT_LAYER` | (Optional) Index of layer to use as default target layer | 0 - `LAYER_MAX` | _`uint8_t`_ | `1` | -| `AUTO_MOUSE_TIME` | (Optional) Time layer remains active after activation | _ideally_ (250-1000) | _ms_ | `650 ms` | -| `AUTO_MOUSE_DELAY` | (Optional) Lockout time after non-mouse key is pressed | _ideally_ (100-1000) | _ms_ | `TAPPING_TERM` or `200 ms` | -| `AUTO_MOUSE_DEBOUNCE` | (Optional) Time delay from last activation to next update | _ideally_ (10 - 100) | _ms_ | `25 ms` | - -### Adding mouse keys - -While all default mouse keys and layer keys(for current mouse layer) are treated as mouse keys, additional Keyrecords can be added to mouse keys by adding them to the is_mouse_record_* stack. - -#### Callbacks for setting up additional key codes as mouse keys: -| Callback | Description | -| -------------------------------------------------------------------- | -------------------------------------------------- | -| `bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record)` | keyboard level callback for adding mouse keys | -| `bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record)` | user/keymap level callback for adding mouse keys | - -##### To use the callback function to add mouse keys: - -The following code will cause the enter key and all of the arrow keys to be treated as mouse keys (hold target layer while they are pressed and reset active layer timer). -```c - -// in .c: -bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) { - switch(keycode) { - case KC_ENT: - return true; - case KC_RIGHT ... KC_UP: - return true; - default: - return false; - } - return is_mouse_record_user(keycode, record); -} -``` - - -## Advanced control - -There are several functions that allow for more advanced interaction with the auto mouse feature allowing for greater control. - -### Functions to control auto mouse enable and target layer: -| Function | Description | Aliases | Return type | -| :--------------------------------------------------------- | ------------------------------------------------------------------------------------ | ------------------------- | --------------: | -| `set_auto_mouse_enable(bool enable)` | Enable or disable auto mouse (true:enable, false:disable) | | `void`(None) | -| `get_auto_mouse_enable(void)` | Return auto mouse enable state (true:enabled, false:disabled) | `AUTO_MOUSE_ENABLED` | `bool` | -| `set_auto_mouse_layer(uint8_t LAYER)` | Change/set the target layer for auto mouse | | `void`(None) | -| `get_auto_mouse_layer(void)` | Return auto mouse target layer index | `AUTO_MOUSE_TARGET_LAYER` | `uint8_t` | -| `remove_auto_mouse_layer(layer_state_t state, bool force)` | Return `state` with target layer removed if appropriate (ignore criteria if `force`) | | `layer_state_t` | -| `auto_mouse_layer_off(void)` | Disable target layer if appropriate will call (makes call to `layer_state_set`) | | `void`(None) | -| `auto_mouse_toggle(void)` | Toggle on/off target toggle state (disables layer deactivation when true) | | `void`(None) | -| `get_auto_mouse_toggle(void)` | Return value of toggling state variable | | `bool` | -| `set_auto_mouse_timeout(uint16_t timeout)` | Change/set the timeout for turing off the layer | | `void`(None) | -| `get_auto_mouse_timeout(void)` | Return the current timeout for turing off the layer | | `uint16_t` | -| `set_auto_mouse_debounce(uint16_t timeout)` | Change/set the debounce for preventing layer activation | | `void`(None) | -| `get_auto_mouse_debounce(void)` | Return the current debounce for preventing layer activation | | `uint8_t` | - -_NOTES:_ - - _Due to the nature of how some functions work, the `auto_mouse_trigger_reset`, and `auto_mouse_layer_off` functions should never be called in the `layer_state_set_*` stack as this can cause indefinite loops._ - - _It is recommended that `remove_auto_mouse_layer` is used in the `layer_state_set_*` stack of functions and `auto_mouse_layer_off` is used everywhere else_ - - _`remove_auto_mouse_layer(state, false)` or `auto_mouse_layer_off()` should be called before any instance of `set_auto_mouse_enabled(false)` or `set_auto_mouse_layer(layer)` to ensure that the target layer will be removed appropriately before disabling auto mouse or changing target to avoid a stuck layer_ - -### Functions for handling custom key events: -| Function | Description | Return type | -| :--------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------: | -| `auto_mouse_keyevent(bool pressed)` | Auto mouse mouse key event (true: key down, false: key up) | `void`(None) | -| `auto_mouse_trigger_reset(bool pressed)` | Reset auto mouse status on key down and start delay timer (non-mouse key event) | `void`(None) | -| `auto_mouse_toggle(void)` | Toggle on/off target toggle state (disables layer deactivation when true) | `void`(None) | -| `get_auto_mouse_toggle(void)` | Return value of toggling state variable | `bool` | -_NOTE: Generally it would be preferable to use the `is_mouse_record_*` functions to add any additional keys that should act as mouse keys rather than adding `auto_mouse_keyevent(record.event->pressed)` to `process_records_*`_ - -### Advanced control examples - -#### Disable auto mouse on certain layers: - -The auto mouse feature can be disabled any time and this can be helpful if you want to disable the auto mouse feature under certain circumstances such as when particular layers are active. One issue however is the handling of the target layer, it needs to be removed appropriately **before** disabling auto mouse _(see notes under control functions above)_. The following function would disable the auto_mouse feature whenever the layers `_LAYER5` through `_LAYER7` are active as the top most layer _(ignoring target layer)_. - -```c -// in keymap.c: -layer_state_t layer_state_set_user(layer_state_t state) { - // checks highest layer other than target layer - switch(get_highest_layer(remove_auto_mouse_layer(state, true))) { - case _LAYER5 ... _LAYER7: - // remove_auto_mouse_target must be called to adjust state *before* setting enable - state = remove_auto_mouse_layer(state, false); - set_auto_mouse_enable(false); - break; - default: - set_auto_mouse_enable(true); - break; - } - // recommend that any code that makes adjustment based on auto mouse layer state would go here - return state; -} -``` - -#### Set different target layer when a particular layer is active: - -The below code will change the auto mouse layer target to `_MOUSE_LAYER_2` when `_DEFAULT_LAYER_2` is highest default layer state. -*NOTE: that `auto_mouse_layer_off` is used here instead of `remove_auto_mouse_layer` as `default_layer_state_set_*` stack is separate from the `layer_state_set_*` stack* if something similar was to be done in `layer_state_set_user `state = remove_auto_mouse_layer(state, false)` should be used instead -*ADDITIONAL NOTE: `AUTO_MOUSE_TARGET_LAYER` is checked if already set to avoid deactivating the target layer unless needed* - -```c -// in keymap.c -layer_state_t default_layer_state_set_user(layer_state_t state) { - // switch on change in default layer need to check if target layer already set to avoid turning off layer needlessly - switch(get_highest_layer(state)) { - case _DEFAULT_LAYER_2: - if ((AUTO_MOUSE_TARGET_LAYER) == _MOUSE_LAYER_2) break; - auto_mouse_layer_off(); - set_auto_mouse_layer(_MOUSE_LAYER_2); - break; - - default: - if((AUTO_MOUSE_TARGET_LAYER) == _MOUSE_LAYER_1) break; - auto_mouse_layer_off(); - set_auto_mouse_layer(_MOUSE_LAYER_1); - } - return state; -} -``` - -### Use custom keys to control auto mouse: -Custom key records could also be created that control the auto mouse feature. -The code example below would create a custom key that would toggle the auto mouse feature on and off when pressed while also setting a bool that could be used to disable other code that may turn it on such as the layer code above. - -```c -// in config.h: -enum user_custom_keycodes { - AM_Toggle = SAFE_RANGE -}; - -// in keymap.c: -// set up global bool to adjust other user code -bool auto_mouse_tg_off = !AUTO_MOUSE_ENABLED; - -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - // toggle auto mouse enable key - case AM_Toggle: - if(record->event.pressed) { // key down - auto_mouse_layer_off(); // disable target layer if needed - set_auto_mouse_enabled((AUTO_MOUSE_ENABLED) ^ 1); - auto_mouse_tg_off = !get_auto_mouse_enabled(); - } // do nothing on key up - return false; // prevent further processing of keycode - } -} -``` - - -## Customize Target Layer Activation - -Layer activation can be customized by overwriting the `auto_mouse_activation` function. This function is checked every time `pointing_device_task` is called when inactive and every `AUTO_MOUSE_DEBOUNCE` ms when active, and will evaluate pointing device level conditions that trigger target layer activation. When it returns true, the target layer will be activated barring the usual exceptions _(e.g. delay time has not expired)_. - -By default it will return true if any of the `mouse_report` axes `x`,`y`,`h`,`v` are non zero, or if there is any mouse buttons active in `mouse_report`. -_Note: The Cirque pinnacle track pad already implements a custom activation function that will activate on touchdown as well as movement all of the default conditions, currently this only works for the master side of split keyboards._ - -| Function | Description | Return type | -| :--------------------------------------------------------- | -------------------------------------------------------------------------------- | --------------: | -| `auto_mouse_activation(report_mouse_t mouse_report)` | Overwritable function that controls target layer activation (when true) | `bool` | - -## Auto Mouse for Custom Pointing Device Task - -When using a custom pointing device (overwriting `pointing_device_task`) the following code should be somewhere in the `pointing_device_task_*` stack: - -```c -bool pointing_device_task(void) { - //...Custom pointing device task code - - // handle automatic mouse layer (needs report_mouse_t as input) - pointing_device_task_auto_mouse(local_mouse_report); - - //...More custom pointing device task code - - return pointing_device_send(); -} -``` - -In general the following two functions must be implemented in appropriate locations for auto mouse to function: - -| Function | Description | Suggested location | -| -------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------------: | -| `pointing_device_task_auto_mouse(report_mouse_t mouse_report)` | handles target layer activation and is_active status updates | `pointing_device_task` stack | -| `process_auto_mouse(uint16_t keycode, keyrecord_t* record)` | Keycode processing for auto mouse | `process_record` stack | diff --git a/docs/feature_programmable_button.md b/docs/feature_programmable_button.md deleted file mode 100644 index 43a9e7fc1602..000000000000 --- a/docs/feature_programmable_button.md +++ /dev/null @@ -1,144 +0,0 @@ -# Programmable Button :id=programmable-button - -Programmable Buttons are keys that have no predefined meaning. This means they can be processed on the host side by custom software without the operating system trying to interpret them. - -The keycodes are emitted according to the HID Telephony Device page (`0x0B`), Programmable Button usage (`0x07`). On Linux (> 5.14) they are handled automatically and translated to `KEY_MACRO#` keycodes (up to `KEY_MACRO30`). - -?> Currently there is no known support in Windows or macOS. It may be possible to write a custom HID driver to receive these usages, but this is out of the scope of the QMK documentation. - -## Usage :id=usage - -Add the following to your `rules.mk`: - -```make -PROGRAMMABLE_BUTTON_ENABLE = yes -``` - -## Keycodes :id=keycodes - -|Key |Aliases|Description | -|---------------------------|-------|----------------------| -|`QK_PROGRAMMABLE_BUTTON_1` |`PB_1` |Programmable button 1 | -|`QK_PROGRAMMABLE_BUTTON_2` |`PB_2` |Programmable button 2 | -|`QK_PROGRAMMABLE_BUTTON_3` |`PB_3` |Programmable button 3 | -|`QK_PROGRAMMABLE_BUTTON_4` |`PB_4` |Programmable button 4 | -|`QK_PROGRAMMABLE_BUTTON_5` |`PB_5` |Programmable button 5 | -|`QK_PROGRAMMABLE_BUTTON_6` |`PB_6` |Programmable button 6 | -|`QK_PROGRAMMABLE_BUTTON_7` |`PB_7` |Programmable button 7 | -|`QK_PROGRAMMABLE_BUTTON_8` |`PB_8` |Programmable button 8 | -|`QK_PROGRAMMABLE_BUTTON_9` |`PB_9` |Programmable button 9 | -|`QK_PROGRAMMABLE_BUTTON_10`|`PB_10`|Programmable button 10| -|`QK_PROGRAMMABLE_BUTTON_11`|`PB_11`|Programmable button 11| -|`QK_PROGRAMMABLE_BUTTON_12`|`PB_12`|Programmable button 12| -|`QK_PROGRAMMABLE_BUTTON_13`|`PB_13`|Programmable button 13| -|`QK_PROGRAMMABLE_BUTTON_14`|`PB_14`|Programmable button 14| -|`QK_PROGRAMMABLE_BUTTON_15`|`PB_15`|Programmable button 15| -|`QK_PROGRAMMABLE_BUTTON_16`|`PB_16`|Programmable button 16| -|`QK_PROGRAMMABLE_BUTTON_17`|`PB_17`|Programmable button 17| -|`QK_PROGRAMMABLE_BUTTON_18`|`PB_18`|Programmable button 18| -|`QK_PROGRAMMABLE_BUTTON_19`|`PB_19`|Programmable button 19| -|`QK_PROGRAMMABLE_BUTTON_20`|`PB_20`|Programmable button 20| -|`QK_PROGRAMMABLE_BUTTON_21`|`PB_21`|Programmable button 21| -|`QK_PROGRAMMABLE_BUTTON_22`|`PB_22`|Programmable button 22| -|`QK_PROGRAMMABLE_BUTTON_23`|`PB_23`|Programmable button 23| -|`QK_PROGRAMMABLE_BUTTON_24`|`PB_24`|Programmable button 24| -|`QK_PROGRAMMABLE_BUTTON_25`|`PB_25`|Programmable button 25| -|`QK_PROGRAMMABLE_BUTTON_26`|`PB_26`|Programmable button 26| -|`QK_PROGRAMMABLE_BUTTON_27`|`PB_27`|Programmable button 27| -|`QK_PROGRAMMABLE_BUTTON_28`|`PB_28`|Programmable button 28| -|`QK_PROGRAMMABLE_BUTTON_29`|`PB_29`|Programmable button 29| -|`QK_PROGRAMMABLE_BUTTON_30`|`PB_30`|Programmable button 30| -|`QK_PROGRAMMABLE_BUTTON_31`|`PB_31`|Programmable button 31| -|`QK_PROGRAMMABLE_BUTTON_32`|`PB_32`|Programmable button 32| - -## API :id=api - -### `void programmable_button_clear(void)` :id=api-programmable-button-clear - -Clear the programmable button report. - ---- - -### `void programmable_button_add(uint8_t index)` :id=api-programmable-button-add - -Set the state of a button. - -#### Arguments :id=api-programmable-button-add-arguments - - - `uint8_t index` - The index of the button to press, from 0 to 31. - ---- - -### `void programmable_button_remove(uint8_t index)` :id=api-programmable-button-remove - -Reset the state of a button. - -#### Arguments :id=api-programmable-button-remove-arguments - - - `uint8_t index` - The index of the button to release, from 0 to 31. - ---- - -### `void programmable_button_register(uint8_t index)` :id=api-programmable-button-register - -Set the state of a button, and flush the report. - -#### Arguments :id=api-programmable-button-register-arguments - - - `uint8_t index` - The index of the button to press, from 0 to 31. - ---- - -### `void programmable_button_unregister(uint8_t index)` :id=api-programmable-button-unregister - -Reset the state of a button, and flush the report. - -#### Arguments :id=api-programmable-button-unregister-arguments - - - `uint8_t index` - The index of the button to release, from 0 to 31. - ---- - -### `bool programmable_button_is_on(uint8_t index)` :id=api-programmable-button-is-on - -Get the state of a button. - -#### Arguments :id=api-programmable-button-is-on-arguments - - - `uint8_t index` - The index of the button to check, from 0 to 31. - -#### Return Value :id=api-programmable-button-is-on-return - -`true` if the button is pressed. - ---- - -### `void programmable_button_flush(void)` :id=api-programmable-button-flush - -Send the programmable button report to the host. - ---- - -### `uint32_t programmable_button_get_report(void)` :id=api-programmable-button-get-report - -Get the programmable button report. - -#### Return Value :id=api-programmable-button-get-report-return - -The bitmask of programmable button states. - ---- - -### `void programmable_button_set_report(uint32_t report)` :id=api-programmable-button-set-report - -Set the programmable button report. - -#### Arguments :id=api-programmable-button-set-report-arguments - - - `uint32_t report` - A bitmask of programmable button states. diff --git a/docs/feature_ps2_mouse.md b/docs/feature_ps2_mouse.md deleted file mode 100644 index e714d9b86763..000000000000 --- a/docs/feature_ps2_mouse.md +++ /dev/null @@ -1,326 +0,0 @@ -# PS/2 Mouse Support :id=ps2-mouse-support - -Its possible to hook up a PS/2 mouse (for example touchpads or trackpoints) to your keyboard as a composite device. - -To hook up a Trackpoint, you need to obtain a Trackpoint module (i.e. harvest from a Thinkpad keyboard), identify the function of each pin of the module, and make the necessary circuitry between controller and Trackpoint module. For more information, please refer to [Trackpoint Hardware](https://deskthority.net/wiki/TrackPoint_Hardware) page on Deskthority Wiki. - -There are three available modes for hooking up PS/2 devices: USART (best), interrupts (better) or busywait (not recommended). - -## The Circuitry between Trackpoint and Controller :id=the-circuitry-between-trackpoint-and-controller - -To get the things working, a 4.7K drag is needed between the two lines DATA and CLK and the line 5+. - -``` - - DATA ----------+--------- PIN - | - 4.7K - | -MODULE 5+ --------+--+--------- PWR CONTROLLER - | - 4.7K - | - CLK ------+------------ PIN -``` - - -## Busywait Version :id=busywait-version - -Note: This is not recommended, you may encounter jerky movement or unsent inputs. Please use interrupt or USART version if possible. - -In rules.mk: - -```make -PS2_MOUSE_ENABLE = yes -PS2_ENABLE = yes -PS2_DRIVER = busywait -``` - -In your keyboard config.h: - -```c -#ifdef PS2_DRIVER_BUSYWAIT -# define PS2_CLOCK_PIN D1 -# define PS2_DATA_PIN D2 -#endif -``` - -### Interrupt Version (AVR/ATMega32u4) :id=interrupt-version-avr - -The following example uses D2 for clock and D5 for data. You can use any INT or PCINT pin for clock, and any pin for data. - -In rules.mk: - -```make -PS2_MOUSE_ENABLE = yes -PS2_ENABLE = yes -PS2_DRIVER = interrupt -``` - -In your keyboard config.h: - -```c -#ifdef PS2_DRIVER_INTERRUPT -#define PS2_CLOCK_PIN D2 -#define PS2_DATA_PIN D5 - -#define PS2_INT_INIT() do { \ - EICRA |= ((1<Z key types another "`z`." This is useful for -typing doubled letters, like the `z` in "`dazzle`": a double tap on Z -can instead be a roll from Z to Repeat, which is -potentially faster and more comfortable. The Repeat Key is also useful for -hotkeys, like repeating Ctrl + Shift + Right Arrow to select by word. - -Repeat Key remembers mods that were active with the last key press. These mods -are combined with any additional mods while pressing the Repeat Key. If the last -press key was Ctrl + Z, then Shift + -Repeat performs Ctrl + Shift + `Z`. - -## How do I enable Repeat Key - -In your `rules.mk`, add: - -```make -REPEAT_KEY_ENABLE = yes -``` - -Then pick a key in your keymap and assign it the keycode `QK_REPEAT_KEY` (short -alias `QK_REP`). Optionally, use the keycode `QK_ALT_REPEAT_KEY` (short alias -`QK_AREP`) on another key. - -## Keycodes - -|Keycode |Aliases |Description | -|-----------------------|---------|-------------------------------------| -|`QK_REPEAT_KEY` |`QK_REP` |Repeat the last pressed key | -|`QK_ALT_REPEAT_KEY` |`QK_AREP`|Perform alternate of the last key | - -## Alternate Repeating - -The Alternate Repeat Key performs the "alternate" action of the last pressed key -if it is defined. By default, Alternate Repeat is defined for navigation keys to -act in the reverse direction. When the last key is the common "select by word" -hotkey Ctrl + Shift + Right Arrow, the Alternate Repeat Key performs Ctrl + -Shift + Left Arrow, which together with the Repeat Key enables convenient -selection by words in either direction. - -Alternate Repeat is enabled with the Repeat Key by default. Optionally, to -reduce firmware size, Alternate Repeat may be disabled by adding in config.h: - -```c -#define NO_ALT_REPEAT_KEY -``` - -The following alternate keys are defined by default. See -`get_alt_repeat_key_keycode_user()` below for how to change or add to these -definitions. Where it makes sense, these definitions also include combinations -with mods, like Ctrl + Left ↔ Ctrl + Right Arrow. - -**Navigation** - -|Keycodes |Description | -|-----------------------------------|-----------------------------------| -|`KC_LEFT` ↔ `KC_RGHT` | Left ↔ Right Arrow | -|`KC_UP` ↔ `KC_DOWN` | Up ↔ Down Arrow | -|`KC_HOME` ↔ `KC_END` | Home ↔ End | -|`KC_PGUP` ↔ `KC_PGDN` | Page Up ↔ Page Down | -|`KC_MS_L` ↔ `KC_MS_R` | Mouse Cursor Left ↔ Right | -|`KC_MS_U` ↔ `KC_MS_D` | Mouse Cursor Up ↔ Down | -|`KC_WH_L` ↔ `KC_WH_R` | Mouse Wheel Left ↔ Right | -|`KC_WH_U` ↔ `KC_WH_D` | Mouse Wheel Up ↔ Down | - -**Misc** - -|Keycodes |Description | -|-----------------------------------|-----------------------------------| -|`KC_BSPC` ↔ `KC_DEL` | Backspace ↔ Delete | -|`KC_LBRC` ↔ `KC_RBRC` | `[` ↔ `]` | -|`KC_LCBR` ↔ `KC_RCBR` | `{` ↔ `}` | - -**Media** - -|Keycodes |Description | -|-----------------------------------|-----------------------------------| -|`KC_WBAK` ↔ `KC_WFWD` | Browser Back ↔ Forward | -|`KC_MNXT` ↔ `KC_MPRV` | Next ↔ Previous Media Track | -|`KC_MFFD` ↔ `KC_MRWD` | Fast Forward ↔ Rewind Media | -|`KC_VOLU` ↔ `KC_VOLD` | Volume Up ↔ Down | -|`KC_BRIU` ↔ `KC_BRID` | Brightness Up ↔ Down | - -**Hotkeys in Vim, Emacs, and other programs** - -|Keycodes |Description | -|-----------------------------------|-----------------------------------| -|mod + `KC_F` ↔ mod + `KC_B` | Forward ↔ Backward | -|mod + `KC_D` ↔ mod + `KC_U` | Down ↔ Up | -|mod + `KC_N` ↔ mod + `KC_P` | Next ↔ Previous | -|mod + `KC_A` ↔ mod + `KC_E` | Home ↔ End | -|mod + `KC_O` ↔ mod + `KC_I` | Vim jump list Older ↔ Newer | -|`KC_J` ↔ `KC_K` | Down ↔ Up | -|`KC_H` ↔ `KC_L` | Left ↔ Right | -|`KC_W` ↔ `KC_B` | Forward ↔ Backward by Word | - -(where above, "mod" is Ctrl, Alt, or GUI) - - -## Defining alternate keys - -Use the `get_alt_repeat_key_keycode_user()` callback to define the "alternate" -for additional keys or override the default definitions. For example, to define -Ctrl + Y as the alternate of Ctrl + Z, and vice versa, add the following in -keymap.c: - -```c -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - if ((mods & MOD_MASK_CTRL)) { // Was Ctrl held? - switch (keycode) { - case KC_Y: return C(KC_Z); // Ctrl + Y reverses to Ctrl + Z. - case KC_Z: return C(KC_Y); // Ctrl + Z reverses to Ctrl + Y. - } - } - - return KC_TRNS; // Defer to default definitions. -} -``` - -The `keycode` and `mods` args are the keycode and mods that were active with the -last pressed key. The meaning of the return value from this function is: - -* `KC_NO` – do nothing (any predefined alternate key is not used); -* `KC_TRNS` – use the default alternate key if it exists; -* anything else – use the specified keycode. Any keycode may be returned - as an alternate key, including custom keycodes. - -Another example, defining Shift + Tab as the alternate of Tab, and vice versa: - -```c -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - bool shifted = (mods & MOD_MASK_SHIFT); // Was Shift held? - switch (keycode) { - case KC_TAB: - if (shifted) { // If the last key was Shift + Tab, - return KC_TAB; // ... the reverse is Tab. - } else { // Otherwise, the last key was Tab, - return S(KC_TAB); // ... and the reverse is Shift + Tab. - } - } - - return KC_TRNS; -} -``` - -#### Eliminating SFBs - -Alternate Repeat can be configured more generally to perform an action that -"complements" the last key. Alternate Repeat is not limited to reverse -repeating, and it need not be symmetric. You can use it to eliminate cases of -same-finger bigrams in your layout, that is, pairs of letters typed by the same -finger. The following addresses the top 5 same-finger bigrams in English on -QWERTY, so that for instance "`ed`" may be typed as E, Alt -Repeat. - -```c -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - switch (keycode) { - case KC_E: return KC_D; // For "ED" bigram. - case KC_D: return KC_E; // For "DE" bigram. - case KC_C: return KC_E; // For "CE" bigram. - case KC_L: return KC_O; // For "LO" bigram. - case KC_U: return KC_N; // For "UN" bigram. - } - - return KC_TRNS; -} -``` - -#### Typing shortcuts - -A useful possibility is having Alternate Repeat press [a -macro](feature_macros.md). This way macros can be used without having to -dedicate keys to them. The following defines a couple shortcuts. - -* Typing K, Alt Repeat produces "`keyboard`," with the - initial "`k`" typed as usual and the "`eybord`" produced by the macro. -* Typing ., Alt Repeat produces "`../`," handy for "up - directory" on the shell. Similary, . types the initial "`.`" and - "`./`" is produced by the macro. - -```c -enum custom_keycodes { - M_KEYBOARD = SAFE_RANGE, - M_UPDIR, - // Other custom keys... -}; - -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - switch (keycode) { - case KC_K: return M_KEYBOARD; - case KC_DOT: return M_UPDIR; - } - - return KC_TRNS; -} - -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case M_KEYBOARD: SEND_STRING(/*k*/"eyboard"); break; - case M_UPDIR: SEND_STRING(/*.*/"./"); break; - } - return true; -} -``` - -## Ignoring certain keys and mods - -In tracking what is "the last key" to be repeated or alternate repeated, -modifier and layer switch keys are always ignored. This makes it possible to set -some mods and change layers between pressing a key and repeating it. By default, -all other (non-modifier, non-layer switch) keys are remembered so that they are -eligible for repeating. To configure additional keys to be ignored, define -`remember_last_key_user()` in your keymap.c. - -#### Ignoring a key - -The following ignores the Backspace key: - -```c -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, - uint8_t* remembered_mods) { - switch (keycode) { - case KC_BSPC: - return false; // Ignore backspace. - } - - return true; // Other keys can be repeated. -} -``` - -Then for instance, the Repeat key in Left Arrow, -Backspace, Repeat sends Left Arrow again instead of -repeating Backspace. - -The `remember_last_key_user()` callback is called on every key press excluding -modifiers and layer switches. Returning true indicates the key is remembered, -while false means it is ignored. - -#### Filtering remembered mods - -The `remembered_mods` arg represents the mods that will be remembered with -this key. It can be modified to forget certain mods. This may be -useful to forget capitalization when repeating shifted letters, so that "Aaron" -does not becom "AAron": - -```c -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, - uint8_t* remembered_mods) { - // Forget Shift on letter keys when Shift or AltGr are the only mods. - switch (keycode) { - case KC_A ... KC_Z: - if ((*remembered_mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_RALT))) == 0) { - *remembered_mods &= ~MOD_MASK_SHIFT; - } - break; - } - - return true; -} -``` - -#### Further conditions - -Besides checking the keycode, this callback could also make conditions based on -the current layer state (with `IS_LAYER_ON(layer)`) or mods (`get_mods()`). For -example, the following ignores keys on layer 2 as well as key combinations -involving GUI: - -```c -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, - uint8_t* remembered_mods) { - if (IS_LAYER_ON(2) || (get_mods() & MOD_MASK_GUI)) { - return false; // Ignore layer 2 keys and GUI chords. - } - - return true; // Other keys can be repeated. -} -``` - -?> See [Layer Functions](feature_layers.md#functions) and [Checking Modifier -State](feature_advanced_keycodes.md#checking-modifier-state) for further -details. - - -## Handle how a key is repeated - -By default, pressing the Repeat Key will simply behave as if the last key -were pressed again. This also works with macro keys with custom handlers, -invoking the macro again. In case fine-tuning is needed for sensible repetition, -you can handle how a key is repeated with `get_repeat_key_count()` within -`process_record_user()`. - -The `get_repeat_key_count()` function returns a signed count of times the key -has been repeated or alternate repeated. When a key is pressed as usual, -`get_repeat_key_count()` is 0. On the first repeat, it is 1, then the second -repeat, 2, and so on. Negative counts are used similarly for alternate -repeating. For instance supposing `MY_MACRO` is a custom keycode used in the -layout: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case MY_MACRO: - if (get_repeat_key_count() > 0) { - // MY_MACRO is being repeated! - if (record->event.pressed) { - SEND_STRING("repeat!"); - } - } else { - // MY_MACRO is being used normally. - if (record->event.pressed) { - SEND_STRING("macro"); - } - } - return false; - - // Other macros... - } - return true; -} -``` - -## Handle how a key is alternate repeated - -Pressing the Alternate Repeat Key behaves as if the "alternate" of the last -pressed key were pressed, if an alternate is defined. To define how a particular -key is alternate repeated, use the `get_alt_repeat_key_keycode_user()` callback -as described above to define which keycode to use as its alternate. Beyond this, -`get_repeat_key_count()` may be used in custom handlers to fine-tune behavior -when alternate repeating. - -The following example defines `MY_MACRO` as its own alternate, and specially -handles repeating and alternate repeating: - -```c -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - switch (keycode) { - case MY_MACRO: return MY_MACRO; // MY_MACRO is its own alternate. - } - return KC_TRNS; -} - -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case MY_MACRO: - if (get_repeat_key_count() > 0) { // Repeating. - if (record->event.pressed) { - SEND_STRING("repeat!"); - } - } else if (get_repeat_key_count() < 0) { // Alternate repeating. - if (record->event.pressed) { - SEND_STRING("alt repeat!"); - } - } else { // Used normally. - if (record->event.pressed) { - SEND_STRING("macro"); - } - } - return false; - - // Other macros... - } - return true; -} -``` - - -## Functions - -| Function | Description | -|--------------------------------|------------------------------------------------------------------------| -| `get_last_keycode()` | The last key's keycode, the key to be repeated. | -| `get_last_mods()` | Mods to apply when repeating. | -| `set_last_keycode(kc)` | Set the keycode to be repeated. | -| `set_last_mods(mods)` | Set the mods to apply when repeating. | -| `get_repeat_key_count()` | Signed count of times the key has been repeated or alternate repeated. | -| `get_alt_repeat_key_keycode()` | Keycode to be used for alternate repeating. | - - -## Additional "Alternate" keys - -By leveraging `get_last_keycode()` in macros, it is possible to define -additional, distinct "Alternate Repeat"-like keys. The following defines two -keys `ALTREP2` and `ALTREP3` and implements ten shortcuts with them for common -English 5-gram letter patterns, taking inspiration from -[Stenotype](feature_stenography.md): - - -| Typing | Produces | Typing | Produces | -|----------------------------------|----------|----------------------------------|----------| -| A, ALTREP2 | `ation` | A, ALTREP3 | `about` | -| I, ALTREP2 | `ition` | I, ALTREP3 | `inter` | -| S, ALTREP2 | `ssion` | S, ALTREP3 | `state` | -| T, ALTREP2 | `their` | T, ALTREP3 | `there` | -| W, ALTREP2 | `which` | W, ALTREP3 | `would` | - -```c -enum custom_keycodes { - ALTREP2 = SAFE_RANGE, - ALTREP3, -}; - -// Use ALTREP2 and ALTREP3 in your layout... - -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, - uint8_t* remembered_mods) { - switch (keycode) { - case ALTREP2: - case ALTREP3: - return false; // Ignore ALTREP keys. - } - - return true; // Other keys can be repeated. -} - -static void process_altrep2(uint16_t keycode, uint8_t mods) { - switch (keycode) { - case KC_A: SEND_STRING(/*a*/"tion"); break; - case KC_I: SEND_STRING(/*i*/"tion"); break; - case KC_S: SEND_STRING(/*s*/"sion"); break; - case KC_T: SEND_STRING(/*t*/"heir"); break; - case KC_W: SEND_STRING(/*w*/"hich"); break; - } -} - -static void process_altrep3(uint16_t keycode, uint8_t mods) { - switch (keycode) { - case KC_A: SEND_STRING(/*a*/"bout"); break; - case KC_I: SEND_STRING(/*i*/"nter"); break; - case KC_S: SEND_STRING(/*s*/"tate"); break; - case KC_T: SEND_STRING(/*t*/"here"); break; - case KC_W: SEND_STRING(/*w*/"ould"); break; - } -} - -bool process_record_user(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case ALTREP2: - if (record->event.pressed) { - process_altrep2(get_last_keycode(), get_last_mods()); - } - return false; - - case ALTREP3: - if (record->event.pressed) { - process_altrep3(get_last_keycode(), get_last_mods()); - } - return false; - } - - return true; -} -``` - diff --git a/docs/feature_rgb_matrix.md b/docs/feature_rgb_matrix.md deleted file mode 100644 index 75f07b5e64cf..000000000000 --- a/docs/feature_rgb_matrix.md +++ /dev/null @@ -1,1096 +0,0 @@ -# RGB Matrix Lighting :id=rgb-matrix-lighting - -This feature allows you to use RGB LED matrices driven by external drivers. It hooks into the RGBLIGHT system so you can use the same keycodes as RGBLIGHT to control it. - -If you want to use single color LED's you should use the [LED Matrix Subsystem](feature_led_matrix.md) instead. - -## Driver configuration :id=driver-configuration ---- -### IS31FL3731 :id=is31fl3731 - -There is basic support for addressable RGB matrix lighting with the I2C IS31FL3731 RGB controller. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = IS31FL3731 -``` - -You can use between 1 and 4 IS31FL3731 IC's. Do not specify `DRIVER_ADDR_` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `ISSI_3731_DEGHOST` | (Optional) Set this define to enable de-ghosting by halving Vcc during blanking time | | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | -| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | | -| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | | -| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | | - -Here is an example using 2 drivers. - -```c -// This is a 7-bit address, that gets left-shifted and bit 0 -// set to 0 for write, 1 for read (as per I2C protocol) -// The address will vary depending on your wiring: -// 0b1110100 AD <-> GND -// 0b1110111 AD <-> VCC -// 0b1110101 AD <-> SCL -// 0b1110110 AD <-> SDA -#define DRIVER_ADDR_1 0b1110100 -#define DRIVER_ADDR_2 0b1110110 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 25 -#define DRIVER_2_LED_TOTAL 24 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` - -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -For split keyboards using `RGB_MATRIX_SPLIT` with an LED driver, you can either have the same driver address or different driver addresses. If using different addresses, use `DRIVER_ADDR_1` for one and `DRIVER_ADDR_2` for the other one. Then, in `g_is31_leds`, fill out the correct driver index (0 or 1). If using one address, use `DRIVER_ADDR_1` for both, and use index 0 for `g_is31_leds`. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - {0, C1_3, C2_3, C3_3}, - .... -} -``` - -Where `Cx_y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3731.pdf) and the header file `drivers/led/issi/is31fl3731.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3`). - ---- -### IS31FL3733 :id=is31fl3733 - -There is basic support for addressable RGB matrix lighting with the I2C IS31FL3733 RGB controller. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = IS31FL3733 -``` - -You can use between 1 and 4 IS31FL3733 IC's. Do not specify `DRIVER_ADDR_` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3733B only | 0 | -| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF | -| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | -| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | | -| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | | -| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | | -| `DRIVER_SYNC_1` | (Optional) Sync configuration for the first RGB driver | 0 | -| `DRIVER_SYNC_2` | (Optional) Sync configuration for the second RGB driver | 0 | -| `DRIVER_SYNC_3` | (Optional) Sync configuration for the third RGB driver | 0 | -| `DRIVER_SYNC_4` | (Optional) Sync configuration for the fourth RGB driver | 0 | - -The IS31FL3733 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows: - -| `ISSI_SWPULLUP/ISSI_CSPULLUP` | Description | -|----------------------|-------------| -| `PUR_0R` | (default) Do not use the on-chip resistors/enable de-ghosting | -| `PUR_05KR` | The 0.5k Ohm resistor used during blanking period (t_NOL) | -| `PUR_3KR` | The 3k Ohm resistor used at all times | -| `PUR_4KR` | The 4k Ohm resistor used at all times | -| `PUR_8KR` | The 8k Ohm resistor used at all times | -| `PUR_16KR` | The 16k Ohm resistor used at all times | -| `PUR_32KR` | The 32k Ohm resistor used during blanking period (t_NOL) | - -Here is an example using 2 drivers. - -```c -// This is a 7-bit address, that gets left-shifted and bit 0 -// set to 0 for write, 1 for read (as per I2C protocol) -// The address will vary depending on your wiring: -// 00 <-> GND -// 01 <-> SCL -// 10 <-> SDA -// 11 <-> VCC -// ADDR1 represents A1:A0 of the 7-bit address. -// ADDR2 represents A3:A2 of the 7-bit address. -// The result is: 0b101(ADDR2)(ADDR1) -#define DRIVER_ADDR_1 0b1010000 -#define DRIVER_ADDR_2 0b1010011 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 58 -#define DRIVER_2_LED_TOTAL 10 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` - -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Currently only 4 drivers are supported, but it would be trivial to support all 8 combinations. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - {0, B_1, A_1, C_1}, - .... -} -``` - -Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3733.pdf) and the header file `drivers/led/issi/is31fl3733.h`. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now). - ---- -### IS31FL3736 :id=is31fl3736 - -There is basic support for addressable RGB matrix lighting with the I2C IS31FL3736 RGB controller. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = IS31FL3736 -``` -You can use between 1 and 4 IS31FL3736 IC's. Do not specify `DRIVER_ADDR_` defines for IC's that are not present on your keyboard. - -Configure the hardware via your `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3736B only | 0 | -| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF | -| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | -| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | | -| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | | -| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | | - -The IS31FL3736 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows: - -| `ISSI_SWPULLUP/ISSI_CSPULLUP` | Description | -|----------------------|-------------| -| `PUR_0R` | (default) Do not use the on-chip resistors/enable de-ghosting | -| `PUR_05KR` | The 0.5k Ohm resistor used during blanking period (t_NOL) | -| `PUR_1KR` | The 1k Ohm resistor used during blanking period (t_NOL) | -| `PUR_2KR` | The 2k Ohm resistor used during blanking period (t_NOL) | -| `PUR_4KR` | The 4k Ohm resistor used during blanking period (t_NOL) | -| `PUR_8KR` | The 8k Ohm resistor during blanking period (t_NOL) | -| `PUR_16KR` | The 16k Ohm resistor during blanking period (t_NOL) | -| `PUR_32KR` | The 32k Ohm resistor used during blanking period (t_NOL) | - -Here is an example using 2 drivers. - -```c -// This is a 7-bit address, that gets left-shifted and bit 0 -// set to 0 for write, 1 for read (as per I2C protocol) -// The address will vary depending on your wiring: -// 0000 <-> GND -// 0101 <-> SCL -// 1010 <-> SDA -// 1111 <-> VCC -// ADDR represents A3:A0 of the 7-bit address. -// The result is: 0b101(ADDR) -#define DRIVER_ADDR_1 0b1010000 -#define DRIVER_ADDR_2 0b1010001 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 30 -#define DRIVER_2_LED_TOTAL 32 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - {0, B_1, A_1, C_1}, - .... -} -``` -### IS31FL3737 :id=is31fl3737 - -There is basic support for addressable RGB matrix lighting with the I2C IS31FL3737 RGB controller. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = IS31FL3737 -``` -You can use between 1 and 4 IS31FL3737 IC's. Do not specify `DRIVER_ADDR_` defines for IC's that are not present on your keyboard. - -Configure the hardware via your `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `ISSI_PWM_FREQUENCY` | (Optional) PWM Frequency Setting - IS31FL3737B only | 0 | -| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF | -| `ISSI_SWPULLUP` | (Optional) Set the value of the SWx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `ISSI_CSPULLUP` | (Optional) Set the value of the CSx lines on-chip de-ghosting resistors | PUR_0R (Disabled) | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Required) Address for the first RGB driver | | -| `DRIVER_ADDR_2` | (Optional) Address for the second RGB driver | | -| `DRIVER_ADDR_3` | (Optional) Address for the third RGB driver | | -| `DRIVER_ADDR_4` | (Optional) Address for the fourth RGB driver | | - -The IS31FL3737 IC's have on-chip resistors that can be enabled to allow for de-ghosting of the RGB matrix. By default these resistors are not enabled (`ISSI_SWPULLUP`/`ISSI_CSPULLUP` are given the value of`PUR_0R`), the values that can be set to enable de-ghosting are as follows: - -| `ISSI_SWPULLUP/ISSI_CSPULLUP` | Description | -|----------------------|-------------| -| `PUR_0R` | (default) Do not use the on-chip resistors/enable de-ghosting | -| `PUR_05KR` | The 0.5k Ohm resistor used during blanking period (t_NOL) | -| `PUR_1KR` | The 1k Ohm resistor used during blanking period (t_NOL) | -| `PUR_2KR` | The 2k Ohm resistor used during blanking period (t_NOL) | -| `PUR_4KR` | The 4k Ohm resistor used during blanking period (t_NOL) | -| `PUR_8KR` | The 8k Ohm resistor during blanking period (t_NOL) | -| `PUR_16KR` | The 16k Ohm resistor during blanking period (t_NOL) | -| `PUR_32KR` | The 32k Ohm resistor used during blanking period (t_NOL) | - -Here is an example using 2 drivers. - -```c -// This is a 7-bit address, that gets left-shifted and bit 0 -// set to 0 for write, 1 for read (as per I2C protocol) -// The address will vary depending on your wiring: -// 0000 <-> GND -// 0101 <-> SCL -// 1010 <-> SDA -// 1111 <-> VCC -// ADDR represents A3:A0 of the 7-bit address. -// The result is: 0b101(ADDR) -#define DRIVER_ADDR_1 0b1010000 -#define DRIVER_ADDR_2 0b1010001 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 30 -#define DRIVER_2_LED_TOTAL 36 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led PROGMEM g_is31_leds[RGB_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - {0, B_1, A_1, C_1}, - .... -} -``` - -Where `X_Y` is the location of the LED in the matrix defined by [the datasheet](https://www.issi.com/WW/pdf/31FL3737.pdf) and the header file `drivers/led/issi/is31fl3737.h`. The `driver` is the index of the driver you defined in your `config.h` (Only `0`, `1`, `2`, or `3` for now). - ---- -### IS31FLCOMMON :id=is31flcommon - -There is basic support for addressable RGB matrix lighting with a selection of I2C ISSI Lumissil RGB controllers through a shared common driver. To enable it, add this to your `rules.mk`: - -```makefile -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = -``` - -Where `` is the applicable LED driver chip as below - -| Driver Name | Data Sheet | Capability | -|-------------|------------|------------| -| `IS31FL3742A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3742A_DS.pdf) | 60 RGB, 30x6 Matrix | -| `IS31FL3743A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3743A_DS.pdf) | 66 RGB, 18x11 Matrix | -| `IS31FL3745` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3745_DS.pdf) | 48 RGB, 18x8 Matrix | -| `IS31FL3746A` | [datasheet](https://www.lumissil.com/assets/pdf/core/IS31FL3746A_DS.pdf) | 24 RGB, 18x4 Matrix | - -You can use between 1 and 4 IC's. Do not specify `DRIVER_ADDR_` define for IC's if not present on your keyboard. The `DRIVER_ADDR_1` default assumes that all Address pins on the controller have been connected to GND. Drivers that have SYNC functionality have the default settings to disable if 1 driver. If more than 1 drivers then `DRIVER_ADDR_1` will be set to Master and the remaining ones set to Slave. - -Configure the hardware via your `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (Optional) How long to wait for i2c messages, in milliseconds | 100 | -| `ISSI_PERSISTENCE` | (Optional) Retry failed messages this many times | 0 | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `DRIVER_ADDR_1` | (Optional) Address for the first RGB driver | | -| `DRIVER_ADDR_` | (Required) Address for the additional RGB drivers | | -| `ISSI_SSR_` | (Optional) Configuration for the Spread Spectrum Register | | -| `ISSI_CONFIGURATION` | (Optional) Configuration for the Configuration Register | | -| `ISSI_GLOBALCURRENT` | (Optional) Configuration for the Global Current Register | 0xFF | -| `ISSI_PULLDOWNUP` | (Optional) Configuration for the Pull Up & Pull Down Register | | -| `ISSI_TEMP` | (Optional) Configuration for the Temperature Register | | -| `ISSI_PWM_ENABLE` | (Optional) Configuration for the PWM Enable Register | | -| `ISSI_PWM_SET` | (Optional) Configuration for the PWM Setting Register | | -| `ISSI_SCAL_RED` | (Optional) Configuration for the RED LEDs in Scaling Registers | 0xFF | -| `ISSI_SCAL_BLUE` | (Optional) Configuration for the BLUE LEDs in Scaling Registers | 0xFF | -| `ISSI_SCAL_GREEN` | (Optional) Configuration for the GREEN LEDs in Scaling Registers | 0xFF | -| `ISSI_MANUAL_SCALING` | (Optional) If you wish to configure the Scaling Registers manually | | - - -Defaults - -| Variable | IS31FL3742A | IS31FL3743A | IS31FL3745 | IS31FL3746 | -|----------|-------------|-------------|------------|------------| -| `DRIVER_ADDR_1` | 0b0110000 | 0b0100000 | 0b0100000 | 0b1100000 | -| `ISSI_SSR_1` | 0x00 | 0x00 / 0x60 | 0x00 / 0xC0 | 0x00 | -| `ISSI_SSR_<2-4>` | 0x00 | 0x40 | 0x80 | 0x00 | -| `ISSI_CONFIGURATION` | 0x31 | 0x01 | 0x31 | 0x01 | -| `ISSI_PULLDOWNUP` | 0x55 | 0x33 | 0x33 | 0x33 | -| `ISSI_TEMP` | N/A | 0x00 | 0x00 | 0x00 | -| `ISSI_PWM_ENABLE` | N/A | N/A | N/A | 0x00 | -| `ISSI_PWM_SET` | 0x00 | N/A | N/A | 0x00 | - -Here is an example using 2 drivers. - -```c -#define DRIVER_ADDR_2 0b0100001 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 66 -#define DRIVER_2_LED_TOTAL 42 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` - -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Currently only 4 drivers are supported, but it would be trivial to support for more. Note that using a combination of different drivers is not supported. All drivers must be of the same model. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const is31_led __flash g_is31_leds[RGB_MATRIX_LED_COUNT] = { -/* Refer to IS31 manual for these locations - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - {0, CS1_SW1, CS2_SW1, CS3_SW1}, - .... -} -``` - -Where `CSx_SWx` is the location of the LED in the matrix defined by the datasheet. The `driver` is the index of the driver you defined in your `config.h` (`0`, `1`, `2`, or `3` for now). - -`ISSI_MANUAL_SCALING` is used to override the Scaling for individual LED's. By default they will be set as per `ISSI_SCAL_`. In `config.h` set how many LED's you want to manually set scaling for. -Eg `#define ISSI_MANUAL_SCALING 3` - -Then Define the array listing all the LEDs you want to override in your `.c`: - -```c -const is31_led __flash g_is31_scaling[ISSI_MANUAL_SCALING] = { - * LED Index - * | R scaling - * | | G scaling - * | | | B scaling - * | | | | */ - {5, 120, 155, 167}, - {9, 120, 155, 167}, - .... -} -``` - -Where LED Index is the position of the LED in the `g_is31_leds` array. The `scaling` value between 0 and 255 to be written to the Scaling Register. - ---- - -### WS2812 :id=ws2812 - -There is basic support for addressable RGB matrix lighting with a WS2811/WS2812{a,b,c} addressable LED strand. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = WS2812 -``` - -Configure the hardware via your `config.h`: - -```c -// The pin connected to the data pin of the LEDs -#define WS2812_DI_PIN D7 -// The number of LEDs connected -#define RGB_MATRIX_LED_COUNT 70 -``` - -?> There are additional configuration options for ARM controllers that offer increased performance over the default bitbang driver. Please see [WS2812 Driver](ws2812_driver.md) for more information. - ---- - -### APA102 :id=apa102 - -There is basic support for APA102 based addressable LED strands. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = APA102 -``` - -Configure the hardware via your `config.h`: - -```c -// The pin connected to the data pin of the LEDs -#define APA102_DI_PIN D7 -// The pin connected to the clock pin of the LEDs -#define APA102_CI_PIN D6 -// The number of LEDs connected -#define RGB_MATRIX_LED_COUNT 70 -``` - ---- -### AW20216 :id=aw20216 -There is basic support for addressable RGB matrix lighting with the SPI AW20216 RGB controller. To enable it, add this to your `rules.mk`: - -```make -RGB_MATRIX_ENABLE = yes -RGB_MATRIX_DRIVER = AW20216 -``` - -You can use up to 2 AW20216 IC's. Do not specify `DRIVER__xxx` defines for IC's that are not present on your keyboard. You can define the following items in `config.h`: - -| Variable | Description | Default | -|----------|-------------|---------| -| `DRIVER_1_CS` | (Required) MCU pin connected to first RGB driver chip select line | B13 | -| `DRIVER_2_CS` | (Optional) MCU pin connected to second RGB driver chip select line | | -| `DRIVER_1_EN` | (Required) MCU pin connected to first RGB driver hardware enable line | C13 | -| `DRIVER_2_EN` | (Optional) MCU pin connected to second RGB driver hardware enable line | | -| `DRIVER_1_LED_TOTAL` | (Required) How many RGB lights are connected to first RGB driver | | -| `DRIVER_2_LED_TOTAL` | (Optional) How many RGB lights are connected to second RGB driver | | -| `DRIVER_COUNT` | (Required) How many RGB driver IC's are present | | -| `RGB_MATRIX_LED_COUNT` | (Required) How many RGB lights are present across all drivers | | -| `AW_SCALING_MAX` | (Optional) LED current scaling value (0-255, higher values mean LED is brighter at full PWM) | 150 | -| `AW_GLOBAL_CURRENT_MAX` | (Optional) Driver global current limit (0-255, higher values means the driver may consume more power) | 150 | -| `AW_SPI_MODE` | (Optional) Mode for SPI communication (0-3, defines polarity and phase of the clock) | 3 | -| `AW_SPI_DIVISOR` | (Optional) Clock divisor for SPI communication (powers of 2, smaller numbers means faster communication, should not be less than 4) | 4 | - -Here is an example using 2 drivers. - -```c -#define DRIVER_1_CS B13 -#define DRIVER_2_CS B14 -// Hardware enable lines may be connected to the same pin -#define DRIVER_1_EN C13 -#define DRIVER_2_EN C13 - -#define DRIVER_COUNT 2 -#define DRIVER_1_LED_TOTAL 66 -#define DRIVER_2_LED_TOTAL 32 -#define RGB_MATRIX_LED_COUNT (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL) -``` - -!> Note the parentheses, this is so when `RGB_MATRIX_LED_COUNT` is used in code and expanded, the values are added together before any additional math is applied to them. As an example, `rand() % (DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL)` will give very different results than `rand() % DRIVER_1_LED_TOTAL + DRIVER_2_LED_TOTAL`. - -Define these arrays listing all the LEDs in your `.c`: - -```c -const aw_led PROGMEM g_aw_leds[RGB_MATRIX_LED_COUNT] = { -/* Each AW20216 channel is controlled by a register at some offset between 0x00 - * and 0xD7 inclusive. - * See drivers/awinic/aw20216.h for the mapping between register offsets and - * driver pin locations. - * driver - * | R location - * | | G location - * | | | B location - * | | | | */ - { 0, CS1_SW1, CS2_SW1, CS3_SW1 }, - { 0, CS4_SW1, CS5_SW1, CS6_SW1 }, - { 0, CS7_SW1, CS8_SW1, CS9_SW1 }, - { 0, CS10_SW1, CS11_SW1, CS12_SW1 }, - { 0, CS13_SW1, CS14_SW1, CS15_SW1 }, - ... - { 1, CS1_SW1, CS2_SW1, CS3_SW1 }, - { 1, CS13_SW1, CS14_SW1, CS15_SW1 }, - { 1, CS16_SW1, CS17_SW1, CS18_SW1 }, - { 1, CS4_SW2, CS5_SW2, CS6_SW2 }, - ... -}; -``` - ---- - -## Common Configuration :id=common-configuration - -From this point forward the configuration is the same for all the drivers. The `led_config_t` struct provides a key electrical matrix to led index lookup table, what the physical position of each LED is on the board, and what type of key or usage the LED if the LED represents. Here is a brief example: - -```c -led_config_t g_led_config = { { - // Key Matrix to LED Index - { 5, NO_LED, NO_LED, 0 }, - { NO_LED, NO_LED, NO_LED, NO_LED }, - { 4, NO_LED, NO_LED, 1 }, - { 3, NO_LED, NO_LED, 2 } -}, { - // LED Index to Physical Position - { 188, 16 }, { 187, 48 }, { 149, 64 }, { 112, 64 }, { 37, 48 }, { 38, 16 } -}, { - // LED Index to Flag - 1, 4, 4, 4, 4, 1 -} }; -``` - -The first part, `// Key Matrix to LED Index`, tells the system what key this LED represents by using the key's electrical matrix row & col. The second part, `// LED Index to Physical Position` represents the LED's physical `{ x, y }` position on the keyboard. The default expected range of values for `{ x, y }` is the inclusive range `{ 0..224, 0..64 }`. This default expected range is due to effects that calculate the center of the keyboard for their animations. The easiest way to calculate these positions is imagine your keyboard is a grid, and the top left of the keyboard represents `{ x, y }` coordinate `{ 0, 0 }` and the bottom right of your keyboard represents `{ 224, 64 }`. Using this as a basis, you can use the following formula to calculate the physical position: - -```c -x = 224 / (NUMBER_OF_COLS - 1) * COL_POSITION -y = 64 / (NUMBER_OF_ROWS - 1) * ROW_POSITION -``` - -Where NUMBER_OF_COLS, NUMBER_OF_ROWS, COL_POSITION, & ROW_POSITION are all based on the physical layout of your keyboard, not the electrical layout. - -As mentioned earlier, the center of the keyboard by default is expected to be `{ 112, 32 }`, but this can be changed if you want to more accurately calculate the LED's physical `{ x, y }` positions. Keyboard designers can implement `#define RGB_MATRIX_CENTER { 112, 32 }` in their config.h file with the new center point of the keyboard, or where they want it to be allowing more possibilities for the `{ x, y }` values. Do note that the maximum value for x or y is 255, and the recommended maximum is 224 as this gives animations runoff room before they reset. - -`// LED Index to Flag` is a bitmask, whether or not a certain LEDs is of a certain type. It is recommended that LEDs are set to only 1 type. - -## Flags :id=flags - -|Define |Value |Description | -|----------------------------|------|-------------------------------------------------| -|`HAS_FLAGS(bits, flags)` |*n/a* |Evaluates to `true` if `bits` has all `flags` set| -|`HAS_ANY_FLAGS(bits, flags)`|*n/a* |Evaluates to `true` if `bits` has any `flags` set| -|`LED_FLAG_NONE` |`0x00`|If this LED has no flags | -|`LED_FLAG_ALL` |`0xFF`|If this LED has all flags | -|`LED_FLAG_MODIFIER` |`0x01`|If the LED is on a modifier key | -|`LED_FLAG_UNDERGLOW` |`0x02`|If the LED is for underglow | -|`LED_FLAG_KEYLIGHT` |`0x04`|If the LED is for key backlight | -|`LED_FLAG_INDICATOR` |`0x08`|If the LED is for keyboard state indication | - -## Keycodes :id=keycodes - -All RGB keycodes are currently shared with the RGBLIGHT system: - -|Key |Aliases |Description | -|-------------------|----------|--------------------------------------------------------------------------------------| -|`RGB_TOG` | |Toggle RGB lighting on or off | -|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | -|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held | -|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | -|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | -|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | -|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | -|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | -|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | -|`RGB_SPI` | |Increase effect speed (does not support eeprom yet), decrease speed when Shift is held| -|`RGB_SPD` | |Decrease effect speed (does not support eeprom yet), increase speed when Shift is held| -|`RGB_MODE_PLAIN` |`RGB_M_P` |Static (no animation) mode | -|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | -|`RGB_MODE_RAINBOW` |`RGB_M_R` |Full gradient scrolling left to right (uses the `RGB_MATRIX_CYCLE_LEFT_RIGHT` mode) | -|`RGB_MODE_SWIRL` |`RGB_M_SW`|Full gradient spinning pinwheel around center of keyboard (uses `RGB_MATRIX_CYCLE_PINWHEEL` mode) | - -* `RGB_MODE_*` keycodes will generally work, but not all of the modes are currently mapped to the correct effects for the RGB Matrix system. - -`RGB_MODE_PLAIN`, `RGB_MODE_BREATHE`, `RGB_MODE_RAINBOW`, and `RGB_MODE_SWIRL` are the only ones that are mapped properly. The rest don't have a direct equivalent, and are not mapped. - -?> `RGB_*` keycodes cannot be used with functions like `tap_code16(RGB_HUD)` as they're not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead. - - -!> By default, if you have both the [RGB Light](feature_rgblight.md) and the RGB Matrix feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature. - -## RGB Matrix Effects :id=rgb-matrix-effects - -All effects have been configured to support current configuration values (Hue, Saturation, Value, & Speed) unless otherwise noted below. These are the effects that are currently available: - -```c -enum rgb_matrix_effects { - RGB_MATRIX_NONE = 0, - RGB_MATRIX_SOLID_COLOR = 1, // Static single hue, no speed support - RGB_MATRIX_ALPHAS_MODS, // Static dual hue, speed is hue for secondary hue - RGB_MATRIX_GRADIENT_UP_DOWN, // Static gradient top to bottom, speed controls how much gradient changes - RGB_MATRIX_GRADIENT_LEFT_RIGHT, // Static gradient left to right, speed controls how much gradient changes - RGB_MATRIX_BREATHING, // Single hue brightness cycling animation - RGB_MATRIX_BAND_SAT, // Single hue band fading saturation scrolling left to right - RGB_MATRIX_BAND_VAL, // Single hue band fading brightness scrolling left to right - RGB_MATRIX_BAND_PINWHEEL_SAT, // Single hue 3 blade spinning pinwheel fades saturation - RGB_MATRIX_BAND_PINWHEEL_VAL, // Single hue 3 blade spinning pinwheel fades brightness - RGB_MATRIX_BAND_SPIRAL_SAT, // Single hue spinning spiral fades saturation - RGB_MATRIX_BAND_SPIRAL_VAL, // Single hue spinning spiral fades brightness - RGB_MATRIX_CYCLE_ALL, // Full keyboard solid hue cycling through full gradient - RGB_MATRIX_CYCLE_LEFT_RIGHT, // Full gradient scrolling left to right - RGB_MATRIX_CYCLE_UP_DOWN, // Full gradient scrolling top to bottom - RGB_MATRIX_CYCLE_OUT_IN, // Full gradient scrolling out to in - RGB_MATRIX_CYCLE_OUT_IN_DUAL, // Full dual gradients scrolling out to in - RGB_MATRIX_RAINBOW_MOVING_CHEVRON, // Full gradient Chevron shapped scrolling left to right - RGB_MATRIX_CYCLE_PINWHEEL, // Full gradient spinning pinwheel around center of keyboard - RGB_MATRIX_CYCLE_SPIRAL, // Full gradient spinning spiral around center of keyboard - RGB_MATRIX_DUAL_BEACON, // Full gradient spinning around center of keyboard - RGB_MATRIX_RAINBOW_BEACON, // Full tighter gradient spinning around center of keyboard - RGB_MATRIX_RAINBOW_PINWHEELS, // Full dual gradients spinning two halfs of keyboard - RGB_MATRIX_RAINDROPS, // Randomly changes a single key's hue - RGB_MATRIX_JELLYBEAN_RAINDROPS, // Randomly changes a single key's hue and saturation - RGB_MATRIX_HUE_BREATHING, // Hue shifts up a slight ammount at the same time, then shifts back - RGB_MATRIX_HUE_PENDULUM, // Hue shifts up a slight ammount in a wave to the right, then back to the left - RGB_MATRIX_HUE_WAVE, // Hue shifts up a slight ammount and then back down in a wave to the right - RGB_MATRIX_PIXEL_FRACTAL, // Single hue fractal filled keys pulsing horizontally out to edges - RGB_MATRIX_PIXEL_FLOW, // Pulsing RGB flow along LED wiring with random hues - RGB_MATRIX_PIXEL_RAIN, // Randomly light keys with random hues -#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) - RGB_MATRIX_TYPING_HEATMAP, // How hot is your WPM! - RGB_MATRIX_DIGITAL_RAIN, // That famous computer simulation -#endif -#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES) - RGB_MATRIX_SOLID_REACTIVE_SIMPLE, // Pulses keys hit to hue & value then fades value out - RGB_MATRIX_SOLID_REACTIVE, // Static single hue, pulses keys hit to shifted hue then fades to current hue - RGB_MATRIX_SOLID_REACTIVE_WIDE // Hue & value pulse near a single key hit then fades value out - RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE // Hue & value pulse near multiple key hits then fades value out - RGB_MATRIX_SOLID_REACTIVE_CROSS // Hue & value pulse the same column and row of a single key hit then fades value out - RGB_MATRIX_SOLID_REACTIVE_MULTICROSS // Hue & value pulse the same column and row of multiple key hits then fades value out - RGB_MATRIX_SOLID_REACTIVE_NEXUS // Hue & value pulse away on the same column and row of a single key hit then fades value out - RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS // Hue & value pulse away on the same column and row of multiple key hits then fades value out - RGB_MATRIX_SPLASH, // Full gradient & value pulse away from a single key hit then fades value out - RGB_MATRIX_MULTISPLASH, // Full gradient & value pulse away from multiple key hits then fades value out - RGB_MATRIX_SOLID_SPLASH, // Hue & value pulse away from a single key hit then fades value out - RGB_MATRIX_SOLID_MULTISPLASH, // Hue & value pulse away from multiple key hits then fades value out -#endif - RGB_MATRIX_EFFECT_MAX -}; -``` - -You can enable a single effect by defining `ENABLE_[EFFECT_NAME]` in your `config.h`: - - -|Define |Description | -|------------------------------------------------------|----------------------------------------------| -|`#define ENABLE_RGB_MATRIX_ALPHAS_MODS` |Enables `RGB_MATRIX_ALPHAS_MODS` | -|`#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN` |Enables `RGB_MATRIX_GRADIENT_UP_DOWN` | -|`#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT` |Enables `RGB_MATRIX_GRADIENT_LEFT_RIGHT` | -|`#define ENABLE_RGB_MATRIX_BREATHING` |Enables `RGB_MATRIX_BREATHING` | -|`#define ENABLE_RGB_MATRIX_BAND_SAT` |Enables `RGB_MATRIX_BAND_SAT` | -|`#define ENABLE_RGB_MATRIX_BAND_VAL` |Enables `RGB_MATRIX_BAND_VAL` | -|`#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT` |Enables `RGB_MATRIX_BAND_PINWHEEL_SAT` | -|`#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL` |Enables `RGB_MATRIX_BAND_PINWHEEL_VAL` | -|`#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT` |Enables `RGB_MATRIX_BAND_SPIRAL_SAT` | -|`#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL` |Enables `RGB_MATRIX_BAND_SPIRAL_VAL` | -|`#define ENABLE_RGB_MATRIX_CYCLE_ALL` |Enables `RGB_MATRIX_CYCLE_ALL` | -|`#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT` |Enables `RGB_MATRIX_CYCLE_LEFT_RIGHT` | -|`#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN` |Enables `RGB_MATRIX_CYCLE_UP_DOWN` | -|`#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON` |Enables `RGB_MATRIX_RAINBOW_MOVING_CHEVRON` | -|`#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN` |Enables `RGB_MATRIX_CYCLE_OUT_IN` | -|`#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL` |Enables `RGB_MATRIX_CYCLE_OUT_IN_DUAL` | -|`#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL` |Enables `RGB_MATRIX_CYCLE_PINWHEEL` | -|`#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL` |Enables `RGB_MATRIX_CYCLE_SPIRAL` | -|`#define ENABLE_RGB_MATRIX_DUAL_BEACON` |Enables `RGB_MATRIX_DUAL_BEACON` | -|`#define ENABLE_RGB_MATRIX_RAINBOW_BEACON` |Enables `RGB_MATRIX_RAINBOW_BEACON` | -|`#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS` |Enables `RGB_MATRIX_RAINBOW_PINWHEELS` | -|`#define ENABLE_RGB_MATRIX_RAINDROPS` |Enables `RGB_MATRIX_RAINDROPS` | -|`#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS` |Enables `RGB_MATRIX_JELLYBEAN_RAINDROPS` | -|`#define ENABLE_RGB_MATRIX_HUE_BREATHING` |Enables `RGB_MATRIX_HUE_BREATHING` | -|`#define ENABLE_RGB_MATRIX_HUE_PENDULUM` |Enables `RGB_MATRIX_HUE_PENDULUM` | -|`#define ENABLE_RGB_MATRIX_HUE_WAVE` |Enables `RGB_MATRIX_HUE_WAVE ` | -|`#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL` |Enables `RGB_MATRIX_PIXEL_FRACTAL` | -|`#define ENABLE_RGB_MATRIX_PIXEL_FLOW` |Enables `RGB_MATRIX_PIXEL_FLOW` | -|`#define ENABLE_RGB_MATRIX_PIXEL_RAIN` |Enables `RGB_MATRIX_PIXEL_RAIN` | - -?> These modes don't require any additional defines. - -|Framebuffer Defines |Description | -|------------------------------------------------------|----------------------------------------------| -|`#define ENABLE_RGB_MATRIX_TYPING_HEATMAP` |Enables `RGB_MATRIX_TYPING_HEATMAP` | -|`#define ENABLE_RGB_MATRIX_DIGITAL_RAIN` |Enables `RGB_MATRIX_DIGITAL_RAIN` | - -?> These modes also require the `RGB_MATRIX_FRAMEBUFFER_EFFECTS` define to be available. - -|Reactive Defines |Description | -|------------------------------------------------------|----------------------------------------------| -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE` |Enables `RGB_MATRIX_SOLID_REACTIVE_SIMPLE` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE` |Enables `RGB_MATRIX_SOLID_REACTIVE` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE` |Enables `RGB_MATRIX_SOLID_REACTIVE_WIDE` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE` |Enables `RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS` |Enables `RGB_MATRIX_SOLID_REACTIVE_CROSS` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS` |Enables `RGB_MATRIX_SOLID_REACTIVE_MULTICROSS`| -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS` |Enables `RGB_MATRIX_SOLID_REACTIVE_NEXUS` | -|`#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS` |Enables `RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS`| -|`#define ENABLE_RGB_MATRIX_SPLASH` |Enables `RGB_MATRIX_SPLASH` | -|`#define ENABLE_RGB_MATRIX_MULTISPLASH` |Enables `RGB_MATRIX_MULTISPLASH` | -|`#define ENABLE_RGB_MATRIX_SOLID_SPLASH` |Enables `RGB_MATRIX_SOLID_SPLASH` | -|`#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH` |Enables `RGB_MATRIX_SOLID_MULTISPLASH` | - -?> These modes also require the `RGB_MATRIX_KEYPRESSES` or `RGB_MATRIX_KEYRELEASES` define to be available. - - -### RGB Matrix Effect Typing Heatmap :id=rgb-matrix-effect-typing-heatmap - -This effect will color the RGB matrix according to a heatmap of recently pressed keys. Whenever a key is pressed its "temperature" increases as well as that of its neighboring keys. The temperature of each key is then decreased automatically every 25 milliseconds by default. - -In order to change the delay of temperature decrease define `RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS`: - -```c -#define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 50 -``` - -As heatmap uses the physical position of the leds set in the g_led_config, you may need to tweak the following options to get the best effect for your keyboard. Note the size of this grid is `224x64`. - -Limit the distance the effect spreads to surrounding keys. - -```c -#define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40 -``` - -Limit how hot surrounding keys get from each press. - -```c -#define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16 -``` - -Remove the spread effect entirely. - -```c -#define RGB_MATRIX_TYPING_HEATMAP_SLIM -``` - -It's also possible to adjust the tempo of *heating up*. It's defined as the number of shades that are -increased on the [HSV scale](https://en.wikipedia.org/wiki/HSL_and_HSV). Decreasing this value increases -the number of keystrokes needed to fully heat up the key. - -```c -#define RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP 32 -``` - -### RGB Matrix Effect Solid Reactive :id=rgb-matrix-effect-solid-reactive - -Solid reactive effects will pulse RGB light on key presses with user configurable hues. To enable gradient mode that will automatically change reactive color, add the following define: - -```c -#define RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE -``` - -Gradient mode will loop through the color wheel hues over time and its duration can be controlled with the effect speed keycodes (`RGB_SPI`/`RGB_SPD`). - -## Custom RGB Matrix Effects :id=custom-rgb-matrix-effects - -By setting `RGB_MATRIX_CUSTOM_USER = yes` in `rules.mk`, new effects can be defined directly from your keymap or userspace, without having to edit any QMK core files. To declare new effects, create a `rgb_matrix_user.inc` file in the user keymap directory or userspace folder. - -?> Hardware maintainers who want to limit custom effects to a specific keyboard can create a `rgb_matrix_kb.inc` file in the root of the keyboard directory, and add `RGB_MATRIX_CUSTOM_KB = yes` to the keyboard level `rules.mk`. - -To use custom effects in your code, simply prepend `RGB_MATRIX_CUSTOM_` to the effect name specified in `RGB_MATRIX_EFFECT()`. For example, an effect declared as `RGB_MATRIX_EFFECT(my_cool_effect)` would be referenced with: - -```c -rgb_matrix_mode(RGB_MATRIX_CUSTOM_my_cool_effect); -``` - -```c -// !!! DO NOT ADD #pragma once !!! // - -// Step 1. -// Declare custom effects using the RGB_MATRIX_EFFECT macro -// (note the lack of semicolon after the macro!) -RGB_MATRIX_EFFECT(my_cool_effect) -RGB_MATRIX_EFFECT(my_cool_effect2) - -// Step 2. -// Define effects inside the `RGB_MATRIX_CUSTOM_EFFECT_IMPLS` ifdef block -#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -// e.g: A simple effect, self-contained within a single method -static bool my_cool_effect(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - for (uint8_t i = led_min; i < led_max; i++) { - rgb_matrix_set_color(i, 0xff, 0xff, 0x00); - } - return rgb_matrix_check_finished_leds(led_max); -} - -// e.g: A more complex effect, relying on external methods and state, with -// dedicated init and run methods -static uint8_t some_global_state; -static void my_cool_effect2_complex_init(effect_params_t* params) { - some_global_state = 1; -} -static bool my_cool_effect2_complex_run(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - for (uint8_t i = led_min; i < led_max; i++) { - rgb_matrix_set_color(i, 0xff, some_global_state++, 0xff); - } - return rgb_matrix_check_finished_leds(led_max); -} -static bool my_cool_effect2(effect_params_t* params) { - if (params->init) my_cool_effect2_complex_init(params); - return my_cool_effect2_complex_run(params); -} - -#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -``` - -For inspiration and examples, check out the built-in effects under `quantum/rgb_matrix/animations/`. - - -## Colors :id=colors - -These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. - -|RGB |HSV | -|---------------------|---------------------| -|`RGB_AZURE` |`HSV_AZURE` | -|`RGB_BLACK`/`RGB_OFF`|`HSV_BLACK`/`HSV_OFF`| -|`RGB_BLUE` |`HSV_BLUE` | -|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | -|`RGB_CORAL` |`HSV_CORAL` | -|`RGB_CYAN` |`HSV_CYAN` | -|`RGB_GOLD` |`HSV_GOLD` | -|`RGB_GOLDENROD` |`HSV_GOLDENROD` | -|`RGB_GREEN` |`HSV_GREEN` | -|`RGB_MAGENTA` |`HSV_MAGENTA` | -|`RGB_ORANGE` |`HSV_ORANGE` | -|`RGB_PINK` |`HSV_PINK` | -|`RGB_PURPLE` |`HSV_PURPLE` | -|`RGB_RED` |`HSV_RED` | -|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | -|`RGB_TEAL` |`HSV_TEAL` | -|`RGB_TURQUOISE` |`HSV_TURQUOISE` | -|`RGB_WHITE` |`HSV_WHITE` | -|`RGB_YELLOW` |`HSV_YELLOW` | - -These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list! - - -## Additional `config.h` Options :id=additional-configh-options - -```c -#define RGB_MATRIX_KEYPRESSES // reacts to keypresses -#define RGB_MATRIX_KEYRELEASES // reacts to keyreleases (instead of keypresses) -#define RGB_MATRIX_FRAMEBUFFER_EFFECTS // enable framebuffer effects -#define RGB_MATRIX_TIMEOUT 0 // number of milliseconds to wait until rgb automatically turns off -#define RGB_DISABLE_WHEN_USB_SUSPENDED // turn off effects when suspended -#define RGB_MATRIX_LED_PROCESS_LIMIT (RGB_MATRIX_LED_COUNT + 4) / 5 // limits the number of LEDs to process in an animation per task run (increases keyboard responsiveness) -#define RGB_MATRIX_LED_FLUSH_LIMIT 16 // limits in milliseconds how frequently an animation will update the LEDs. 16 (16ms) is equivalent to limiting to 60fps (increases keyboard responsiveness) -#define RGB_MATRIX_MAXIMUM_BRIGHTNESS 200 // limits maximum brightness of LEDs to 200 out of 255. If not defined maximum brightness is set to 255 -#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT // Sets the default mode, if none has been set -#define RGB_MATRIX_DEFAULT_HUE 0 // Sets the default hue value, if none has been set -#define RGB_MATRIX_DEFAULT_SAT 255 // Sets the default saturation value, if none has been set -#define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS // Sets the default brightness value, if none has been set -#define RGB_MATRIX_DEFAULT_SPD 127 // Sets the default animation speed, if none has been set -#define RGB_MATRIX_DISABLE_KEYCODES // disables control of rgb matrix by keycodes (must use code functions to control the feature) -#define RGB_MATRIX_SPLIT { X, Y } // (Optional) For split keyboards, the number of LEDs connected on each half. X = left, Y = Right. - // If RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is enabled, you also will want to enable SPLIT_TRANSPORT_MIRROR -#define RGB_TRIGGER_ON_KEYDOWN // Triggers RGB keypress events on key down. This makes RGB control feel more responsive. This may cause RGB to not function properly on some boards -``` - -## EEPROM storage :id=eeprom-storage - -The EEPROM for it is currently shared with the LED Matrix system (it's generally assumed only one feature would be used at a time). - -## Functions :id=functions - -### Direct Operation :id=direct-operation -|Function |Description | -|--------------------------------------------|-------------| -|`rgb_matrix_set_color_all(r, g, b)` |Set all of the LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | -|`rgb_matrix_set_color(index, r, g, b)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255, and `index` is between 0 and `RGB_MATRIX_LED_COUNT` (not written to EEPROM) | - -### Disable/Enable Effects :id=disable-enable-effects -|Function |Description | -|--------------------------------------------|-------------| -|`rgb_matrix_toggle()` |Toggle effect range LEDs between on and off | -|`rgb_matrix_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) | -|`rgb_matrix_enable()` |Turn effect range LEDs on, based on their previous state | -|`rgb_matrix_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) | -|`rgb_matrix_disable()` |Turn effect range LEDs off, based on their previous state | -|`rgb_matrix_disable_noeeprom()` |Turn effect range LEDs off, based on their previous state (not written to EEPROM) | - -### Change Effect Mode :id=change-effect-mode -|Function |Description | -|--------------------------------------------|-------------| -|`rgb_matrix_mode(mode)` |Set the mode, if RGB animations are enabled | -|`rgb_matrix_mode_noeeprom(mode)` |Set the mode, if RGB animations are enabled (not written to EEPROM) | -|`rgb_matrix_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations | -|`rgb_matrix_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) | -|`rgb_matrix_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations | -|`rgb_matrix_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) | -|`rgb_matrix_increase_speed()` |Increase the speed of the animations | -|`rgb_matrix_increase_speed_noeeprom()` |Increase the speed of the animations (not written to EEPROM) | -|`rgb_matrix_decrease_speed()` |Decrease the speed of the animations | -|`rgb_matrix_decrease_speed_noeeprom()` |Decrease the speed of the animations (not written to EEPROM) | -|`rgb_matrix_set_speed(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 | -|`rgb_matrix_set_speed_noeeprom(speed)` |Set the speed of the animations to the given value where `speed` is between 0 and 255 (not written to EEPROM) | -|`rgb_matrix_reload_from_eeprom()` |Reload the effect configuration (enabled, mode and color) from EEPROM | - -### Change Color :id=change-color -|Function |Description | -|--------------------------------------------|-------------| -|`rgb_matrix_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue | -|`rgb_matrix_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) | -|`rgb_matrix_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue | -|`rgb_matrix_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) | -|`rgb_matrix_increase_sat()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation | -|`rgb_matrix_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This wraps around at maximum saturation (not written to EEPROM) | -|`rgb_matrix_decrease_sat()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation | -|`rgb_matrix_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This wraps around at minimum saturation (not written to EEPROM) | -|`rgb_matrix_increase_val()` |Increase the value for effect range LEDs. This wraps around at maximum value | -|`rgb_matrix_increase_val_noeeprom()` |Increase the value for effect range LEDs. This wraps around at maximum value (not written to EEPROM) | -|`rgb_matrix_decrease_val()` |Decrease the value for effect range LEDs. This wraps around at minimum value | -|`rgb_matrix_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This wraps around at minimum value (not written to EEPROM) | -|`rgb_matrix_sethsv(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 | -|`rgb_matrix_sethsv_noeeprom(h, s, v)` |Set LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | - -### Query Current Status :id=query-current-status -|Function |Description | -|---------------------------------|---------------------------| -|`rgb_matrix_is_enabled()` |Gets current on/off status | -|`rgb_matrix_get_mode()` |Gets current mode | -|`rgb_matrix_get_hue()` |Gets current hue | -|`rgb_matrix_get_sat()` |Gets current sat | -|`rgb_matrix_get_val()` |Gets current val | -|`rgb_matrix_get_hsv()` |Gets hue, sat, and val and returns a [`HSV` structure](https://github.com/qmk/qmk_firmware/blob/7ba6456c0b2e041bb9f97dbed265c5b8b4b12192/quantum/color.h#L56-L61)| -|`rgb_matrix_get_speed()` |Gets current speed | -|`rgb_matrix_get_suspend_state()` |Gets current suspend state | - -## Callbacks :id=callbacks - -### Indicators :id=indicators - -If you want to set custom indicators, such as an LED for Caps Lock, or layer indication, you can use the `rgb_matrix_indicators_kb` or `rgb_matrix_indicators_user` function for that: -```c -bool rgb_matrix_indicators_kb(void) { - if (!rgb_matrix_indicators_user()) { - return false; - } - rgb_matrix_set_color(index, red, green, blue); - return true; -} -``` - -In addition, there are the advanced indicator functions. These are aimed at those with heavily customized displays, where rendering every LED per cycle is expensive. Such as some of the "drashna" layouts. This includes a special macro to help make this easier to use: `RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b)`. - -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - RGB_MATRIX_INDICATOR_SET_COLOR(index, red, green, blue); - return false; -} -``` - -### Indicator Examples :id=indicator-examples - -Caps Lock indicator on alphanumeric flagged keys: -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - if (host_keyboard_led_state().caps_lock) { - for (uint8_t i = led_min; i < led_max; i++) { - if (g_led_config.flags[i] & LED_FLAG_KEYLIGHT) { - rgb_matrix_set_color(i, RGB_RED); - } - } - } - return false; -} -``` - -Layer indicator on all keys: -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - for (uint8_t i = led_min; i < led_max; i++) { - switch(get_highest_layer(layer_state|default_layer_state)) { - case 2: - rgb_matrix_set_color(i, RGB_BLUE); - break; - case 1: - rgb_matrix_set_color(i, RGB_YELLOW); - break; - default: - break; - } - } - return false; -} -``` - -Layer indicator only on keys with configured keycodes: -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - if (get_highest_layer(layer_state) > 0) { - uint8_t layer = get_highest_layer(layer_state); - - for (uint8_t row = 0; row < MATRIX_ROWS; ++row) { - for (uint8_t col = 0; col < MATRIX_COLS; ++col) { - uint8_t index = g_led_config.matrix_co[row][col]; - - if (index >= led_min && index < led_max && index != NO_LED && - keymap_key_to_keycode(layer, (keypos_t){col,row}) > KC_TRNS) { - rgb_matrix_set_color(index, RGB_GREEN); - } - } - } - } - return false; -} -``` - -?> Split keyboards will require layer state data syncing with `#define SPLIT_LAYER_STATE_ENABLE`. See [Data Sync Options](feature_split_keyboard?id=data-sync-options) for more details. - -#### Examples :id=indicator-examples - -This example sets the modifiers to be a specific color based on the layer state. You can use a switch case here, instead, if you would like. This uses HSV and then converts to RGB, because this allows the brightness to be limited (important when using the WS2812 driver). - -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - HSV hsv = {0, 255, 255}; - - if (layer_state_is(layer_state, 2)) { - hsv = {130, 255, 255}; - } else { - hsv = {30, 255, 255}; - } - - if (hsv.v > rgb_matrix_get_val()) { - hsv.v = rgb_matrix_get_val(); - } - RGB rgb = hsv_to_rgb(hsv); - - for (uint8_t i = led_min; i < led_max; i++) { - if (HAS_FLAGS(g_led_config.flags[i], 0x01)) { // 0x01 == LED_FLAG_MODIFIER - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - } - return false; -} -``` - -If you want to indicate a Host LED status (caps lock, num lock, etc), you can use something like this to light up the caps lock key: - -```c -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - if (host_keyboard_led_state().caps_lock) { - RGB_MATRIX_INDICATOR_SET_COLOR(5, 255, 255, 255); // assuming caps lock is at led #5 - } else { - RGB_MATRIX_INDICATOR_SET_COLOR(5, 0, 0, 0); - } - return false; -} -``` - -?> RGB indicators on split keyboards will require state information synced to the slave half (e.g. `#define SPLIT_LAYER_STATE_ENABLE`). See [data sync options](feature_split_keyboard.md#data-sync-options) for more details. - -#### Indicators without RGB Matrix Effect - -If you want to just use RGB indicators without RGB matrix effect, it is not possible to disable the latter because toggling RGB off will disable everything. You can workaround it with solid effect and colors off using this init function: -```c -void keyboard_post_init_user(void) { - rgb_matrix_mode_noeeprom(RGB_MATRIX_SOLID_COLOR); - rgb_matrix_sethsv_noeeprom(HSV_OFF); -} -``` diff --git a/docs/feature_rgblight.md b/docs/feature_rgblight.md deleted file mode 100644 index 5131658ae158..000000000000 --- a/docs/feature_rgblight.md +++ /dev/null @@ -1,585 +0,0 @@ -# RGB Lighting - -QMK has the ability to control RGB LEDs attached to your keyboard. This is commonly called *underglow*, due to the LEDs often being mounted on the bottom of the keyboard, producing a nice diffused effect when combined with a translucent case. - -![Planck with RGB Underglow](https://raw.githubusercontent.com/qmk/qmk_firmware/3774a7fcdab5544fc787f4c200be05fcd417e31f/keyboards/planck/keymaps/yang/planck-with-rgb-underglow.jpg) - -Some keyboards come with RGB LEDs preinstalled. Others must have them installed after the fact. See the [Hardware Modification](#hardware-modification) section for information on adding RGB lighting to your keyboard. - -Currently QMK supports the following addressable LEDs (however, the white LED in RGBW variants is not supported): - - * WS2811, WS2812, WS2812B, WS2812C, etc. - * SK6812, SK6812MINI, SK6805 - * APA102 - -These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs. - -## Usage - -On keyboards with onboard RGB LEDs, it is usually enabled by default. If it is not working for you, check that your `rules.mk` includes the following: - -```make -RGBLIGHT_ENABLE = yes -``` - -?> There are additional configuration options for ARM controllers that offer increased performance over the default WS2812 bitbang driver. Please see [WS2812 Driver](ws2812_driver.md) for more information. - -For APA102 LEDs, add the following to your `rules.mk`: - -```make -RGBLIGHT_ENABLE = yes -RGBLIGHT_DRIVER = APA102 -``` - -At minimum you must define the data pin your LED strip is connected to, and the number of LEDs in the strip, in your `config.h`. For APA102 LEDs, you must also define the clock pin. If your keyboard has onboard RGB LEDs, and you are simply creating a keymap, you usually won't need to modify these. - -|Define |Description | -|---------------|-------------------------------------------------------------------------| -|`WS2812_DI_PIN`|The pin connected to the data pin of the LEDs (WS2812) | -|`APA102_DI_PIN`|The pin connected to the data pin of the LEDs (APA102) | -|`APA102_CI_PIN`|The pin connected to the clock pin of the LEDs (APA102) | -|`RGBLED_NUM` |The number of LEDs connected | -|`RGBLED_SPLIT` |(Optional) For split keyboards, the number of LEDs connected on each half| - -Then you should be able to use the keycodes below to change the RGB lighting to your liking. - -### Color Selection - -QMK uses [Hue, Saturation, and Value](https://en.wikipedia.org/wiki/HSL_and_HSV) to select colors rather than RGB. The color wheel below demonstrates how this works. - -HSV Color Wheel - -Changing the **Hue** cycles around the circle.
-Changing the **Saturation** moves between the inner and outer sections of the wheel, affecting the intensity of the color.
-Changing the **Value** sets the overall brightness.
- -![QMK Color Wheel with HSV Values](https://i.imgur.com/vkYVo66.jpg) - -## Keycodes - -|Key |Aliases |Description | -|-------------------|----------|--------------------------------------------------------------------| -|`RGB_TOG` | |Toggle RGB lighting on or off | -|`RGB_MODE_FORWARD` |`RGB_MOD` |Cycle through modes, reverse direction when Shift is held | -|`RGB_MODE_REVERSE` |`RGB_RMOD`|Cycle through modes in reverse, forward direction when Shift is held| -|`RGB_HUI` | |Increase hue, decrease hue when Shift is held | -|`RGB_HUD` | |Decrease hue, increase hue when Shift is held | -|`RGB_SAI` | |Increase saturation, decrease saturation when Shift is held | -|`RGB_SAD` | |Decrease saturation, increase saturation when Shift is held | -|`RGB_VAI` | |Increase value (brightness), decrease value when Shift is held | -|`RGB_VAD` | |Decrease value (brightness), increase value when Shift is held | -|`RGB_MODE_PLAIN` |`RGB_M_P `|Static (no animation) mode | -|`RGB_MODE_BREATHE` |`RGB_M_B` |Breathing animation mode | -|`RGB_MODE_RAINBOW` |`RGB_M_R` |Rainbow animation mode | -|`RGB_MODE_SWIRL` |`RGB_M_SW`|Swirl animation mode | -|`RGB_MODE_SNAKE` |`RGB_M_SN`|Snake animation mode | -|`RGB_MODE_KNIGHT` |`RGB_M_K` |"Knight Rider" animation mode | -|`RGB_MODE_XMAS` |`RGB_M_X` |Christmas animation mode | -|`RGB_MODE_GRADIENT`|`RGB_M_G` |Static gradient animation mode | -|`RGB_MODE_RGBTEST` |`RGB_M_T` |Red, Green, Blue test animation mode | -|`RGB_MODE_TWINKLE` |`RGB_M_TW`|Twinkle animation mode | - -?> `RGB_*` keycodes cannot be used with functions like `tap_code16(RGB_HUI)` as they're not USB HID keycodes. If you wish to replicate similar behaviour in custom code within your firmware (e.g. inside `encoder_update_user()` or `process_record_user()`), the equivalent [RGB functions](#functions) should be used instead. - - -!> By default, if you have both the RGB Light and the [RGB Matrix](feature_rgb_matrix.md) feature enabled, these keycodes will work for both features, at the same time. You can disable the keycode functionality by defining the `*_DISABLE_KEYCODES` option for the specific feature. - -## Configuration - -Your RGB lighting can be configured by placing these `#define`s in your `config.h`: - -|Define |Default |Description | -|---------------------------|----------------------------|---------------------------------------------------------------------------------------------------------------------------| -|`RGBLIGHT_HUE_STEP` |`10` |The number of steps to cycle through the hue by | -|`RGBLIGHT_SAT_STEP` |`17` |The number of steps to increment the saturation by | -|`RGBLIGHT_VAL_STEP` |`17` |The number of steps to increment the brightness by | -|`RGBLIGHT_LIMIT_VAL` |`255` |The maximum brightness level | -|`RGBLIGHT_SLEEP` |*Not defined* |If defined, the RGB lighting will be switched off when the host goes to sleep | -|`RGBLIGHT_SPLIT` |*Not defined* |If defined, synchronization functionality for split keyboards is added | -|`RGBLIGHT_DISABLE_KEYCODES`|*Not defined* |If defined, disables the ability to control RGB Light from the keycodes. You must use code functions to control the feature| -|`RGBLIGHT_DEFAULT_MODE` |`RGBLIGHT_MODE_STATIC_LIGHT`|The default mode to use upon clearing the EEPROM | -|`RGBLIGHT_DEFAULT_HUE` |`0` (red) |The default hue to use upon clearing the EEPROM | -|`RGBLIGHT_DEFAULT_SAT` |`UINT8_MAX` (255) |The default saturation to use upon clearing the EEPROM | -|`RGBLIGHT_DEFAULT_VAL` |`RGBLIGHT_LIMIT_VAL` |The default value (brightness) to use upon clearing the EEPROM | -|`RGBLIGHT_DEFAULT_SPD` |`0` |The default speed to use upon clearing the EEPROM | - -## Effects and Animations - -Not only can this lighting be whatever color you want, -if `RGBLIGHT_EFFECT_xxxx` is defined, you also have a number of animation modes at your disposal: - -|Mode number symbol |Additional number |Description | -|-----------------------------|-------------------|---------------------------------------| -|`RGBLIGHT_MODE_STATIC_LIGHT` | *None* |Solid color (this mode is always enabled) | -|`RGBLIGHT_MODE_BREATHING` | 0,1,2,3 |Solid color breathing | -|`RGBLIGHT_MODE_RAINBOW_MOOD` | 0,1,2 |Cycling rainbow | -|`RGBLIGHT_MODE_RAINBOW_SWIRL`| 0,1,2,3,4,5 |Swirling rainbow | -|`RGBLIGHT_MODE_SNAKE` | 0,1,2,3,4,5 |Snake | -|`RGBLIGHT_MODE_KNIGHT` | 0,1,2 |Knight | -|`RGBLIGHT_MODE_CHRISTMAS` | *None* |Christmas | -|`RGBLIGHT_MODE_STATIC_GRADIENT`| 0,1,..,9 |Static gradient | -|`RGBLIGHT_MODE_RGB_TEST` | *None* |RGB Test | -|`RGBLIGHT_MODE_ALTERNATING` | *None* |Alternating | -|`RGBLIGHT_MODE_TWINKLE` | 0,1,2,3,4,5 |Twinkle | - -Check out [this video](https://youtube.com/watch?v=VKrpPAHlisY) for a demonstration. - -Note: For versions older than 0.6.117, The mode numbers were written directly. In `quantum/rgblight/rgblight.h` there is a contrast table between the old mode number and the current symbol. - - -### Effect and Animation Toggles - -Use these defines to add or remove animations from the firmware. When you are running low on flash space, it can be helpful to disable animations you are not using. - -|Define |Default |Description | -|------------------------------------|-------------|-------------------------------------------------------------------------| -|`RGBLIGHT_ANIMATIONS` |*Not defined*|Enable all additional animation modes. (deprecated) | -|`RGBLIGHT_EFFECT_ALTERNATING` |*Not defined*|Enable alternating animation mode. | -|`RGBLIGHT_EFFECT_BREATHING` |*Not defined*|Enable breathing animation mode. | -|`RGBLIGHT_EFFECT_CHRISTMAS` |*Not defined*|Enable christmas animation mode. | -|`RGBLIGHT_EFFECT_KNIGHT` |*Not defined*|Enable knight animation mode. | -|`RGBLIGHT_EFFECT_RAINBOW_MOOD` |*Not defined*|Enable rainbow mood animation mode. | -|`RGBLIGHT_EFFECT_RAINBOW_SWIRL` |*Not defined*|Enable rainbow swirl animation mode. | -|`RGBLIGHT_EFFECT_RGB_TEST` |*Not defined*|Enable RGB test animation mode. | -|`RGBLIGHT_EFFECT_SNAKE` |*Not defined*|Enable snake animation mode. | -|`RGBLIGHT_EFFECT_STATIC_GRADIENT` |*Not defined*|Enable static gradient mode. | -|`RGBLIGHT_EFFECT_TWINKLE` |*Not defined*|Enable twinkle animation mode. | - -!> `RGBLIGHT_ANIMATIONS` is being deprecated and animation modes should be explicitly defined. - -### Effect and Animation Settings - -The following options are used to tweak the various animations: - -|Define |Default |Description | -|------------------------------------|-------------|-----------------------------------------------------------------------------------------------| -|`RGBLIGHT_EFFECT_BREATHE_CENTER` |*Not defined*|If defined, used to calculate the curve for the breathing animation. Valid values are 1.0 to 2.7 | -|`RGBLIGHT_EFFECT_BREATHE_MAX` |`255` |The maximum brightness for the breathing mode. Valid values are 1 to 255 | -|`RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL`|`40` |How long (in milliseconds) to wait between animation steps for the "Christmas" animation | -|`RGBLIGHT_EFFECT_CHRISTMAS_STEP` |`2` |The number of LEDs to group the red/green colors by for the "Christmas" animation | -|`RGBLIGHT_EFFECT_KNIGHT_LED_NUM` |`RGBLED_NUM` |The number of LEDs to have the "Knight" animation travel | -|`RGBLIGHT_EFFECT_KNIGHT_LENGTH` |`3` |The number of LEDs to light up for the "Knight" animation | -|`RGBLIGHT_EFFECT_KNIGHT_OFFSET` |`0` |The number of LEDs to start the "Knight" animation from the start of the strip by | -|`RGBLIGHT_RAINBOW_SWIRL_RANGE` |`255` |Range adjustment for the rainbow swirl effect to get different swirls | -|`RGBLIGHT_EFFECT_SNAKE_LENGTH` |`4` |The number of LEDs to light up for the "Snake" animation | -|`RGBLIGHT_EFFECT_TWINKLE_LIFE` |`200` |Adjusts how quickly each LED brightens and dims when twinkling (in animation steps) | -|`RGBLIGHT_EFFECT_TWINKLE_PROBABILITY`|`1/127` |Adjusts how likely each LED is to twinkle (on each animation step) | - -### Example Usage to Reduce Memory Footprint - 1. Use `#undef` to selectively disable animations. The following would disable two animations and save about 4KiB: - -```diff - #undef RGBLED_NUM -+#undef RGBLIGHT_EFFECT_STATIC_GRADIENT -+#undef RGBLIGHT_EFFECT_RAINBOW_SWIRL - #define RGBLED_NUM 12 - #define RGBLIGHT_HUE_STEP 8 - #define RGBLIGHT_SAT_STEP 8 -``` - -### Animation Speed - -You can also modify the speeds that the different modes animate at: - -Here is a quick demo on Youtube (with NPKC KC60) (https://www.youtube.com/watch?v=VKrpPAHlisY). - -```c -// How long (in milliseconds) to wait between animation steps for each of the "Solid color breathing" animations -const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; - -// How long (in milliseconds) to wait between animation steps for each of the "Cycling rainbow" animations -const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; - -// How long (in milliseconds) to wait between animation steps for each of the "Swirling rainbow" animations -const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; - -// How long (in milliseconds) to wait between animation steps for each of the "Snake" animations -const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; - -// How long (in milliseconds) to wait between animation steps for each of the "Knight" animations -const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; - -// How long (in milliseconds) to wait between animation steps for each of the "Twinkle" animations -const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {50, 25, 10}; - -// These control which hues are selected for each of the "Static gradient" modes -const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64}; -``` - -## Lighting Layers - -?> **Note:** Lighting Layers is an RGB Light feature, it will not work for RGB Matrix. See [RGB Matrix Indicators](feature_rgb_matrix.md#indicators) for details on how to do so. - -By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make -it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do. - -### Defining Lighting Layers :id=defining-lighting-layers - -By default, 8 layers are possible. This can be expanded to as many as 32 by overriding the definition of `RGBLIGHT_MAX_LAYERS` in `config.h` (e.g. `#define RGBLIGHT_MAX_LAYERS 32`). Please note, if you use a split keyboard, you will need to flash both sides of the split after changing this. Also, increasing the maximum will increase the firmware size, and will slow sync on split keyboards. - -To define a layer, we modify `keymap.c` to list the LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently: - -```c -// Light LEDs 6 to 9 and 12 to 15 red when caps lock is active. Hard to ignore! -const rgblight_segment_t PROGMEM my_capslock_layer[] = RGBLIGHT_LAYER_SEGMENTS( - {6, 4, HSV_RED}, // Light 4 LEDs, starting with LED 6 - {12, 4, HSV_RED} // Light 4 LEDs, starting with LED 12 -); -// Light LEDs 9 & 10 in cyan when keyboard layer 1 is active -const rgblight_segment_t PROGMEM my_layer1_layer[] = RGBLIGHT_LAYER_SEGMENTS( - {9, 2, HSV_CYAN} -); -// Light LEDs 11 & 12 in purple when keyboard layer 2 is active -const rgblight_segment_t PROGMEM my_layer2_layer[] = RGBLIGHT_LAYER_SEGMENTS( - {11, 2, HSV_PURPLE} -); -// Light LEDs 13 & 14 in green when keyboard layer 3 is active -const rgblight_segment_t PROGMEM my_layer3_layer[] = RGBLIGHT_LAYER_SEGMENTS( - {13, 2, HSV_GREEN} -); -// etc.. -``` - -We combine these layers into an array using the `RGBLIGHT_LAYERS_LIST` macro, and assign it to the `rgblight_layers` variable during keyboard setup. Note that you can only define up to 8 lighting layers. Any extra layers will be ignored. Since the different lighting layers overlap, the order matters in the array, with later layers taking precedence: - -```c -// Now define the array of layers. Later layers take precedence -const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST( - my_capslock_layer, - my_layer1_layer, // Overrides caps lock layer - my_layer2_layer, // Overrides other layers - my_layer3_layer // Overrides other layers -); - -void keyboard_post_init_user(void) { - // Enable the LED layers - rgblight_layers = my_rgb_layers; -} -``` -Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers. - -### Enabling and disabling lighting layers :id=enabling-lighting-layers - -Everything above just configured the definition of each lighting layer. -We can now enable and disable the lighting layers whenever the state of the keyboard changes: - -```c -bool led_update_user(led_t led_state) { - rgblight_set_layer_state(0, led_state.caps_lock); - return true; -} - -layer_state_t default_layer_state_set_user(layer_state_t state) { - rgblight_set_layer_state(1, layer_state_cmp(state, _DVORAK)); - return state; -} - -layer_state_t layer_state_set_user(layer_state_t state) { - rgblight_set_layer_state(2, layer_state_cmp(state, _FN)); - rgblight_set_layer_state(3, layer_state_cmp(state, _ADJUST)); - return state; -} -``` - -### Lighting layer blink :id=lighting-layer-blink - -By including `#define RGBLIGHT_LAYER_BLINK` in your `config.h` file you can turn a lighting -layer on for a specified duration. Once the specified number of milliseconds has elapsed -the layer will be turned off. This is useful, e.g., if you want to acknowledge some -action (e.g. toggling some setting): - -```c -const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_GREEN} ); -const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_RED} ); - -const rgblight_segment_t* const PROGMEM _rgb_layers[] = - RGBLIGHT_LAYERS_LIST( _yes_layer, _no_layer ); - -void keyboard_post_init_user(void) { - rgblight_layers = _rgb_layers; -} - -// Note we user post_process_record_user because we want the state -// after the flag has been flipped... -void post_process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_DEBUG_TOGGLE: - rgblight_blink_layer(debug_enable ? 0 : 1, 500); - break; - - case NK_TOGG: - case NK_ON: - case NK_OFF: - rgblight_blink_layer(keymap_config.nkro ? 0 : 1, 500); - break; - } -} -``` - -You can also use `rgblight_blink_layer_repeat` to specify the amount of times the layer is supposed to blink. Using the layers from above, -```c -void post_process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_DEBUG_TOGGLE: - rgblight_blink_layer_repeat(debug_enable ? 0 : 1, 200, 3); - break; - } -} -``` -would turn the layer 0 (or 1) on and off again three times when `DB_TOGG` is pressed. - -Blinking accumulates layers so if multiple layers are set blinking at the same time they will all blink for the duration and repeat times of the last layer to be blinked. -To stop these other layers from blinking use `rgblight_unblink_layer` or `rgblight_unblink_all_but_layer`: - -```c -rgblight_blink_layer(1, 500); -rgblight_unblink_all_but_layer(1); -``` - -```c -rgblight_unblink_layer(3); -rgblight_blink_layer(2, 500); -``` - -!> Lighting layers on split keyboards will require layer state synced to the slave half (e.g. `#define SPLIT_LAYER_STATE_ENABLE`). See [data sync options](feature_split_keyboard.md#data-sync-options) for more details. - -### Overriding RGB Lighting on/off status - -Normally lighting layers are not shown when RGB Lighting is disabled (e.g. with `RGB_TOG` keycode). If you would like lighting layers to work even when the RGB Lighting is otherwise off, add `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` to your `config.h`. - -### Retain brightness - -Usually lighting layers apply their configured brightness once activated. If you would like lighting layers to retain the currently used brightness (as returned by `rgblight_get_val()`), add `#define RGBLIGHT_LAYERS_RETAIN_VAL` to your `config.h`. - -## Functions - -If you need to change your RGB lighting in code, for example in a macro to change the color whenever you switch layers, QMK provides a set of functions to assist you. See [`rgblight.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/rgblight/rgblight.h) for the full list, but the most commonly used functions include: - -### Utility Functions -|Function |Description | -|--------------------------------------------|-------------------------------------------------------------------| -|`sethsv(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value | -|`sethsv_raw(hue, sat, val, ledbuf)` |Set ledbuf to the given HSV value without RGBLIGHT_LIMIT_VAL check | -|`setrgb(r, g, b, ledbuf)` |Set ledbuf to the given RGB value where `r`/`g`/`b` | - -### Low level Functions -|Function |Description | -|--------------------------------------------|-------------------------------------------| -|`rgblight_set()` |Flush out led buffers to LEDs | -|`rgblight_set_clipping_range(pos, num)` |Set clipping Range. see [Clipping Range](#clipping-range) | - -Example: -```c -sethsv(HSV_WHITE, (LED_TYPE *)&led[0]); // led 0 -sethsv(HSV_RED, (LED_TYPE *)&led[1]); // led 1 -sethsv(HSV_GREEN, (LED_TYPE *)&led[2]); // led 2 -rgblight_set(); // Utility functions do not call rgblight_set() automatically, so they need to be called explicitly. -``` - -### Effects and Animations Functions -#### effect range setting -|Function |Description | -|--------------------------------------------|------------------| -|`rgblight_set_effect_range(pos, num)` |Set Effects Range | - -#### direct operation -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_setrgb_at(r, g, b, index)` |Set a single LED to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) | -|`rgblight_sethsv_at(h, s, v, index)` |Set a single LED to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `index` is between 0 and `RGBLED_NUM` (not written to EEPROM) | -|`rgblight_setrgb_range(r, g, b, start, end)`|Set a continuous range of LEDs to the given RGB value, where `r`/`g`/`b` are between 0 and 255 and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| -|`rgblight_sethsv_range(h, s, v, start, end)`|Set a continuous range of LEDs to the given HSV value, where `h`/`s`/`v` are between 0 and 255, and `start`(included) and `stop`(excluded) are between 0 and `RGBLED_NUM` (not written to EEPROM)| -|`rgblight_setrgb(r, g, b)` |Set effect range LEDs to the given RGB value where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | -|`rgblight_setrgb_master(r, g, b)` |Set the LEDs on the master side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | -|`rgblight_setrgb_slave(r, g, b)` |Set the LEDs on the slave side to the given RGB value, where `r`/`g`/`b` are between 0 and 255 (not written to EEPROM) | -|`rgblight_sethsv_master(h, s, v)` |Set the LEDs on the master side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | -|`rgblight_sethsv_slave(h, s, v)` |Set the LEDs on the slave side to the given HSV value, where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | - -Example: -```c -rgblight_sethsv_at(HSV_WHITE, 0); // led 0 -rgblight_sethsv_at(HSV_RED, 1); // led 1 -rgblight_sethsv_at(HSV_GREEN, 2); // led 2 -// The above functions automatically calls rgblight_set(), so there is no need to call it explicitly. -// Note that it is inefficient to call repeatedly. -``` - -#### effect mode change -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_mode(x)` |Set the mode, if RGB animations are enabled | -|`rgblight_mode_noeeprom(x)` |Set the mode, if RGB animations are enabled (not written to EEPROM) | -|`rgblight_step()` |Change the mode to the next RGB animation in the list of enabled RGB animations | -|`rgblight_step_noeeprom()` |Change the mode to the next RGB animation in the list of enabled RGB animations (not written to EEPROM) | -|`rgblight_step_reverse()` |Change the mode to the previous RGB animation in the list of enabled RGB animations | -|`rgblight_step_reverse_noeeprom()` |Change the mode to the previous RGB animation in the list of enabled RGB animations (not written to EEPROM) | -|`rgblight_reload_from_eeprom()` |Reload the effect configuration (enabled, mode and color) from EEPROM | - -#### effects mode disable/enable -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_toggle()` |Toggle effect range LEDs between on and off | -|`rgblight_toggle_noeeprom()` |Toggle effect range LEDs between on and off (not written to EEPROM) | -|`rgblight_enable()` |Turn effect range LEDs on, based on their previous state | -|`rgblight_enable_noeeprom()` |Turn effect range LEDs on, based on their previous state (not written to EEPROM) | -|`rgblight_disable()` |Turn effect range LEDs off | -|`rgblight_disable_noeeprom()` |Turn effect range LEDs off (not written to EEPROM) | - -#### hue, sat, val change -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_increase_hue()` |Increase the hue for effect range LEDs. This wraps around at maximum hue | -|`rgblight_increase_hue_noeeprom()` |Increase the hue for effect range LEDs. This wraps around at maximum hue (not written to EEPROM) | -|`rgblight_decrease_hue()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue | -|`rgblight_decrease_hue_noeeprom()` |Decrease the hue for effect range LEDs. This wraps around at minimum hue (not written to EEPROM) | -|`rgblight_increase_sat()` |Increase the saturation for effect range LEDs. This stops at maximum saturation | -|`rgblight_increase_sat_noeeprom()` |Increase the saturation for effect range LEDs. This stops at maximum saturation (not written to EEPROM) | -|`rgblight_decrease_sat()` |Decrease the saturation for effect range LEDs. This stops at minimum saturation | -|`rgblight_decrease_sat_noeeprom()` |Decrease the saturation for effect range LEDs. This stops at minimum saturation (not written to EEPROM) | -|`rgblight_increase_val()` |Increase the value for effect range LEDs. This stops at maximum value | -|`rgblight_increase_val_noeeprom()` |Increase the value for effect range LEDs. This stops at maximum value (not written to EEPROM) | -|`rgblight_decrease_val()` |Decrease the value for effect range LEDs. This stops at minimum value | -|`rgblight_decrease_val_noeeprom()` |Decrease the value for effect range LEDs. This stops at minimum value (not written to EEPROM) | -|`rgblight_sethsv(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 | -|`rgblight_sethsv_noeeprom(h, s, v)` |Set effect range LEDs to the given HSV value where `h`/`s`/`v` are between 0 and 255 (not written to EEPROM) | - -#### Speed functions -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_increase_speed()` |Increases the animation speed | -|`rgblight_increase_speed_noeeprom()` |Increases the animation speed (not written to EEPROM) | -|`rgblight_decrease_speed()` |Decreases the animation speed | -|`rgblight_decrease_speed_noeeprom()` |Decreases the animation speed (not written to EEPROM) | -|`rgblight_set_speed()` |Sets the speed. Value is between 0 and 255 | -|`rgblight_set_speed_noeeprom()` |Sets the speed. Value is between 0 and 255 (not written to EEPROM) | - - -#### layer functions -|Function |Description | -|--------------------------------------------|-------------| -|`rgblight_get_layer_state(i)` |Returns `true` if lighting layer `i` is enabled | -|`rgblight_set_layer_state(i, is_on)` |Enable or disable lighting layer `i` based on value of `bool is_on` | - -#### query -|Function |Description | -|-----------------------|---------------------------| -|`rgblight_is_enabled()`|Gets current on/off status | -|`rgblight_get_mode()` |Gets current mode | -|`rgblight_get_hue()` |Gets current hue | -|`rgblight_get_sat()` |Gets current sat | -|`rgblight_get_val()` |Gets current val | -|`rgblight_get_speed()` |Gets current speed | - -## Colors - -These are shorthands to popular colors. The `RGB` ones can be passed to the `setrgb` functions, while the `HSV` ones to the `sethsv` functions. - -|RGB |HSV | -|---------------------|---------------------| -|`RGB_AZURE` |`HSV_AZURE` | -|`RGB_BLACK`/`RGB_OFF`|`HSV_BLACK`/`HSV_OFF`| -|`RGB_BLUE` |`HSV_BLUE` | -|`RGB_CHARTREUSE` |`HSV_CHARTREUSE` | -|`RGB_CORAL` |`HSV_CORAL` | -|`RGB_CYAN` |`HSV_CYAN` | -|`RGB_GOLD` |`HSV_GOLD` | -|`RGB_GOLDENROD` |`HSV_GOLDENROD` | -|`RGB_GREEN` |`HSV_GREEN` | -|`RGB_MAGENTA` |`HSV_MAGENTA` | -|`RGB_ORANGE` |`HSV_ORANGE` | -|`RGB_PINK` |`HSV_PINK` | -|`RGB_PURPLE` |`HSV_PURPLE` | -|`RGB_RED` |`HSV_RED` | -|`RGB_SPRINGGREEN` |`HSV_SPRINGGREEN` | -|`RGB_TEAL` |`HSV_TEAL` | -|`RGB_TURQUOISE` |`HSV_TURQUOISE` | -|`RGB_WHITE` |`HSV_WHITE` | -|`RGB_YELLOW` |`HSV_YELLOW` | - -```c -rgblight_setrgb(RGB_ORANGE); -rgblight_sethsv_noeeprom(HSV_GREEN); -rgblight_setrgb_at(RGB_GOLD, 3); -rgblight_sethsv_range(HSV_WHITE, 0, 6); -``` - -These are defined in [`color.h`](https://github.com/qmk/qmk_firmware/blob/master/quantum/color.h). Feel free to add to this list! - - -## Changing the order of the LEDs - -If you want to make the logical order of LEDs different from the electrical connection order, you can do this by defining the `RGBLIGHT_LED_MAP` macro in your `config.h`. - -Normally, the contents of the LED buffer are output to the LEDs in the same order. -simple dicrect - -By defining `RGBLIGHT_LED_MAP` as in the example below, you can specify the LED with addressing in reverse order of the electrical connection order. - -```c -// config.h - -#define RGBLED_NUM 4 -#define RGBLIGHT_LED_MAP { 3, 2, 1, 0 } - -``` -simple mapped - -For keyboards that use the RGB LEDs as a backlight for each key, you can also define it as in the example below. - -```c -// config.h - -#define RGBLED_NUM 30 - -/* RGB LED Conversion macro from physical array to electric array */ -#define LED_LAYOUT( \ - L00, L01, L02, L03, L04, L05, \ - L10, L11, L12, L13, L14, L15, \ - L20, L21, L22, L23, L24, L25, \ - L30, L31, L32, L33, L34, L35, \ - L40, L41, L42, L43, L44, L45 ) \ - { \ - L05, L04, L03, L02, L01, L00, \ - L10, L11, L12, L13, L14, L15, \ - L25, L24, L23, L22, L21, L20, \ - L30, L31, L32, L33, L34, L35, \ - L46, L45, L44, L43, L42, L41 \ - } - -/* RGB LED logical order map */ -/* Top->Bottom, Right->Left */ -#define RGBLIGHT_LED_MAP LED_LAYOUT( \ - 25, 20, 15, 10, 5, 0, \ - 26, 21, 16, 11, 6, 1, \ - 27, 22, 17, 12, 7, 2, \ - 28, 23, 18, 13, 8, 3, \ - 29, 24, 19, 14, 9, 4 ) - -``` -## Clipping Range - -Using the `rgblight_set_clipping_range()` function, you can prepare more buffers than the actual number of LEDs, and output some of the buffers to the LEDs. This is useful if you want the split keyboard to treat left and right LEDs as logically contiguous. - -You can set the Clipping Range by executing the following code. - -```c -// some source -rgblight_set_clipping_range(3, 4); -``` -clip direct - -In addition to setting the Clipping Range, you can use `RGBLIGHT_LED_MAP` together. - -```c -// config.h -#define RGBLED_NUM 8 -#define RGBLIGHT_LED_MAP { 7, 6, 5, 4, 3, 2, 1, 0 } - -// some soruce - rgblight_set_clipping_range(3, 4); -``` -clip mapped - -## Hardware Modification - -If your keyboard lacks onboard underglow LEDs, you may often be able to solder on an RGB LED strip yourself. You will need to find an unused pin to wire to the data pin of your LED strip. Some keyboards may break out unused pins from the MCU to make soldering easier. The other two pins, VCC and GND, must also be connected to the appropriate power pins. diff --git a/docs/feature_secure.md b/docs/feature_secure.md deleted file mode 100644 index eaa2b601aef6..000000000000 --- a/docs/feature_secure.md +++ /dev/null @@ -1,54 +0,0 @@ -# Secure - -The secure feature aims to prevent unwanted interaction without user intervention. - -?> Secure does **not** currently implement encryption/decryption/etc and should not be a replacement where a strong hardware/software based solution is required. - -### Unlock sequence - -To unlock, the user must perform a set of actions. This can optionally be configured to be multiple keys. - -* While unlocking all keyboard input is ignored -* Incorrect attempts will revert back to the previously locked state - -### Automatic Locking - -Once unlocked, the keyboard will revert back to a locked state after the configured timeout. -The timeout can be refreshed by using the `secure_activity_event` function, for example from one of the various [hooks](custom_quantum_functions.md). - -## Usage - -Add the following to your `rules.mk`: - -```make -SECURE_ENABLE = yes -``` - -## Keycodes - -| Key |Aliases | Description | -|---------------------|---------|--------------------------------------------------------------------------------| -| `QK_SECURE_LOCK` |`SE_LOCK`| Revert back to a locked state | -| `QK_SECURE_UNLOCK` |`SE_UNLK`| Forces unlock without performing a unlock sequence | -| `QK_SECURE_TOGGLE` |`SE_TOGG`| Toggle directly between locked and unlock without performing a unlock sequence | -| `QK_SECURE_REQUEST` |`SE_REQ` | Request that user perform the unlock sequence | - -## Configuration - -| Define | Default | Description | -|-------------------------|----------------|---------------------------------------------------------------------------------| -|`SECURE_UNLOCK_TIMEOUT` | `5000` | Timeout for the user to perform the configured unlock sequence - `0` to disable | -|`SECURE_IDLE_TIMEOUT` | `60000` | Timeout while unlocked before returning to locked - `0` to disable | -|`SECURE_UNLOCK_SEQUENCE` | `{ { 0, 0 } }` | Array of matrix locations describing a sequential sequence of keypresses | - -## Functions - -| Function | Description | -|---------------------------|----------------------------------------------------------------------------| -| `secure_is_locked()` | Check if the device is currently locked | -| `secure_is_unlocking()` | Check if an unlock sequence is currently in progress | -| `secure_is_unlocked()` | Check if the device is currently unlocked | -| `secure_lock()` | Lock down the device | -| `secure_unlock()` | Force unlock the device - bypasses user unlock sequence | -| `secure_request_unlock()` | Begin listening for an unlock sequence | -| `secure_activity_event()` | Flag that user activity has happened and the device should remain unlocked | diff --git a/docs/feature_send_string.md b/docs/feature_send_string.md deleted file mode 100644 index 67df0224e93b..000000000000 --- a/docs/feature_send_string.md +++ /dev/null @@ -1,224 +0,0 @@ -# Send String - -The Send String API is part of QMK's macro system. It allows for sequences of keystrokes to be sent automatically. - -The full ASCII character set is supported, along with all of the keycodes in the Basic Keycode range (as these are the only ones that will actually be sent to the host). - -?> Unicode characters are **not** supported with this API -- see the [Unicode](feature_unicode.md) feature instead. - -## Usage - -Send String is enabled by default, so there is usually no need for any special setup. However, if it is disabled, add the following to your `rules.mk`: - -```make -SEND_STRING_ENABLE = yes -``` - -## Basic Configuration - -Add the following to your `config.h`: - -|Define |Default |Description | -|-----------------|----------------|------------------------------------------------------------------------------------------------------------| -|`SENDSTRING_BELL`|*Not defined* |If the [Audio](feature_audio.md) feature is enabled, the `\a` character (ASCII `BEL`) will beep the speaker.| -|`BELL_SOUND` |`TERMINAL_SOUND`|The song to play when the `\a` character is encountered. By default, this is an eighth note of C5. | - -## Keycodes - -The Send String functions accept C string literals, but specific keycodes can be injected with the below macros. All of the keycodes in the [Basic Keycode range](keycodes_basic.md) are supported (as these are the only ones that will actually be sent to the host), but with an `X_` prefix instead of `KC_`. - -|Macro |Description | -|--------------|-------------------------------------------------------------------| -|`SS_TAP(x)` |Send a keydown, then keyup, event for the given Send String keycode| -|`SS_DOWN(x)` |Send a keydown event for the given Send String keycode | -|`SS_UP(x)` |Send a keyup event for the given Send String keycode | -|`SS_DELAY(ms)`|Wait for `ms` milliseconds | - -The following characters are also mapped to their respective keycodes for convenience: - -|Character|Hex |ASCII|Keycode | -|---------|------|-----|--------------| -|`\b` |`\x08`|`BS` |`KC_BACKSPACE`| -|`\e` |`\x09`|`ESC`|`KC_ESCAPE` | -|`\n` |`\x0A`|`LF` |`KC_ENTER` | -|`\t` |`\x1B`|`TAB`|`KC_TAB` | -| |`\x7F`|`DEL`|`KC_DELETE` | - -### Language Support - -By default, Send String assumes your OS keyboard layout is set to US ANSI. If you are using a different keyboard layout, you can [override the lookup tables used to convert ASCII characters to keystrokes](reference_keymap_extras.md#sendstring-support). - -## Examples - -### Hello World - -A simple custom keycode which types out "Hello, world!" and the Enter key when pressed. - -Add the following to your `keymap.c`: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SS_HELLO: - if (record->event.pressed) { - SEND_STRING("Hello, world!\n"); - } - return false; - } - - return true; -} -``` - -### Keycode Injection - -This example types out opening and closing curly braces, then taps the left arrow key to move the cursor between the two. - -```c -SEND_STRING("{}" SS_TAP(X_LEFT)); -``` - -This example types Ctrl+A, then Ctrl+C, without releasing Ctrl. - -```c -SEND_STRING(SS_LCTL("ac")); -``` - -## API - -### `void send_string(const char *string)` - -Type out a string of ASCII characters. - -This function simply calls `send_string_with_delay(string, 0)`. - -#### Arguments - - - `const char *string` - The string to type out. - ---- - -### `void send_string_with_delay(const char *string, uint8_t interval)` - -Type out a string of ASCII characters, with a delay between each character. - -#### Arguments - - - `const char *string` - The string to type out. - - `uint8_t interval` - The amount of time, in milliseconds, to wait before typing the next character. - ---- - -### `void send_string_P(const char *string)` - -Type out a PROGMEM string of ASCII characters. - -On ARM devices, this function is simply an alias for `send_string_with_delay(string, 0)`. - -#### Arguments - - - `const char *string` - The string to type out. - ---- - -### `void send_string_with_delay_P(const char *string, uint8_t interval)` - -Type out a PROGMEM string of ASCII characters, with a delay between each character. - -On ARM devices, this function is simply an alias for `send_string_with_delay(string, interval)`. - -#### Arguments - - - `const char *string` - The string to type out. - - `uint8_t interval` - The amount of time, in milliseconds, to wait before typing the next character. - ---- - -### `void send_char(char ascii_code)` - -Type out an ASCII character. - -#### Arguments - - - `char ascii_code` - The character to type. - ---- - -### `void send_dword(uint32_t number)` - -Type out an eight digit (unsigned 32-bit) hexadecimal value. - -The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`. - -#### Arguments - - - `uint32_t number` - The value to type, from 0 to 4,294,967,295. - ---- - -### `void send_word(uint16_t number)` - -Type out a four digit (unsigned 16-bit) hexadecimal value. - -The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`. - -#### Arguments - - - `uint16_t number` - The value to type, from 0 to 65,535. - ---- - -### `void send_byte(uint8_t number)` - -Type out a two digit (8-bit) hexadecimal value. - -The format is `[0-9a-f]{2}`, eg. `00` through `ff`. - -#### Arguments - - - `uint8_t number` - The value to type, from 0 to 255. - ---- - -### `void send_nibble(uint8_t number)` - -Type out a single hexadecimal digit. - -The format is `[0-9a-f]{1}`, eg. `0` through `f`. - -#### Arguments - - - `uint8_t number` - The value to type, from 0 to 15. - ---- - -### `void tap_random_base64(void)` - -Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`. - ---- - -### `SEND_STRING(string)` - -Shortcut macro for `send_string_with_delay_P(PSTR(string), 0)`. - -On ARM devices, this define evaluates to `send_string_with_delay(string, 0)`. - ---- - -### `SEND_STRING_DELAY(string, interval)` - -Shortcut macro for `send_string_with_delay_P(PSTR(string), interval)`. - -On ARM devices, this define evaluates to `send_string_with_delay(string, interval)`. diff --git a/docs/feature_sequencer.md b/docs/feature_sequencer.md deleted file mode 100644 index 87a277400a23..000000000000 --- a/docs/feature_sequencer.md +++ /dev/null @@ -1,87 +0,0 @@ -# Sequencer - -Since QMK has experimental support for MIDI, you can now turn your keyboard into a [step sequencer](https://en.wikipedia.org/wiki/Music_sequencer#Step_sequencers)! - -!> **IMPORTANT:** This feature is highly experimental, it has only been tested on a Planck EZ so far. Also, the scope will be limited to support the drum machine use-case to start with. - -## Enable the step sequencer - -Add the following line to your `rules.mk`: - -```make -SEQUENCER_ENABLE = yes -``` - -By default the sequencer has 16 steps, but you can override this setting in your `config.h`: - -```c -#define SEQUENCER_STEPS 32 -``` - -## Tracks - -You can program up to 8 independent tracks with the step sequencer. Select the tracks you want to edit, enable or disable some steps, and start the sequence! - -## Resolutions - -While the tempo defines the absolute speed at which the sequencer goes through the steps, the resolution defines the granularity of these steps (from coarser to finer). - -|Resolution |Description | -|---------- |----------- | -|`SQ_RES_2` |Every other beat | -|`SQ_RES_2T` |Every 1.5 beats | -|`SQ_RES_4` |Every beat | -|`SQ_RES_4T` |Three times per 2 beats| -|`SQ_RES_8` |Twice per beat | -|`SQ_RES_8T` |Three times per beat | -|`SQ_RES_16` |Four times per beat | -|`SQ_RES_16T` |Six times per beat | -|`SQ_RES_32` |Eight times per beat | - -## Keycodes - -|Key |Aliases |Description | -|-------------------------------|---------|---------------------------------------------------| -|`QK_SEQUENCER_ON` |`SQ_ON` |Start the step sequencer | -|`QK_SEQUENCER_OFF` |`SQ_OFF` |Stop the step sequencer | -|`QK_SEQUENCER_TOGGLE` |`SQ_TOG` |Toggle the step sequencer playback | -|`QK_SEQUENCER_STEPS_ALL` |`SQ_SALL`|Enable all the steps | -|`QK_SEQUENCER_STEPS_CLEAR` |`SQ_SCLR`|Disable all the steps | -|`QK_SEQUENCER_TEMPO_DOWN` |`SQ_TMPD`|Decrease the tempo | -|`QK_SEQUENCER_TEMPO_UP` |`SQ_TMPU`|Increase the tempo | -|`QK_SEQUENCER_RESOLUTION_DOWN` |`SQ_RESD`|Change to the slower resolution | -|`QK_SEQUENCER_RESOLUTION_UP` |`SQ_RESU`|Change to the faster resolution | -|`SQ_S(n)` | |Toggle the step `n` | -|`SQ_R(n)` | |Set the resolution to n | -|`SQ_T(n)` | |Set `n` as the only active track or deactivate all | - -## Functions - -|Function |Description | -|-------- |----------- | -|`bool is_sequencer_on(void);` |Return whether the sequencer is playing | -|`void sequencer_toggle(void);` |Toggle the step sequencer playback | -|`void sequencer_on(void);` |Start the step sequencer | -|`void sequencer_off(void);` |Stop the step sequencer | -|`bool is_sequencer_step_on(uint8_t step);` |Return whether the step is currently enabled | -|`void sequencer_set_step(uint8_t step, bool value);` |Enable or disable the step | -|`void sequencer_set_step_on();` |Enable the step | -|`void sequencer_set_step_off();` |Disable the step | -|`void sequencer_toggle_step(uint8_t step);` |Toggle the step | -|`void sequencer_set_all_steps(bool value);` |Enable or disable all the steps | -|`void sequencer_set_all_steps_on();` |Enable all the steps | -|`void sequencer_set_all_steps_off();` |Disable all the steps | -|`uint8_t sequencer_get_tempo(void);` |Return the current tempo | -|`void sequencer_set_tempo(uint8_t tempo);` |Set the tempo to `tempo` (between 1 and 255) | -|`void sequencer_increase_tempo(void);` |Increase the tempo | -|`void sequencer_decrease_tempo(void);` |Decrease the tempo | -|`sequencer_resolution_t sequencer_get_resolution(void);` |Return the current resolution | -|`void sequencer_set_resolution(sequencer_resolution_t resolution);` |Set the resolution to `resolution` | -|`void sequencer_increase_resolution(void);` |Change to the faster resolution | -|`void sequencer_decrease_resolution(void);` |Change to the slower resolution | -|`bool is_sequencer_track_active(uint8_t track);` |Return whether the track is active | -|`void sequencer_set_track_activation(uint8_t track, bool value);` |Activate or deactivate the `track` | -|`void sequencer_toggle_track_activation(uint8_t track);` |Toggle the `track` | -|`void sequencer_activate_track(uint8_t track);` |Activate the `track` | -|`void sequencer_deactivate_track(uint8_t track);` |Deactivate the `track` | -|`void sequencer_toggle_single_active_track(uint8_t track);` |Set `track` as the only active track or deactivate all | diff --git a/docs/feature_space_cadet.md b/docs/feature_space_cadet.md deleted file mode 100644 index 223a5b3ccf69..000000000000 --- a/docs/feature_space_cadet.md +++ /dev/null @@ -1,60 +0,0 @@ -# Space Cadet: The Future, Built In - -Steve Losh described the [Space Cadet Shift](https://web.archive.org/web/20230330090938/https://stevelosh.com/blog/2012/10/a-modern-space-cadet/) quite well. Essentially, when you tap Left Shift on its own, you get an opening parenthesis; tap Right Shift on its own and you get the closing one. When held, the Shift keys function as normal. Yes, it's as cool as it sounds, and now even cooler supporting Control and Alt as well! - -## Usage - -Firstly, in your keymap, do one of the following: -- Replace the Left Shift key with `SC_LSPO` (Left Shift, Parenthesis Open), and Right Shift with `SC_RSPC` (Right Shift, Parenthesis Close). -- Replace the Left Control key with `SC_LCPO` (Left Control, Parenthesis Open), and Right Control with `SC_RCPC` (Right Control, Parenthesis Close). -- Replace the Left Alt key with `SC_LAPO` (Left Alt, Parenthesis Open), and Right Alt with `SC_RAPC` (Right Alt, Parenthesis Close). -- Replace any Shift key in your keymap with `SC_SENT` (Right Shift, Enter). - -## Keycodes - -|Keycode |Aliases |Description | -|----------------------------------------------|---------|----------------------------------------| -|`QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN` |`SC_LCPO`|Left Control when held, `(` when tapped | -|`QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE` |`SC_RCPC`|Right Control when held, `)` when tapped| -|`QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN` |`SC_LSPO`|Left Shift when held, `(` when tapped | -|`QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE`|`SC_RSPC`|Right Shift when held, `)` when tapped | -|`QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN` |`SC_LAPO`|Left Alt when held, `(` when tapped | -|`QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE` |`SC_RAPC`|Right Alt when held, `)` when tapped | -|`QK_SPACE_CADET_RIGHT_SHIFT_ENTER` |`SC_SENT`|Right Shift when held, Enter when tapped| - -## Caveats - -Space Cadet's functionality can conflict with the default Command functionality when both Shift keys are held at the same time. See the [Command feature](feature_command.md) for info on how to change it, or make sure that Command is disabled in your `rules.mk` with: - -```make -COMMAND_ENABLE = no -``` - -## Configuration - -By default Space Cadet assumes a US ANSI layout, but if your layout uses different keys for parentheses, you can redefine them in your `config.h`. In addition, you can redefine the modifier to send on tap, or even send no modifier at all. The new configuration defines bundle all options up into a single define of 3 key codes in this order: the `Modifier` when held or when used with other keys, the `Tap Modifer` sent when tapped (no modifier if `KC_TRNS`), finally the `Keycode` sent when tapped. Now keep in mind, mods from other keys will still apply to the `Keycode` if say `KC_RSFT` is held while tapping `SC_LSPO` key with `KC_TRNS` as the `Tap Modifer`. - -|Define |Default |Description | -|----------------|-------------------------------|---------------------------------------------------------------------------------| -|`LSPO_KEYS` |`KC_LSFT, LSPO_MOD, LSPO_KEY` |Send `KC_LSFT` when held, the mod and key defined by `LSPO_MOD` and `LSPO_KEY`. | -|`RSPC_KEYS` |`KC_RSFT, RSPC_MOD, RSPC_KEY` |Send `KC_RSFT` when held, the mod and key defined by `RSPC_MOD` and `RSPC_KEY`. | -|`LCPO_KEYS` |`KC_LCTL, KC_LSFT, KC_9` |Send `KC_LCTL` when held, the mod `KC_LSFT` with the key `KC_9` when tapped. | -|`RCPC_KEYS` |`KC_RCTL, KC_RSFT, KC_0` |Send `KC_RCTL` when held, the mod `KC_RSFT` with the key `KC_0` when tapped. | -|`LAPO_KEYS` |`KC_LALT, KC_LSFT, KC_9` |Send `KC_LALT` when held, the mod `KC_LSFT` with the key `KC_9` when tapped. | -|`RAPC_KEYS` |`KC_RALT, KC_RSFT, KC_0` |Send `KC_RALT` when held, the mod `KC_RSFT` with the key `KC_0` when tapped. | -|`SFTENT_KEYS` |`KC_RSFT, KC_TRNS, SFTENT_KEY` |Send `KC_RSFT` when held, no mod with the key `SFTENT_KEY` when tapped. | -|`SPACE_CADET_MODIFIER_CARRYOVER` |*Not defined* |Store current modifiers before the hold mod is pressed and use them with the tap mod and keycode. Useful for when you frequently release a modifier before triggering Space Cadet. | - - -## Obsolete Configuration - -These defines are used in the above defines internally to support backwards compatibility, so you may continue to use them, however the above defines open up a larger range of flexibility than before. As an example, say you want to not send any modifier when you tap just `SC_LSPO`, with the old defines you had an all or nothing choice of using the `DISABLE_SPACE_CADET_MODIFIER` define. Now you can define that key as: `#define LSPO_KEYS KC_LSFT, KC_TRNS, KC_9`. This tells the system to set Left Shift if held or used with other keys, then on tap send no modifier (transparent) with the `KC_9`. - -|Define |Default |Description | -|------------------------------|-------------|------------------------------------------------------------------| -|`LSPO_KEY` |`KC_9` |The keycode to send when Left Shift is tapped | -|`RSPC_KEY` |`KC_0` |The keycode to send when Right Shift is tapped | -|`LSPO_MOD` |`KC_LSFT` |The modifier to apply to `LSPO_KEY` | -|`RSPC_MOD` |`KC_RSFT` |The modifier to apply to `RSPC_KEY` | -|`SFTENT_KEY` |`KC_ENT` |The keycode to send when the Shift key is tapped | -|`DISABLE_SPACE_CADET_MODIFIER`|*Not defined*|If defined, prevent the Space Cadet from applying a modifier | diff --git a/docs/feature_split_keyboard.md b/docs/feature_split_keyboard.md deleted file mode 100644 index 1705ea922217..000000000000 --- a/docs/feature_split_keyboard.md +++ /dev/null @@ -1,486 +0,0 @@ -# Split Keyboard - -Many keyboards in the QMK Firmware repo are "split" keyboards. They use two controllers—one plugging into USB, and the second connected by a serial or an I2C connection over a TRRS or similar cable. - -Split keyboards can have a lot of benefits, but there is some additional work needed to get them enabled. - -QMK Firmware has a generic implementation that is usable by any board, as well as numerous board specific implementations. - -For this, we will mostly be talking about the generic implementation used by the Let's Split and other keyboards. - -!> ARM split supports most QMK subsystems when using the 'serial' and 'serial_usart' drivers. I2C slave is currently unsupported. - -!> Both sides must use the same MCU family, for eg two Pro Micro-compatible controllers or two Blackpills. Currently, mixing AVR and ARM is not possible as ARM vs AVR uses different method for serial communication, and are not compatible. Moreover Blackpill's uses 3.3v logic, and atmega32u4 uses 5v logic. - -## Compatibility Overview - -| Transport | AVR | ARM | -|------------------------------|--------------------|--------------------| -| ['serial'](serial_driver.md) | :heavy_check_mark: | :white_check_mark: 1 | -| I2C | :heavy_check_mark: | | - -Notes: - -1. Both hardware and software limitations are detailed within the [driver documentation](serial_driver.md). - -## Hardware Configuration - -This assumes that you're using two Pro Micro-compatible controllers, and are using TRRS jacks to connect to two halves. - -### Required Hardware - -Apart from diodes and key switches for the keyboard matrix in each half, you will need 2x TRRS sockets and 1x TRRS cable. - -Alternatively, you can use any sort of cable and socket that has at least 3 wires. - -If you want to use I2C to communicate between halves, you will need a cable with at least 4 wires and 2x 4.7kΩ pull-up resistors. - -#### Considerations - -The most commonly used connection is a TRRS cable and jacks. These provide 4 wires, making them very useful for split keyboards, and are easy to find. - -However, since one of the wires carries VCC, this means that the boards are not hot pluggable. You should always disconnect the board from USB before unplugging and plugging in TRRS cables, or you can short the controller, or worse. - -Another option is to use phone cables (as in, old school RJ-11/RJ-14 cables). Make sure that you use one that actually supports 4 wires/lanes. - -However, USB cables, SATA cables, and even just 4 wires have been known to be used for communication between the controllers. - -!> Using USB cables for communication between the controllers works just fine, but the connector could be mistaken for a normal USB connection and potentially short out the keyboard, depending on how it's wired. For this reason, they are not recommended for connecting split keyboards. - -### Serial Wiring - -The 3 wires of the TRS/TRRS cable need to connect GND, VCC, and D0/D1/D2/D3 (aka PD0/PD1/PD2/PD3) between the two Pro Micros. - -?> Note that the pin used here is actually set by `SOFT_SERIAL_PIN` below. - -sk-pd0-connection-mono -sk-pd2-connection-mono - -### I2C Wiring - -The 4 wires of the TRRS cable need to connect GND, VCC, and SCL and SDA (aka PD0/pin 3 and PD1/pin 2, respectively) between the two Pro Micros. - -The pull-up resistors may be placed on either half. If you wish to use the halves independently, it is also possible to use 4 resistors and have the pull-ups in both halves. -Note that the total resistance for the connected system should be within spec at 2.2k-10kOhm, with an 'ideal' at 4.7kOhm, regardless of the placement and number. - -sk-i2c-connection-mono - -## Firmware Configuration - -To enable the split keyboard feature, add the following to your `rules.mk`: - -```make -SPLIT_KEYBOARD = yes -``` - -If you're using a custom transport (communication method), then you will also need to add: - -```make -SPLIT_TRANSPORT = custom -``` - -### Layout Macro - -Configuring your layout in a split keyboard works slightly differently to a non-split keyboard. Take for example the following layout. The top left numbers refer to the matrix row and column, and the bottom right are the order of the keys in the layout: - -![Physical layout](https://i.imgur.com/QeY6kMQ.png) - -Since the matrix scanning procedure operates on entire rows, it first populates the left half's rows, then the right half's. Thus, the matrix as QMK views it has double the rows instead of double the columns: - -![Matrix](https://i.imgur.com/4wjJzBU.png) - -### Setting Handedness - -By default, the firmware does not know which side is which; it needs some help to determine that. There are several ways to do this, listed in order of precedence. - -#### Handedness by Pin - -You can configure the firmware to read a pin on the controller to determine handedness. To do this, add the following to your `config.h` file: - -```c -#define SPLIT_HAND_PIN B7 -``` - -This will read the specified pin. By default, if it's high, then the controller assumes it is the left hand, and if it's low, it's assumed to be the right side. - -This behaviour can be flipped by adding this to you `config.h` file: - -```c -#define SPLIT_HAND_PIN_LOW_IS_LEFT -``` - -#### Handedness by Matrix Pin - -You can configure the firmware to read key matrix pins on the controller to determine handedness. To do this, add the following to your `config.h` file: - -```c -#define SPLIT_HAND_MATRIX_GRID D0, F1 -``` - -The first pin is the output pin and the second is the input pin. - -Some keyboards have unused intersections in the key matrix. This setting uses one of these unused intersections to determine the handness. - -Normally, when a diode is connected to an intersection, it is judged to be left. If you add the following definition, it will be judged to be right. - -```c -#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT -``` - -Note that adding a diode at a previously unused intersection will effectively tell the firmware that there is a key held down at that point. You can instruct qmk to ignore that intersection by defining `MATRIX_MASKED` and then defining a `matrix_row_t matrix_mask[MATRIX_ROWS]` array in your keyboard config. Each bit of a single value (starting form the least-significant bit) is used to tell qmk whether or not to pay attention to key presses at that intersection. - -While `MATRIX_MASKED` isn't necessary to use `SPLIT_HAND_MATRIX_GRID` successfully, without it you may experience issues trying to suspend your computer with your keyboard attached as the matrix will always report at least one key-press. - -#### Handedness by EEPROM - -This method sets the keyboard's handedness by setting a flag in the persistent storage (`EEPROM`). This is checked when the controller first starts up, and determines what half the keyboard is, and how to orient the keyboard layout. - - -To enable this method, add the following to your `config.h` file: - -```c -#define EE_HANDS -``` - -Next, you will have to flash the correct handedness option to the controller on each halve. You can do this manually with the following bootloader targets using `qmk flash -kb -km -bl ` command to flash: - -|Microcontroller Type|Bootloader Parameter| -|--------------------|--------------------| -|AVR controllers with Caterina bootloader
(e.g. Pro Micro)|`avrdude-split-left`
`avrdude-split-right`| -|AVR controllers with the stock Amtel DFU or DFU compatible bootloader
(e.g. Elite-C)|`dfu-split-left`
`dfu-split-right`| -|ARM controllers with a DFU compatible bootloader
(e.g. Proton-C)|`dfu-util-split-left`
`dfu-util-split-right`| -|ARM controllers with a UF2 compatible bootloader
(e.g. RP2040)|`uf2-split-left`
`uf2-split-right`| - -Example for `crkbd/rev1` keyboard with normal AVR Pro Micro MCUs, reset the left controller and run: -``` -qmk flash -kb crkbd/rev1 -km default -bl avrdude-split-left -``` -Reset the right controller and run: -``` -qmk flash -kb crkbd/rev1 -km default -bl avrdude-split-right -``` - -?> Some controllers (e.g. Blackpill with DFU compatible bootloader) will need to be flashed with handedness bootloader parameter every time because it is not retained between flashes. - -?> [QMK Toolbox]() can also be used to flash EEPROM handedness files. Place the controller in bootloader mode and select menu option Tools -> EEPROM -> Set Left/Right Hand - -This setting is not changed when re-initializing the EEPROM using the `EE_CLR` key, or using the `eeconfig_init()` function. However, if you reset the EEPROM outside of the firmware's built in options (such as flashing a file that overwrites the `EEPROM`, like how the [QMK Toolbox]()'s "Reset EEPROM" button works), you'll need to re-flash the controller with the `EEPROM` files. - -You can find the `EEPROM` files in the QMK firmware repo, [here](https://github.com/qmk/qmk_firmware/tree/master/quantum/split_common). - - -#### Handedness by `#define` - -You can use this option when USB cable is always connected to just one side of the split keyboard. - -If the USB cable is always connected to the right side, add the following to your `config.h` file and flash both sides with this option: -```c -#define MASTER_RIGHT -``` - -If the USB cable is always connected to the left side, add the following to your `config.h` file and flash both sides with this option: -```c -#define MASTER_LEFT -``` - -?> If neither options are defined, the handedness defaults to `MASTER_LEFT`. - - -### Communication Options - -Because not every split keyboard is identical, there are a number of additional options that can be configured in your `config.h` file. - -```c -#define USE_I2C -``` - -This configures the use of I2C support for split keyboard transport (AVR only). - -```c -#define SOFT_SERIAL_PIN D0 -``` - -This sets the pin to be used for serial communication. If you're not using serial, you shouldn't need to define this. - -However, if you are using serial and I2C on the board, you will need to set this, and to something other than D0 and D1 (as these are used for I2C communication). - -```c -#define SELECT_SOFT_SERIAL_SPEED {#}` -``` - -If you're having issues with serial communication, you can change this value, as it controls the communication speed for serial. The default is 1, and the possible values are: - -* **`0`**: about 189kbps (Experimental only) -* **`1`**: about 137kbps (default) -* **`2`**: about 75kbps -* **`3`**: about 39kbps -* **`4`**: about 26kbps -* **`5`**: about 20kbps - -```c -#define FORCED_SYNC_THROTTLE_MS 100 -``` - -This sets the maximum number of milliseconds before forcing a synchronization of data from master to slave. Under normal circumstances this sync occurs whenever the data _changes_, for safety a data transfer occurs after this number of milliseconds if no change has been detected since the last sync. - -```c -#define SPLIT_MAX_CONNECTION_ERRORS 10 -``` -This sets the maximum number of failed communication attempts (one per scan cycle) from the master part before it assumes that no slave part is connected. This makes it possible to use a master part without the slave part connected. - -Set to 0 to disable the disconnection check altogether. - -```c -#define SPLIT_CONNECTION_CHECK_TIMEOUT 500 -``` -How long (in milliseconds) the master part should block all connection attempts to the slave after the communication has been flagged as disconnected (see `SPLIT_MAX_CONNECTION_ERRORS` above). - -One communication attempt will be allowed everytime this amount of time has passed since the last attempt. If that attempt succeeds, the communication is seen as working again. - -Set to 0 to disable this throttling of communications while disconnected. This can save you a couple of bytes of firmware size. - - -### Data Sync Options - -The following sync options add overhead to the split communication protocol and may negatively impact the matrix scan speed when enabled. These can be enabled by adding the chosen option(s) to your `config.h` file. - -```c -#define SPLIT_TRANSPORT_MIRROR -``` - -This mirrors the master side matrix to the slave side for features that react or require knowledge of master side key presses on the slave side. The purpose of this feature is to support cosmetic use of key events (e.g. RGB reacting to keypresses). - -```c -#define SPLIT_LAYER_STATE_ENABLE -``` - -This enables syncing of the layer state between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the currently active layer. - -```c -#define SPLIT_LED_STATE_ENABLE -``` - -This enables syncing of the Host LED status (caps lock, num lock, etc) between both halves of the split keyboard. The main purpose of this feature is to enable support for use of things like OLED display of the Host LED status. - -```c -#define SPLIT_MODS_ENABLE -``` - -This enables transmitting modifier state (normal, weak and oneshot) to the non primary side of the split keyboard. The purpose of this feature is to support cosmetic use of modifer state (e.g. displaying status on an OLED screen). - -```c -#define SPLIT_WPM_ENABLE -``` - -This enables transmitting the current WPM to the slave side of the split keyboard. The purpose of this feature is to support cosmetic use of WPM (e.g. displaying the current value on an OLED screen). - -```c -#define SPLIT_OLED_ENABLE -``` - -This enables transmitting the current OLED on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing. - -```c -#define SPLIT_ST7565_ENABLE -``` - -This enables transmitting the current ST7565 on/off status to the slave side of the split keyboard. The purpose of this feature is to support state (on/off state only) syncing. - -```c -#define SPLIT_POINTING_ENABLE -``` - -This enables transmitting the pointing device status to the master side of the split keyboard. The purpose of this feature is to enable use pointing devices on the slave side. - -!> There is additional required configuration for `SPLIT_POINTING_ENABLE` outlined in the [pointing device documentation](feature_pointing_device.md?id=split-keyboard-configuration). - -```c -#define SPLIT_HAPTIC_ENABLE -``` - -This enables triggering of haptic feedback on the slave side of the split keyboard. For DRV2605L this will send the mode, but for solenoids it is expected that the desired mode is already set up on the slave. - -```c -#define SPLIT_ACTIVITY_ENABLE -``` - -This synchronizes the activity timestamps between sides of the split keyboard, allowing for activity timeouts to occur. - -### Custom data sync between sides :id=custom-data-sync - -QMK's split transport allows for arbitrary data transactions at both the keyboard and user levels. This is modelled on a remote procedure call, with the master invoking a function on the slave side, with the ability to send data from master to slave, process it slave side, and send data back from slave to master. - -To leverage this, a keyboard or user/keymap can define a comma-separated list of _transaction IDs_: - -```c -// for keyboard-level data sync: -#define SPLIT_TRANSACTION_IDS_KB KEYBOARD_SYNC_A, KEYBOARD_SYNC_B -// or, for user: -#define SPLIT_TRANSACTION_IDS_USER USER_SYNC_A, USER_SYNC_B, USER_SYNC_C -``` - -These _transaction IDs_ then need a slave-side handler function to be registered with the split transport, for example: - -```c -typedef struct _master_to_slave_t { - int m2s_data; -} master_to_slave_t; - -typedef struct _slave_to_master_t { - int s2m_data; -} slave_to_master_t; - -void user_sync_a_slave_handler(uint8_t in_buflen, const void* in_data, uint8_t out_buflen, void* out_data) { - const master_to_slave_t *m2s = (const master_to_slave_t*)in_data; - slave_to_master_t *s2m = (slave_to_master_t*)out_data; - s2m->s2m_data = m2s->m2s_data + 5; // whatever comes in, add 5 so it can be sent back -} - -void keyboard_post_init_user(void) { - transaction_register_rpc(USER_SYNC_A, user_sync_a_slave_handler); -} -``` - -The master side can then invoke the slave-side handler - for normal keyboard functionality to be minimally affected, any keyboard- or user-level code attempting to sync data should be throttled: - -```c -void housekeeping_task_user(void) { - if (is_keyboard_master()) { - // Interact with slave every 500ms - static uint32_t last_sync = 0; - if (timer_elapsed32(last_sync) > 500) { - master_to_slave_t m2s = {6}; - slave_to_master_t s2m = {0}; - if(transaction_rpc_exec(USER_SYNC_A, sizeof(m2s), &m2s, sizeof(s2m), &s2m)) { - last_sync = timer_read32(); - dprintf("Slave value: %d\n", s2m.s2m_data); // this will now be 11, as the slave adds 5 - } else { - dprint("Slave sync failed!\n"); - } - } - } -} -``` - -!> It is recommended that any data sync between halves happens during the master side's _housekeeping task_. This ensures timely retries should failures occur. - -If only one-way data transfer is needed, helper methods are provided: - -```c -bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); -bool transaction_rpc_send(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer); -bool transaction_rpc_recv(int8_t transaction_id, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); -``` - -By default, the inbound and outbound data is limited to a maximum of 32 bytes each. The sizes can be altered if required: - -```c -// Master to slave: -#define RPC_M2S_BUFFER_SIZE 48 -// Slave to master: -#define RPC_S2M_BUFFER_SIZE 48 -``` - -### Hardware Configuration Options - -There are some settings that you may need to configure, based on how the hardware is set up. - -```c -#define MATRIX_ROW_PINS_RIGHT { } -#define MATRIX_COL_PINS_RIGHT { } -``` - -This allows you to specify a different set of pins for the matrix on the right side. This is useful if you have a board with differently-shaped halves that requires a different configuration (such as Keebio's Quefrency). The number of pins in the right and left matrices must be the same, if you have a board with a different number of rows or columns on one side, pad out the extra spaces with `NO_PIN` and make sure you add the unused rows or columns to your matrix. - -```c -#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } } -``` - -This allows you to specify a different set of direct pins for the right side. - -```c -#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } -#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } -``` - -This allows you to specify a different set of encoder pins for the right side. - -```c -#define RGBLIGHT_SPLIT -``` - -This option enables synchronization of the RGB Light modes between the controllers of the split keyboard. This is for keyboards that have RGB LEDs that are directly wired to the controller (that is, they are not using the "extra data" option on the TRRS cable). - -```c -#define RGBLED_SPLIT { 6, 6 } -``` - -This sets how many LEDs are directly connected to each controller. The first number is the left side, and the second number is the right side. - -?> This setting implies that `RGBLIGHT_SPLIT` is enabled, and will forcibly enable it, if it's not. - - -```c -#define SPLIT_USB_DETECT -``` - -Enabling this option changes the startup behavior to listen for an active USB communication to delegate which part is master and which is slave. With this option enabled and theres's USB communication, then that half assumes it is the master, otherwise it assumes it is the slave. - -Without this option, the master is the half that can detect voltage on the physical USB connection (VBUS detection). - -Enabled by default on ChibiOS/ARM. - -?> This setting will stop the ability to demo using battery packs. - -```c -#define SPLIT_USB_TIMEOUT 2000 -``` -This sets the maximum timeout when detecting master/slave when using `SPLIT_USB_DETECT`. - -```c -#define SPLIT_USB_TIMEOUT_POLL 10 -``` -This sets the poll frequency when detecting master/slave when using `SPLIT_USB_DETECT` - -```c -#define SPLIT_WATCHDOG_ENABLE -``` - -This will enable a software watchdog on any side delegated as slave and will reboot the keyboard if no successful communication occurs within `SPLIT_WATCHDOG_TIMEOUT`. This can be particularly helpful when `SPLIT_USB_DETECT` delegates both sides as slave in some circumstances. - -```c -#define SPLIT_WATCHDOG_TIMEOUT 3000 -``` -This set the maximum slave timeout when waiting for communication from master when using `SPLIT_WATCHDOG_ENABLE` - -## Hardware Considerations and Mods - -Master/slave delegation is made either by detecting voltage on VBUS connection or waiting for USB communication (`SPLIT_USB_DETECT`). Pro Micro boards can use VBUS detection out of the box and be used with or without `SPLIT_USB_DETECT`. - -Many ARM boards, but not all, do not support VBUS detection. Because it is common that ARM boards lack VBUS detection, `SPLIT_USB_DETECT` is automatically defined on ARM targets (technically when ChibiOS is targetted). - -### Teensy boards - -Teensy boards lack VBUS detection out of the box and must have `SPLIT_USB_DETECT` defined. With the Teensy 2.0 and Teensy++ 2.0, there is a simple hardware mod that you can perform to add VBUS detection, so you don't need the `SPLIT_USB_DETECT` option. - -You'll only need a few things: - -* A knife (x-acto knife, ideally) -* A solder station or hot air station -* An appropriate Schottky diode, such as the [PMEG2005EH](https://www.digikey.com/en/products/detail/nexperia-usa-inc/PMEG2005EH,115/1589924) - -You'll need to cut the small trace between the 5V and center pads on the back of the Teensy. - -Once you have done that, you will want to solder the diode from the 5V pad to the center pad. - -You may need to use the 5V pad from the regulator block above as the pads were too small and placed too closely together to place the Schottky diode properly. - -![Teensy++ 2.0](https://i.imgur.com/BPEC5n5.png) - -## Additional Resources - -Nicinabox has a [very nice and detailed guide](https://github.com/nicinabox/lets-split-guide) for the Let's Split keyboard, that covers most everything you need to know, including troubleshooting information. - -However, the RGB Light section is out of date, as it was written long before the RGB Split code was added to QMK Firmware. Instead, wire each strip up directly to the controller. - - diff --git a/docs/feature_st7565.md b/docs/feature_st7565.md deleted file mode 100644 index de3e44d8e931..000000000000 --- a/docs/feature_st7565.md +++ /dev/null @@ -1,274 +0,0 @@ -# ST7565 LCD Driver - -## Supported Hardware - -LCD modules using ST7565 driver IC, communicating over SPI. - -|Module |IC |Size |Notes | -|------------------------------|-------|------|----------------------------------------------------------| -|Newhaven Display NHD-C12832A1Z|ST7565R|128x32|Used by Ergodox Infinity; primary consumer of this feature| -|Zolentech ZLE12864B |ST7565P|128x64|Requires contrast adjustment | - -## Usage - -To enable the feature, there are three steps. First, when compiling your keyboard, you'll need to add the following to your `rules.mk`: - -```make -ST7565_ENABLE = yes -``` - -Then in your `keymap.c` file, implement the ST7565 task call. This example assumes your keymap has three layers named `_QWERTY`, `_FN` and `_ADJ`: - -```c -#ifdef ST7565_ENABLE -void st7565_task_user(void) { - // Host Keyboard Layer Status - st7565_write_P(PSTR("Layer: "), false); - - switch (get_highest_layer(layer_state)) { - case _QWERTY: - st7565_write_P(PSTR("Default\n"), false); - break; - case _FN: - st7565_write_P(PSTR("FN\n"), false); - break; - case _ADJ: - st7565_write_P(PSTR("ADJ\n"), false); - break; - default: - // Or use the write_ln shortcut over adding '\n' to the end of your string - st7565_write_ln_P(PSTR("Undefined"), false); - } - - // Host Keyboard LED Status - led_t led_state = host_keyboard_led_state(); - st7565_write_P(led_state.num_lock ? PSTR("NUM ") : PSTR(" "), false); - st7565_write_P(led_state.caps_lock ? PSTR("CAP ") : PSTR(" "), false); - st7565_write_P(led_state.scroll_lock ? PSTR("SCR ") : PSTR(" "), false); -} -#endif -``` - -## Logo Example - -In the default font, certain ranges of characters are reserved for a QMK logo. To render this logo to the screen, use the following code example: - -```c -static void render_logo(void) { - static const char PROGMEM qmk_logo[] = { - 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, - 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, - 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0x00 - }; - - st7565_write_P(qmk_logo, false); -} -``` - -## Buffer Read Example -For some purposes, you may need to read the current state of the display buffer. The `st7565_read_raw` function can be used to safely read bytes from the buffer. - -In this example, calling `fade_display` in the `st7565_task_user` function will slowly fade away whatever is on the screen by turning random pixels off over time. -```c -//Setup some mask which can be or'd with bytes to turn off pixels -const uint8_t single_bit_masks[8] = {127, 191, 223, 239, 247, 251, 253, 254}; - -static void fade_display(void) { - //Define the reader structure - display_buffer_reader_t reader; - uint8_t buff_char; - if (random() % 30 == 0) { - srand(timer_read()); - // Fetch a pointer for the buffer byte at index 0. The return structure - // will have the pointer and the number of bytes remaining from this - // index position if we want to perform a sequential read by - // incrementing the buffer pointer - reader = st7565_read_raw(0); - //Loop over the remaining buffer and erase pixels as we go - for (uint16_t i = 0; i < reader.remaining_element_count; i++) { - //Get the actual byte in the buffer by dereferencing the pointer - buff_char = *reader.current_element; - if (buff_char != 0) { - st7565_write_raw_byte(buff_char & single_bit_masks[rand() % 8], i); - } - //increment the pointer to fetch a new byte during the next loop - reader.current_element++; - } - } -} -``` - -## Other Examples - -In split keyboards, it is very common to have two displays that each render different content and are oriented or flipped differently. You can do this by switching which content to render by using the return value from `is_keyboard_master()` or `is_keyboard_left()` found in `split_util.h`, e.g: - -```c -#ifdef ST7565_ENABLE -display_rotation_t st7565_init_user(display_rotation_t rotation) { - if (!is_keyboard_master()) { - return DISPLAY_ROTATION_180; // flips the display 180 degrees if offhand - } - - return rotation; -} - -void st7565_task_user(void) { - if (is_keyboard_master()) { - render_status(); // Renders the current keyboard state (layer, lock, caps, scroll, etc) - } else { - render_logo(); // Renders a static logo - } -} -#endif -``` - -## Basic Configuration - -|Define |Default |Description | -|------------------------|--------------|-----------------------------------------------------------------------------------------------------| -|`ST7565_A0_PIN` |*Not defined* |(Required) The GPIO connected to the display's A0 (data/command) pin | -|`ST7565_RST_PIN` |*Not defined* |(Required) The GPIO connected to the display's reset pin | -|`ST7565_SS_PIN` |*Not defined* |(Required) The GPIO connected to the display's slave select pin | -|`ST7565_SPI_CLK_DIVISOR`|`4` |The SPI clock divisor to use | -|`ST7565_FONT_H` |`"glcdfont.c"`|The font code file to use for custom fonts | -|`ST7565_FONT_START` |`0` |The starting character index for custom fonts | -|`ST7565_FONT_END` |`223` |The ending character index for custom fonts | -|`ST7565_FONT_WIDTH` |`6` |The font width | -|`ST7565_FONT_HEIGHT` |`8` |The font height (untested) | -|`ST7565_TIMEOUT` |`60000` |Turns off the screen after 60000ms of keyboard inactivity. Helps reduce burn-in. Set to 0 to disable.| -|`ST7565_COLUMN_OFFSET` |`0` |Shift output to the right this many pixels. | -|`ST7565_CONTRAST` |`32` |The default contrast level of the display, from 0 to 255. | -|`ST7565_UPDATE_INTERVAL`|`0` |Set the time interval for updating the display in ms. This will improve the matrix scan rate. | - -## Custom sized displays - -The default display size for this feature is 128x32 and all necessary defines are precalculated with that in mind. - -|Define |Default |Description | -|-----------------------|----------|-----------------------------------------------------------------------------------------------------------| -|`ST7565_DISPLAY_WIDTH` |`128` |The width of the display. | -|`ST7565_DISPLAY_HEIGHT`|`32` |The height of the display. | -|`ST7565_MATRIX_SIZE` |`512` |The local buffer size to allocate.
`(ST7565_DISPLAY_HEIGHT / 8 * ST7565_DISPLAY_WIDTH)`. | -|`ST7565_BLOCK_TYPE` |`uint16_t`|The unsigned integer type to use for dirty rendering. | -|`ST7565_BLOCK_COUNT` |`16` |The number of blocks the display is divided into for dirty rendering.
`(sizeof(ST7565_BLOCK_TYPE) * 8)`.| -|`ST7565_BLOCK_SIZE` |`32` |The size of each block for dirty rendering
`(ST7565_MATRIX_SIZE / ST7565_BLOCK_COUNT)`. | - -## API - -```c -// Rotation enum values are flags -typedef enum { - DISPLAY_ROTATION_0, - DISPLAY_ROTATION_180 -} display_rotation_t; - -// Initialize the display, rotating the rendered output based on the define passed in. -// Returns true if the was initialized successfully -bool st7565_init(display_rotation_t rotation); - -// Called at the start of st7565_init, weak function overridable by the user -// rotation - the value passed into st7565_init -// Return new display_rotation_t if you want to override default rotation -display_rotation_t st7565_init_user(display_rotation_t rotation); - -// Clears the display buffer, resets cursor position to 0, and sets the buffer to dirty for rendering -void st7565_clear(void); - -// Renders the dirty chunks of the buffer to display -void st7565_render(void); - -// Moves cursor to character position indicated by column and line, wraps if out of bounds -// Max column denoted by 'st7565_max_chars()' and max lines by 'st7565_max_lines()' functions -void st7565_set_cursor(uint8_t col, uint8_t line); - -// Advances the cursor to the next page, writing ' ' if true -// Wraps to the begining when out of bounds -void st7565_advance_page(bool clearPageRemainder); - -// Moves the cursor forward 1 character length -// Advance page if there is not enough room for the next character -// Wraps to the begining when out of bounds -void st7565_advance_char(void); - -// Writes a single character to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Main handler that writes character data to the display buffer -void st7565_write_char(const char data, bool invert); - -// Writes a string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -void st7565_write(const char *data, bool invert); - -// Writes a string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Advances the cursor to the next page, wiring ' ' to the remainder of the current page -void st7565_write_ln(const char *data, bool invert); - -// Pans the buffer to the right (or left by passing true) by moving contents of the buffer -// Useful for moving the screen in preparation for new drawing -void st7565_pan(bool left); - -// Returns a pointer to the requested start index in the buffer plus remaining -// buffer length as struct -display_buffer_reader_t st7565_read_raw(uint16_t start_index); - -// Writes a string to the buffer at current cursor position -void st7565_write_raw(const char *data, uint16_t size); - -// Writes a single byte into the buffer at the specified index -void st7565_write_raw_byte(const char data, uint16_t index); - -// Sets a specific pixel on or off -// Coordinates start at top-left and go right and down for positive x and y -void st7565_write_pixel(uint8_t x, uint8_t y, bool on); - -// Writes a PROGMEM string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Remapped to call 'void st7565_write(const char *data, bool invert);' on ARM -void st7565_write_P(const char *data, bool invert); - -// Writes a PROGMEM string to the buffer at current cursor position -// Advances the cursor while writing, inverts the pixels if true -// Advances the cursor to the next page, wiring ' ' to the remainder of the current page -// Remapped to call 'void st7565_write_ln(const char *data, bool invert);' on ARM -void st7565_write_ln_P(const char *data, bool invert); - -// Writes a PROGMEM string to the buffer at current cursor position -void st7565_write_raw_P(const char *data, uint16_t size); - -// Can be used to manually turn on the screen if it is off -// Returns true if the screen was on or turns on -bool st7565_on(void); - -// Called when st7565_on() turns on the screen, weak function overridable by the user -// Not called if the screen is already on -void st7565_on_user(void); - -// Can be used to manually turn off the screen if it is on -// Returns true if the screen was off or turns off -bool st7565_off(void); - -// Called when st7565_off() turns off the screen, weak function overridable by the user -// Not called if the screen is already off -void st7565_off_user(void); - -// Returns true if the screen is currently on, false if it is -// not -bool st7565_is_on(void); - -// Basically it's st7565_render, but with timeout management and st7565_task_user calling! -void st7565_task(void); - -// Called at the start of st7565_task, weak function overridable by the user -void st7565_task_user(void); - -// Inverts the display -// Returns true if the screen was or is inverted -bool st7565_invert(bool invert); - -// Returns the maximum number of characters that will fit on a line -uint8_t st7565_max_chars(void); - -// Returns the maximum number of lines that will fit on the display -uint8_t st7565_max_lines(void); -``` diff --git a/docs/feature_stenography.md b/docs/feature_stenography.md deleted file mode 100644 index df4c9c6ad353..000000000000 --- a/docs/feature_stenography.md +++ /dev/null @@ -1,215 +0,0 @@ -# Stenography in QMK :id=stenography-in-qmk - -[Stenography](https://en.wikipedia.org/wiki/Stenotype) is a method of writing most often used by court reports, closed-captioning, and real-time transcription for the deaf. In stenography words are chorded syllable by syllable with a mixture of spelling, phonetic, and shortcut (briefs) strokes. Professional stenographers can reach 200-300 WPM without any of the strain usually found in standard typing and with far fewer errors (>99.9% accuracy). - -The [Open Steno Project](https://www.openstenoproject.org/) has built an open-source program called Plover that provides real-time translation of steno strokes into words and commands. It has an established dictionary and supports - -## Plover with QWERTY Keyboard :id=plover-with-qwerty-keyboard - -Plover can work with any standard QWERTY keyboard, although it is more efficient if the keyboard supports NKRO (n-key rollover) to allow Plover to see all the pressed keys at once. An example keymap for Plover can be found in `planck/keymaps/default`. Switching to the `PLOVER` layer adjusts the position of the keyboard to support the number bar. - -To enable NKRO, add `NKRO_ENABLE = yes` in your `rules.mk` and make sure to press `NK_ON` to turn it on because `NKRO_ENABLE = yes` merely adds the possibility of switching to NKRO mode but it doesn't automatically switch to it. If you want to automatically switch, add `#define FORCE_NKRO` in your `config.h`. - -You may also need to adjust your layout, either in QMK or in Plover, if you have anything other than a standard layout. You may also want to purchase some steno-friendly keycaps to make it easier to hit multiple keys. - -## Plover with Steno Protocol :id=plover-with-steno-protocol - -Plover also understands the language of several steno machines. QMK can speak a couple of these languages: TX Bolt and GeminiPR. An example layout can be found in `planck/keymaps/steno`. - -When QMK speaks to Plover over a steno protocol, Plover will not use the keyboard as input. This means that you can switch back and forth between a standard keyboard and your steno keyboard, or even switch layers from Plover to standard and back without needing to activate/deactivate Plover. - -In this mode, Plover expects to speak with a steno machine over a serial port so QMK will present itself to the operating system as a virtual serial port in addition to a keyboard. - -> Note: Due to hardware limitations, you might not be able to run both a virtual serial port and mouse emulation at the same time. - -!> Serial stenography protocols are not supported on [V-USB keyboards](compatible_microcontrollers#atmel-avr). - -To enable stenography protocols, add the following lines to your `rules.mk`: -```mk -STENO_ENABLE = yes -``` - -### TX Bolt :id=tx-bolt - -TX Bolt communicates the status of 24 keys over a simple protocol in variable-sized (1–4 bytes) packets. - -To select TX Bolt, add the following lines to your `rules.mk`: -```mk -STENO_ENABLE = yes -STENO_PROTOCOL = txbolt -``` - -Each byte of the packet represents a different group of steno keys. Determining the group of a certain byte of the packet is done by checking the first two bits, the remaining bits are set if the corresponding steno key was pressed for the stroke. The last set of keys (as indicated by leading `11`) needs to keep track of less keys than there are bits so one of the bits is constantly 0. - -The start of a new packet can be detected by comparing the group “ID” (the two MSBs) of the current byte to that of the previously received byte. If the group “ID” of the current byte is smaller or equal to that of the previous byte, it means that the current byte is the beginning of a new packet. - -The format of TX Bolt packets is shown below. -``` -00HWPKTS 01UE*OAR 10GLBPRF 110#ZDST -``` - -Examples of steno strokes and the associated packet: -- `EUBG` = `01110000 10101000` -- `WAZ` = `00010000 01000010 11001000` -- `PHAPBGS` = `00101000 01000010 10101100 11000010` - -### GeminiPR :id=geminipr - -GeminiPR encodes 42 keys into a 6-byte packet. While TX Bolt contains everything that is necessary for standard stenography, GeminiPR opens up many more options, including differentiating between top and bottom `S-`, and supporting non-English theories. - -To select GeminiPR, add the following lines to your `rules.mk`: -```mk -STENO_ENABLE = yes -STENO_PROTOCOL = geminipr -``` - -All packets in the GeminiPR protocol consist of exactly six bytes, used as bit-arrays for different groups of keys. The beginning of a packet is indicated by setting the most significant bit (MSB) to 1 while setting the MSB of the remaining five bytes to 0. - -The format of GeminiPR packets is shown below. -``` -1 Fn #1 #2 #3 #4 #5 #6 -0 S1- S2- T- K- P- W- H- -0 R- A- O- *1 *2 res1 res2 -0 pwr *3 *4 -E -U -F -R -0 -P -B -L -G -T -S -D -0 #7 #8 #9 #A #B #C -Z -``` - -Examples of steno strokes and the associated packet: -- `EUBG` = `10000000 00000000 00000000 00001100 00101000 00000000` -- `WAZ` = `10000000 00000010 00100000 00000000 00000000 00000001` -- `PHAPBGS` = `10000000 00000101 00100000 00000000 01101010 00000000` - -### Switching protocols on the fly :id=switching-protocols-on-the-fly - -If you wish to switch the serial protocol used to transfer the steno chords without having to recompile your keyboard firmware every time, you can press the `QK_STENO_BOLT` and `QK_STENO_GEMINI` keycodes in order to switch protocols on the fly. - -To enable these special keycodes, add the following lines to your `rules.mk`: -```mk -STENO_ENABLE = yes -STENO_PROTOCOL = all -``` - -If you want to switch protocols programatically, as part of a custom macro for example, don't use `tap_code(QK_STENO_*)`, as `tap_code` only supports [basic keycodes](keycodes_basic). Instead, you should use `steno_set_mode(STENO_MODE_*)`, whose valid arguments are `STENO_MODE_BOLT` and `STENO_MODE_GEMINI`. - -The default protocol is Gemini PR but the last protocol used is stored in non-volatile memory so QMK will remember your choice between reboots of your keyboard — assuming that your keyboard features (emulated) EEPROM. - -Naturally, this option takes the most amount of firmware space as it needs to compile the code for all the available stenography protocols. In most cases, compiling a single stenography protocol is sufficient. - -The default value for `STENO_PROTOCOL` is `all`. - -## Configuring QMK for Steno :id=configuring-qmk-for-steno - -After enabling stenography and optionally selecting a protocol, you may also need disable mouse keys, extra keys, or another USB endpoint to prevent conflicts. The builtin USB stack for some processors only supports a certain number of USB endpoints and the virtual serial port needed for steno fills 3 of them. - -!> If you had *explicitly* set `VIRSTER_ENABLE = no`, none of the serial stenography protocols (GeminiPR, TX Bolt) will work properly. You are expected to either set it to `yes`, remove the line from your `rules.mk` or send the steno chords yourself in an alternative way using the [provided interceptable hooks](#interfacing-with-the-code). - -In your keymap, create a new layer for Plover, that you can fill in with the [steno keycodes](#keycode-reference) (you will need to include `keymap_steno.h`, see `planck/keymaps/steno/keymap.c` for an example). Remember to create a key to switch to the layer as well as a key for exiting the layer. - -Once you have your keyboard flashed, launch Plover. Click the 'Configure...' button. In the 'Machine' tab, select the Stenotype Machine that corresponds to your desired protocol. Click the 'Configure...' button on this tab and enter the serial port or click 'Scan'. Baud rate is fine at 9600 (although you should be able to set as high as 115200 with no issues). Use the default settings for everything else (Data Bits: 8, Stop Bits: 1, Parity: N, no flow control). - -To test your keymap, you can chord keys on your keyboard and either look at the output of the 'paper tape' (Tools > Paper Tape) or that of the 'layout display' (Tools > Layout Display). If your strokes correctly show up, you are now ready to steno! - -## Learning Stenography :id=learning-stenography - -* [Learn Plover!](https://sites.google.com/site/learnplover/) -* [Steno Jig](https://joshuagrams.github.io/steno-jig/) -* More resources at the Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki - -## Interfacing with the code :id=interfacing-with-the-code - -The steno code has three interceptable hooks. If you define these functions, they will be called at certain points in processing; if they return true, processing continues, otherwise it's assumed you handled things. - -```c -bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE]); -``` - -This function is called when a chord is about to be sent. Mode will be one of `STENO_MODE_BOLT` or `STENO_MODE_GEMINI`. This represents the actual chord that would be sent via whichever protocol. You can modify the chord provided to alter what gets sent. Remember to return true if you want the regular sending process to happen. - -```c -bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } -``` - -This function is called when a keypress has come in, before it is processed. The keycode should be one of `QK_STENO_BOLT`, `QK_STENO_GEMINI`, or one of the `STN_*` key values. - -```c -bool post_process_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE], int8_t n_pressed_keys); -``` - -This function is called after a key has been processed, but before any decision about whether or not to send a chord. This is where to put hooks for things like, say, live displays of steno chords or keys. - -If `record->event.pressed` is false, and `n_pressed_keys` is 0 or 1, the chord will be sent shortly, but has not yet been sent. This relieves you of the need of keeping track of where a packet ends and another begins. - -The `chord` argument contains the packet of the current chord as specified by the protocol in use. This is *NOT* simply a list of chorded steno keys of the form `[STN_E, STN_U, STN_BR, STN_GR]`. Refer to the appropriate protocol section of this document to learn more about the format of the packets in your steno protocol/mode of choice. - -The `n_pressed_keys` argument is the number of physical keys actually being held down. -This is not always equal to the number of bits set to 1 (aka the [Hamming weight](https://en.wikipedia.org/wiki/Hamming_weight)) in `chord` because it is possible to simultaneously press down four keys, then release three of those four keys and then press yet another key while the fourth finger is still holding down its key. -At the end of this scenario given as an example, `chord` would have five bits set to 1 but -`n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down. - -## Keycode Reference :id=keycode-reference - -You must include `keymap_steno.h` to your `keymap.c` with `#include "keymap_steno.h"` before you can use these keycodes - -> Note: TX Bolt does not support the full set of keys. The TX Bolt implementation in QMK will map the GeminiPR keys to the nearest TX Bolt key so that one key map will work for both. - -|GeminiPR|TX Bolt|Steno Key| -|--------|-------|-----------| -|`STN_N1`|`STN_NUM`|Number bar #1| -|`STN_N2`|`STN_NUM`|Number bar #2| -|`STN_N3`|`STN_NUM`|Number bar #3| -|`STN_N4`|`STN_NUM`|Number bar #4| -|`STN_N5`|`STN_NUM`|Number bar #5| -|`STN_N6`|`STN_NUM`|Number bar #6| -|`STN_N7`|`STN_NUM`|Number bar #7| -|`STN_N8`|`STN_NUM`|Number bar #8| -|`STN_N9`|`STN_NUM`|Number bar #9| -|`STN_NA`|`STN_NUM`|Number bar #A| -|`STN_NB`|`STN_NUM`|Number bar #B| -|`STN_NC`|`STN_NUM`|Number bar #C| -|`STN_S1`|`STN_SL`| `S-` upper| -|`STN_S2`|`STN_SL`| `S-` lower| -|`STN_TL`|`STN_TL`| `T-`| -|`STN_KL`|`STN_KL`| `K-`| -|`STN_PL`|`STN_PL`| `P-`| -|`STN_WL`|`STN_WL`| `W-`| -|`STN_HL`|`STN_HL`| `H-`| -|`STN_RL`|`STN_RL`| `R-`| -|`STN_A`|`STN_A`| `A` vowel| -|`STN_O`|`STN_O`| `O` vowel| -|`STN_ST1`|`STN_STR`| `*` upper-left | -|`STN_ST2`|`STN_STR`| `*` lower-left| -|`STN_ST3`|`STN_STR`| `*` upper-right| -|`STN_ST4`|`STN_STR`| `*` lower-right| -|`STN_E`|`STN_E`| `E` vowel| -|`STN_U`|`STN_U`| `U` vowel| -|`STN_FR`|`STN_FR`| `-F`| -|`STN_RR`|`STN_RR`| `-R`| -|`STN_PR`|`STN_PR`| `-P`| -|`STN_BR`|`STN_BR`| `-B`| -|`STN_LR`|`STN_LR`| `-L`| -|`STN_GR`|`STN_GR`| `-G`| -|`STN_TR`|`STN_TR`| `-T`| -|`STN_SR`|`STN_SR`| `-S`| -|`STN_DR`|`STN_DR`| `-D`| -|`STN_ZR`|`STN_ZR`| `-Z`| -|`STN_FN`|| (Function)| -|`STN_RES1`||(Reset 1)| -|`STN_RES2`||(Reset 2)| -|`STN_PWR`||(Power)| - -If you do not want to hit two keys with one finger combined keycodes can be used. These are also defined in `keymap_steno.h`, and causes both keys to be reported as pressed or released. To use these keycodes define `STENO_COMBINEDMAP` in your `config.h` file. - -|Combined key | Key1 | Key 2 | -|---------------|--------|----------| -|STN_S3 | STN_S1 | STN_S2 | -|STN_TKL | STN_TL | STN_KL | -|STN_PWL | STN_PL | STN_WL | -|STN_HRL | STN_HL | STN_RL | -|STN_FRR | STN_FR | STN_RR | -|STN_PBR | STN_PR | STN_BR | -|STN_LGR | STN_LR | STN_GR | -|STN_TSR | STN_TR | STN_SR | -|STN_DZR | STN_DR | STN_ZR | -|STN_AO | STN_A | STN_O | -|STN_EU | STN_E | STN_U | diff --git a/docs/feature_swap_hands.md b/docs/feature_swap_hands.md deleted file mode 100644 index e9c1d4b7ba88..000000000000 --- a/docs/feature_swap_hands.md +++ /dev/null @@ -1,57 +0,0 @@ -# Swap-Hands Action - -The swap-hands action allows support for one-handed typing without requiring a separate layer. Set `SWAP_HANDS_ENABLE` in the Makefile and define a `hand_swap_config` entry in your keymap. Now whenever the `ACTION_SWAP_HANDS` command key is pressed the keyboard is mirrored. For instance, to type "Hello, World" on QWERTY you would type `^Ge^s^s^w^c W^wr^sd` - -## Configuration - -The configuration table is a simple 2-dimensional array to map from column/row to new column/row. Example `hand_swap_config` for Planck: - -```c -const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { - {{11, 0}, {10, 0}, {9, 0}, {8, 0}, {7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, - {{11, 1}, {10, 1}, {9, 1}, {8, 1}, {7, 1}, {6, 1}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, - {{11, 2}, {10, 2}, {9, 2}, {8, 2}, {7, 2}, {6, 2}, {5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, - {{11, 3}, {10, 3}, {9, 3}, {8, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, -}; -``` - -Note that the array indices are reversed same as the matrix and the values are of type `keypos_t` which is `{col, row}` and all values are zero-based. In the example above, `hand_swap_config[2][4]` (third row, fifth column) would return `{7, 2}` (third row, eighth column). Yes, this is confusing. - -## Swap Keycodes - -|Key |Aliases |Description | -|-----------------------------|---------|----------------------------------------------------| -|`SH_T(kc)` | |Momentary swap when held, `kc` when tapped | -|`QK_SWAP_HANDS_ON` |`SH_ON` |Turn on hand swap | -|`QK_SWAP_HANDS_OFF` |`SH_OFF` |Turn off hand swap | -|`QK_SWAP_HANDS_MOMENTARY_ON` |`SH_MON` |Turn on hand swap while held | -|`QK_SWAP_HANDS_MOMENTARY_OFF`|`SH_MOFF`|Turn off hand swap while held | -|`QK_SWAP_HANDS_TOGGLE` |`SH_TOGG`|Toggle hand swap | -|`QK_SWAP_HANDS_TAP_TOGGLE` |`SH_TT` |Momentary swap when held, toggle when tapped | -|`QK_SWAP_HANDS_ONE_SHOT` |`SH_OS` |Turn on hand swap while held or until next key press| - -`SH_TT` swap-hands tap-toggle key is similar to [layer tap-toggle](feature_layers.md?id=switching-and-toggling-layers). Tapping repeatedly (5 taps by default) will toggle swap-hands on or off, like `SH_TOGG`. Tap-toggle count can be changed by defining a value for `TAPPING_TOGGLE`. - -## Encoder Mapping - -When using an encoder mapping, it's also able to handle swapping encoders between sides, too. - -Encoder indexes are defined as left-to-right, and the extent of the array needs to match the number of encoders on the keyboard. - -As an example, if a split keyboard has a single encoder per side, you can swap the order by using the following code in your keymap: -```c -#if defined(SWAP_HANDS_ENABLE) && defined(ENCODER_MAP_ENABLE) -const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS] = { 1, 0 }; -#endif -``` - -### Functions :id=functions - -User callback functions to manipulate Swap-Hands: - -| Function | Description | -|-----------------------|---------------------------------------------| -| `swap_hands_on()` | Turns Swap-Hands on. | -| `swap_hands_off()` | Turns Swap-Hands off. | -| `swap_hands_toggle()` | Toggles Swap-Hands. | -| `is_swap_hands_on()` | Returns true if Swap-Hands is currently on. | diff --git a/docs/feature_tap_dance.md b/docs/feature_tap_dance.md deleted file mode 100644 index b7d8a5528fb8..000000000000 --- a/docs/feature_tap_dance.md +++ /dev/null @@ -1,563 +0,0 @@ -# Tap Dance: A Single Key Can Do 3, 5, or 100 Different Things - -## Introduction :id=introduction - -Hit the semicolon key once, send a semicolon. Hit it twice, rapidly -- send a colon. Hit it three times, and your keyboard's LEDs do a wild dance. That's just one example of what Tap Dance can do. It's one of the nicest community-contributed features in the firmware, conceived and created by [algernon](https://github.com/algernon) in [#451](https://github.com/qmk/qmk_firmware/pull/451). Here's how algernon describes the feature: - -With this feature one can specify keys that behave differently, based on the amount of times they have been tapped, and when interrupted, they get handled before the interrupter. - -## How to Use Tap Dance :id=how-to-use - -First, you will need `TAP_DANCE_ENABLE = yes` in your `rules.mk`, because the feature is disabled by default. This adds a little less than 1k to the firmware size. - -Optionally, you might want to set a custom `TAPPING_TERM` time by adding something like this in your `config.h` file: - -```c -#define TAPPING_TERM 175 -#define TAPPING_TERM_PER_KEY -``` - -The `TAPPING_TERM` time is the maximum time allowed between taps of your Tap Dance key, and is measured in milliseconds. For example, if you used the above `#define` statement and set up a Tap Dance key that sends `Space` on single-tap and `Enter` on double-tap, then this key will send `ENT` only if you tap this key twice in less than 175ms. If you tap the key, wait more than 175ms, and tap the key again you'll end up sending `SPC SPC` instead. The `TAPPING_TERM_PER_KEY` definition is only needed if you control the tapping term through a [custom `get_tapping_term` function](tap_hold.md#tapping_term), which may be needed because `TAPPING_TERM` affects not just tap-dance keys. - -Next, you will want to define some tap-dance keys, which is easiest to do with the `TD()` macro. That macro takes a number which will later be used as an index into the `tap_dance_actions` array and turns it into a tap-dance keycode. - -After this, you'll want to use the `tap_dance_actions` array to specify what actions shall be taken when a tap-dance key is in action. Currently, there are five possible options: - -* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: Sends the `kc1` keycode when tapped once, `kc2` otherwise. When the key is held, the appropriate keycode is registered: `kc1` when pressed and held, `kc2` when tapped once, then pressed and held. -* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: Sends the `kc` keycode when tapped once, or moves to `layer`. (this functions like the `TO` layer keycode). -* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: Sends the `kc` keycode when tapped once, or toggles the state of `layer`. (this functions like the `TG` layer keycode). -* `ACTION_TAP_DANCE_FN(fn)`: Calls the specified function - defined in the user keymap - with the final tap count of the tap dance action. -* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: Calls the first specified function - defined in the user keymap - on every tap, the second function when the dance action finishes (like the previous option), and the last function when the tap dance action resets. - - -The first option is enough for a lot of cases, that just want dual roles. For example, `ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` will result in `Space` being sent on single-tap, `Enter` otherwise. - -!> Keep in mind that only [basic keycodes](keycodes_basic.md) are supported here. Custom keycodes are not supported. - -Similar to the first option, the second and third option are good for simple layer-switching cases. - -For more complicated cases, like blink the LEDs, fiddle with the backlighting, and so on, use the fourth or fifth option. Examples of each are listed below. - -## Implementation Details :id=implementation - -Well, that's the bulk of it! You should now be able to work through the examples below, and to develop your own Tap Dance functionality. But if you want a deeper understanding of what's going on behind the scenes, then read on for the explanation of how it all works! - -Let's go over the three functions mentioned in `ACTION_TAP_DANCE_FN_ADVANCED` in a little more detail. They all receive the same two arguments: a pointer to a structure that holds all dance related state information, and a pointer to a use case specific state variable. The three functions differ in when they are called. The first, `on_each_tap_fn()`, is called every time the tap dance key is *pressed*. Before it is called, the counter is incremented and the timer is reset. The second function, `on_dance_finished_fn()`, is called when the tap dance is interrupted or ends because `TAPPING_TERM` milliseconds have passed since the last tap. When the `finished` field of the dance state structure is set to `true`, the `on_dance_finished_fn()` is skipped. After `on_dance_finished_fn()` was called or would have been called, but no sooner than when the tap dance key is *released*, `on_dance_reset_fn()` is called. It is possible to end a tap dance immediately, skipping `on_dance_finished_fn()`, but not `on_dance_reset_fn`, by calling `reset_tap_dance(state)`. - -To accomplish this logic, the tap dance mechanics use three entry points. The main entry point is `process_tap_dance()`, called from `process_record_quantum()` *after* `process_record_kb()` and `process_record_user()`. This function is responsible for calling `on_each_tap_fn()` and `on_dance_reset_fn()`. In order to handle interruptions of a tap dance, another entry point, `preprocess_tap_dance()` is run right at the beginning of `process_record_quantum()`. This function checks whether the key pressed is a tap-dance key. If it is not, and a tap-dance was in action, we handle that first, and enqueue the newly pressed key. If it is a tap-dance key, then we check if it is the same as the already active one (if there's one active, that is). If it is not, we fire off the old one first, then register the new one. Finally, `tap_dance_task()` periodically checks whether `TAPPING_TERM` has passed since the last key press and finishes a tap dance if that is the case. - -This means that you have `TAPPING_TERM` time to tap the key again; you do not have to input all the taps within a single `TAPPING_TERM` timeframe. This allows for longer tap counts, with minimal impact on responsiveness. - -## Examples :id=examples - -### Simple Example: Send `ESC` on Single Tap, `CAPS_LOCK` on Double Tap :id=simple-example - -Here's a simple example for a single definition: - -1. In your `rules.mk`, add `TAP_DANCE_ENABLE = yes` -2. In your `keymap.c` file, define the variables and definitions, then add to your keymap: - -```c -// Tap Dance declarations -enum { - TD_ESC_CAPS, -}; - -// Tap Dance definitions -tap_dance_action_t tap_dance_actions[] = { - // Tap once for Escape, twice for Caps Lock - [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), -}; - -// Add tap dance item to your keymap in place of a keycode -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - // ... - TD(TD_ESC_CAPS) - // ... -}; -``` - -### Complex Examples :id=complex-examples - -This section details several complex tap dance examples. -All the enums used in the examples are declared like this: - -```c -// Enums defined for all examples: -enum { - TD_ESC_CAPS, - CT_EGG, - CT_FLSH, - CT_CLN, - X_CTL, -}; -``` - -#### Example 1: Send "Safety Dance!" After 100 Taps :id=example-1 - -```c -void dance_egg(tap_dance_state_t *state, void *user_data) { - if (state->count >= 100) { - SEND_STRING("Safety dance!"); - reset_tap_dance(state); - } -} - -tap_dance_action_t tap_dance_actions[] = { - [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), -}; -``` - -#### Example 2: Turn LED Lights On Then Off, One at a Time :id=example-2 - -```c -// On each tap, light up one LED, from right to left -// On the fourth tap, turn them off from right to left -void dance_flsh_each(tap_dance_state_t *state, void *user_data) { - switch (state->count) { - case 1: - ergodox_right_led_3_on(); - break; - case 2: - ergodox_right_led_2_on(); - break; - case 3: - ergodox_right_led_1_on(); - break; - case 4: - ergodox_right_led_3_off(); - wait_ms(50); - ergodox_right_led_2_off(); - wait_ms(50); - ergodox_right_led_1_off(); - } -} - -// On the fourth tap, set the keyboard on flash state -void dance_flsh_finished(tap_dance_state_t *state, void *user_data) { - if (state->count >= 4) { - reset_keyboard(); - } -} - -// If the flash state didn't happen, then turn off LEDs, left to right -void dance_flsh_reset(tap_dance_state_t *state, void *user_data) { - ergodox_right_led_1_off(); - wait_ms(50); - ergodox_right_led_2_off(); - wait_ms(50); - ergodox_right_led_3_off(); -} - -// All tap dances now put together. Example 2 is "CT_FLSH" -tap_dance_action_t tap_dance_actions[] = { - [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), - [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), - [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset) -}; -``` - -#### Example 3: Send `:` on Tap, `;` on Hold :id=example-3 - -With a little effort, powerful tap-hold configurations can be implemented as tap dances. To emit taps as early as possible, we need to act on releases of the tap dance key. There is no callback for this in the tap dance framework, so we use `process_record_user()`. - -```c -typedef struct { - uint16_t tap; - uint16_t hold; - uint16_t held; -} tap_dance_tap_hold_t; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - tap_dance_action_t *action; - - switch (keycode) { - case TD(CT_CLN): // list all tap dance keycodes with tap-hold configurations - action = &tap_dance_actions[TD_INDEX(keycode)]; - if (!record->event.pressed && action->state.count && !action->state.finished) { - tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; - tap_code16(tap_hold->tap); - } - } - return true; -} - -void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) { - tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data; - - if (state->pressed) { - if (state->count == 1 -#ifndef PERMISSIVE_HOLD - && !state->interrupted -#endif - ) { - register_code16(tap_hold->hold); - tap_hold->held = tap_hold->hold; - } else { - register_code16(tap_hold->tap); - tap_hold->held = tap_hold->tap; - } - } -} - -void tap_dance_tap_hold_reset(tap_dance_state_t *state, void *user_data) { - tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data; - - if (tap_hold->held) { - unregister_code16(tap_hold->held); - tap_hold->held = 0; - } -} - -#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \ - { .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), } - -tap_dance_action_t tap_dance_actions[] = { - [CT_CLN] = ACTION_TAP_DANCE_TAP_HOLD(KC_COLN, KC_SCLN), -}; -``` - -#### Example 4: 'Quad Function Tap-Dance' :id=example-4 - -By [DanielGGordon](https://github.com/danielggordon) - -Allow one key to have 4 (or more) functions, depending on number of presses, and if the key is held or tapped. -Below is a specific example: -* Tap = Send `x` -* Hold = Send `Control` -* Double Tap = Send `Escape` -* Double Tap and Hold = Send `Alt` - -You will need a few things that can be used for 'Quad Function Tap-Dance'. - -You'll need to add these to the top of your `keymap.c` file, before your keymap. - -```c -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_TAP, - TD_DOUBLE_HOLD, - TD_DOUBLE_SINGLE_TAP, // Send two single taps - TD_TRIPLE_TAP, - TD_TRIPLE_HOLD -} td_state_t; - -typedef struct { - bool is_press_action; - td_state_t state; -} td_tap_t; - -// Tap dance enums -enum { - X_CTL, - SOME_OTHER_DANCE -}; - -td_state_t cur_dance(tap_dance_state_t *state); - -// For the x tap dance. Put it here so it can be used in any keymap -void x_finished(tap_dance_state_t *state, void *user_data); -void x_reset(tap_dance_state_t *state, void *user_data); -``` - -Now, at the bottom of your `keymap.c` file, you'll need to add the following: - -```c -/* Return an integer that corresponds to what kind of tap dance should be executed. - * - * How to figure out tap dance state: interrupted and pressed. - * - * Interrupted: If the state of a dance is "interrupted", that means that another key has been hit - * under the tapping term. This is typically indicitive that you are trying to "tap" the key. - * - * Pressed: Whether or not the key is still being pressed. If this value is true, that means the tapping term - * has ended, but the key is still being pressed down. This generally means the key is being "held". - * - * One thing that is currenlty not possible with qmk software in regards to tap dance is to mimic the "permissive hold" - * feature. In general, advanced tap dances do not work well if they are used with commonly typed letters. - * For example "A". Tap dances are best used on non-letter keys that are not hit while typing letters. - * - * Good places to put an advanced tap dance: - * z,q,x,j,k,v,b, any function key, home/end, comma, semi-colon - * - * Criteria for "good placement" of a tap dance key: - * Not a key that is hit frequently in a sentence - * Not a key that is used frequently to double tap, for example 'tab' is often double tapped in a terminal, or - * in a web form. So 'tab' would be a poor choice for a tap dance. - * Letters used in common words as a double. For example 'p' in 'pepper'. If a tap dance function existed on the - * letter 'p', the word 'pepper' would be quite frustating to type. - * - * For the third point, there does exist the 'TD_DOUBLE_SINGLE_TAP', however this is not fully tested - * - */ -td_state_t cur_dance(tap_dance_state_t *state) { - if (state->count == 1) { - if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; - // Key has not been interrupted, but the key is still held. Means you want to send a 'HOLD'. - else return TD_SINGLE_HOLD; - } else if (state->count == 2) { - // TD_DOUBLE_SINGLE_TAP is to distinguish between typing "pepper", and actually wanting a double tap - // action when hitting 'pp'. Suggested use case for this return value is when you want to send two - // keystrokes of the key, and not the 'double tap' action/macro. - if (state->interrupted) return TD_DOUBLE_SINGLE_TAP; - else if (state->pressed) return TD_DOUBLE_HOLD; - else return TD_DOUBLE_TAP; - } - - // Assumes no one is trying to type the same letter three times (at least not quickly). - // If your tap dance key is 'KC_W', and you want to type "www." quickly - then you will need to add - // an exception here to return a 'TD_TRIPLE_SINGLE_TAP', and define that enum just like 'TD_DOUBLE_SINGLE_TAP' - if (state->count == 3) { - if (state->interrupted || !state->pressed) return TD_TRIPLE_TAP; - else return TD_TRIPLE_HOLD; - } else return TD_UNKNOWN; -} - -// Create an instance of 'td_tap_t' for the 'x' tap dance. -static td_tap_t xtap_state = { - .is_press_action = true, - .state = TD_NONE -}; - -void x_finished(tap_dance_state_t *state, void *user_data) { - xtap_state.state = cur_dance(state); - switch (xtap_state.state) { - case TD_SINGLE_TAP: register_code(KC_X); break; - case TD_SINGLE_HOLD: register_code(KC_LCTL); break; - case TD_DOUBLE_TAP: register_code(KC_ESC); break; - case TD_DOUBLE_HOLD: register_code(KC_LALT); break; - // Last case is for fast typing. Assuming your key is `f`: - // For example, when typing the word `buffer`, and you want to make sure that you send `ff` and not `Esc`. - // In order to type `ff` when typing fast, the next character will have to be hit within the `TAPPING_TERM`, which by default is 200ms. - case TD_DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X); break; - default: break; - } -} - -void x_reset(tap_dance_state_t *state, void *user_data) { - switch (xtap_state.state) { - case TD_SINGLE_TAP: unregister_code(KC_X); break; - case TD_SINGLE_HOLD: unregister_code(KC_LCTL); break; - case TD_DOUBLE_TAP: unregister_code(KC_ESC); break; - case TD_DOUBLE_HOLD: unregister_code(KC_LALT); break; - case TD_DOUBLE_SINGLE_TAP: unregister_code(KC_X); break; - default: break; - } - xtap_state.state = TD_NONE; -} - -tap_dance_action_t tap_dance_actions[] = { - [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset) -}; -``` - -And then simply use `TD(X_CTL)` anywhere in your keymap. - -> In this configuration "hold" takes place **after** tap dance timeout. To achieve instant hold, remove `state->interrupted` checks in conditions. As a result you may use comfortable longer tapping periods to have more time for taps and not to wait too long for holds (try starting with doubled `TAPPING_TERM`). - -#### Example 5: Using tap dance for advanced mod-tap and layer-tap keys :id=example-5 - -Tap dance can be used to emulate `MT()` and `LT()` behavior when the tapped code is not a basic keycode. This is useful to send tapped keycodes that normally require `Shift`, such as parentheses or curly braces—or other modified keycodes, such as `Control + X`. - -Below your layers and custom keycodes, add the following: - -```c -// Tap Dance keycodes -enum td_keycodes { - ALT_LP // Our example key: `LALT` when held, `(` when tapped. Add additional keycodes for each tapdance. -}; - -// Define a type containing as many tapdance states as you need -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_SINGLE_TAP -} td_state_t; - -// Create a global instance of the tapdance state type -static td_state_t td_state; - -// Declare your tapdance functions: - -// Function to determine the current tapdance state -td_state_t cur_dance(tap_dance_state_t *state); - -// `finished` and `reset` functions for each tapdance keycode -void altlp_finished(tap_dance_state_t *state, void *user_data); -void altlp_reset(tap_dance_state_t *state, void *user_data); -``` - -Below your `LAYOUT`, define each of the tapdance functions: - -```c -// Determine the tapdance state to return -td_state_t cur_dance(tap_dance_state_t *state) { - if (state->count == 1) { - if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; - else return TD_SINGLE_HOLD; - } - - if (state->count == 2) return TD_DOUBLE_SINGLE_TAP; - else return TD_UNKNOWN; // Any number higher than the maximum state value you return above -} - -// Handle the possible states for each tapdance keycode you define: - -void altlp_finished(tap_dance_state_t *state, void *user_data) { - td_state = cur_dance(state); - switch (td_state) { - case TD_SINGLE_TAP: - register_code16(KC_LPRN); - break; - case TD_SINGLE_HOLD: - register_mods(MOD_BIT(KC_LALT)); // For a layer-tap key, use `layer_on(_MY_LAYER)` here - break; - case TD_DOUBLE_SINGLE_TAP: // Allow nesting of 2 parens `((` within tapping term - tap_code16(KC_LPRN); - register_code16(KC_LPRN); - break; - default: - break; - } -} - -void altlp_reset(tap_dance_state_t *state, void *user_data) { - switch (td_state) { - case TD_SINGLE_TAP: - unregister_code16(KC_LPRN); - break; - case TD_SINGLE_HOLD: - unregister_mods(MOD_BIT(KC_LALT)); // For a layer-tap key, use `layer_off(_MY_LAYER)` here - break; - case TD_DOUBLE_SINGLE_TAP: - unregister_code16(KC_LPRN); - break; - default: - break; - } -} - -// Define `ACTION_TAP_DANCE_FN_ADVANCED()` for each tapdance keycode, passing in `finished` and `reset` functions -tap_dance_action_t tap_dance_actions[] = { - [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) -}; -``` - -Wrap each tapdance keycode in `TD()` when including it in your keymap, e.g. `TD(ALT_LP)`. - -#### Example 6: Using tap dance for momentary-layer-switch and layer-toggle keys :id=example-6 - -Tap Dance can be used to mimic MO(layer) and TG(layer) functionality. For this example, we will set up a key to function as `KC_QUOT` on single-tap, as `MO(_MY_LAYER)` on single-hold, and `TG(_MY_LAYER)` on double-tap. - -The first step is to include the following code towards the beginning of your `keymap.c`: - -```c -// Define a type for as many tap dance states as you need -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_TAP -} td_state_t; - -typedef struct { - bool is_press_action; - td_state_t state; -} td_tap_t; - -enum { - QUOT_LAYR, // Our custom tap dance key; add any other tap dance keys to this enum -}; - -// Declare the functions to be used with your tap dance key(s) - -// Function associated with all tap dances -td_state_t cur_dance(tap_dance_state_t *state); - -// Functions associated with individual tap dances -void ql_finished(tap_dance_state_t *state, void *user_data); -void ql_reset(tap_dance_state_t *state, void *user_data); -``` - -Towards the bottom of your `keymap.c`, include the following code: - -```c -// Determine the current tap dance state -td_state_t cur_dance(tap_dance_state_t *state) { - if (state->count == 1) { - if (!state->pressed) return TD_SINGLE_TAP; - else return TD_SINGLE_HOLD; - } else if (state->count == 2) return TD_DOUBLE_TAP; - else return TD_UNKNOWN; -} - -// Initialize tap structure associated with example tap dance key -static td_tap_t ql_tap_state = { - .is_press_action = true, - .state = TD_NONE -}; - -// Functions that control what our tap dance key does -void ql_finished(tap_dance_state_t *state, void *user_data) { - ql_tap_state.state = cur_dance(state); - switch (ql_tap_state.state) { - case TD_SINGLE_TAP: - tap_code(KC_QUOT); - break; - case TD_SINGLE_HOLD: - layer_on(_MY_LAYER); - break; - case TD_DOUBLE_TAP: - // Check to see if the layer is already set - if (layer_state_is(_MY_LAYER)) { - // If already set, then switch it off - layer_off(_MY_LAYER); - } else { - // If not already set, then switch the layer on - layer_on(_MY_LAYER); - } - break; - default: - break; - } -} - -void ql_reset(tap_dance_state_t *state, void *user_data) { - // If the key was held down and now is released then switch off the layer - if (ql_tap_state.state == TD_SINGLE_HOLD) { - layer_off(_MY_LAYER); - } - ql_tap_state.state = TD_NONE; -} - -// Associate our tap dance key with its functionality -tap_dance_action_t tap_dance_actions[] = { - [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, ql_finished, ql_reset) -}; - -// Set a long-ish tapping term for tap-dance keys -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - return 275; - default: - return TAPPING_TERM; - } -} -``` - -The above code is similar to that used in previous examples. The one point to note is that we need to be able to check which layers are active at any time so we can toggle them if needed. To do this we use the `layer_state_is(layer)` function which returns `true` if the given `layer` is active. - -The use of `cur_dance()` and `ql_tap_state` mirrors the above examples. - -The `case: TD_SINGLE_TAP` in `ql_finished` is similar to the above examples. The `TD_SINGLE_HOLD` case works in conjunction with `ql_reset()` to switch to `_MY_LAYER` while the tap dance key is held, and to switch away from `_MY_LAYER` when the key is released. This mirrors the use of `MO(_MY_LAYER)`. The `TD_DOUBLE_TAP` case works by checking whether `_MY_LAYER` is the active layer, and toggling it on or off accordingly. This mirrors the use of `TG(_MY_LAYER)`. - -`tap_dance_actions[]` works similar to the above examples. Note that, additionally, I set a longer tapping term for the tap dance keys. This is because I like my `TAPPING_TERM` to be short (\~175ms) for my non-tap-dance keys but find that this is too quick for me to reliably complete tap dance actions - thus the increased time of 275ms here. In order for the per-key tapping terms to take effect, `TAPPING_TERM_PER_KEY` must be defined in your `config.h`. - -Finally, to get this tap dance key working, be sure to include `TD(QUOT_LAYR)` in your `keymaps[]`. diff --git a/docs/feature_tri_layer.md b/docs/feature_tri_layer.md deleted file mode 100644 index aa6c87719ca6..000000000000 --- a/docs/feature_tri_layer.md +++ /dev/null @@ -1,48 +0,0 @@ -# Tri Layers :id=tri-layers - -This enables support for the OLKB style "Tri Layer" keycodes. These function similar to the `MO` (momentary) function key, but if both the "Lower" and "Upper" keys are pressed, it activates a third "Adjust" layer. To enable this functionality, add this line to your `rules.mk`: - -```make -TRI_LAYER_ENABLE = yes -``` - -Note that the "upper", "lower" and "adjust" names don't have a particular significance, they are just used to identify and clarify the behavior. Layers are processed from highest numeric value to lowest, however the values are not required to be consecutive. - -For a detailed explanation of how the layer stack works, check out [Keymap Overview](keymap.md#keymap-and-layers). - -## Keycodes :id=keycodes - -| Keycode | Alias | Description | -|----------------------|-----------|---------------------------------------------------------------------------------------------------------| -| `QK_TRI_LAYER_LOWER` | `TL_LOWR` | Momentarily enables the "lower" layer. Enables the "adjust" layer if the "upper" layer is also enabled" | -| `QK_TRI_LAYER_UPPER` | `TL_UPPR` | Momentarily enables the "upper" layer. Enables the "adjust" layer if the "lower" layer is also enabled" | - -## Configuration - -To change the default values for the layers, you can change these defines, in your `config.h` - -| Config name | Default | Description | -|--------------------------|---------|------------------------------------------| -| `TRI_LAYER_LOWER_LAYER` | `1` | Sets the default for the "lower" layer. | -| `TRI_LAYER_UPPER_LAYER` | `2` | Sets the default for the "upper" layer. | -| `TRI_LAYER_ADJUST_LAYER` | `3` | Sets the default for the "adjust" layer. | - -Eg, if you wanted to set the "Adjust" layer to be layer 5, you'd add this to your `config.h`: - -```c -#define TRI_LAYER_ADJUST_LAYER 5 -``` - -## Functions - -| Function name | Description | -|----------------------------------------------|-------------------------------------------------| -| `set_tri_layer_lower_layer(layer)` | Changes the "lower" layer*. | -| `set_tri_layer_upper_layer(layer)` | Changes the "upper" layer*. | -| `set_tri_layer_adjust_layer(layer)` | Changes the "adjust" layer*. | -| `set_tri_layer_layers(lower, upper, adjust)` | Stes the "lower", "upper" and "adjust" layers*. | -| `get_tri_layer_lower_layer()` | Gets the current "lower" layer. | -| `get_tri_layer_upper_layer()` | Gets the current "upper" layer. | -| `get_tri_layer_adjust_layer()` | Gets the current "adjust" layer. | - -!> Note: these settings are not persisent, and will be reset to the default on power loss or power cycling of the controller. diff --git a/docs/feature_unicode.md b/docs/feature_unicode.md index 455596dab5e1..312a0332570e 100644 --- a/docs/feature_unicode.md +++ b/docs/feature_unicode.md @@ -42,7 +42,7 @@ Add the following to your `rules.mk`: UNICODEMAP_ENABLE = yes ``` -Then add `X(i)` keycodes to your keymap, where _i_ is the desired character's index in the mapping table. This can be a numeric value, but it's recommended to keep the indices in an enum and access them by name. +Then add `UM(i)` keycodes to your keymap, where _i_ is the desired character's index in the mapping table. This can be a numeric value, but it's recommended to keep the indices in an enum and access them by name. ```c enum unicode_names { @@ -58,13 +58,13 @@ const uint32_t unicode_map[] PROGMEM = { }; ``` -Then you can use `X(BANG)`, `X(SNEK)` etc. in your keymap. +Then you can use `UM(BANG)`, `UM(SNEK)` etc. in your keymap. #### Lower and Upper Case -Characters often come in lower and upper case pairs, such as å and Å. To make inputting these characters easier, you can use `XP(i, j)` in your keymap, where _i_ and _j_ are the mapping table indices of the lower and upper case character, respectively. If you're holding down Shift or have Caps Lock turned on when you press the key, the second (upper case) character will be inserted; otherwise, the first (lower case) version will appear. +Characters often come in lower and upper case pairs, such as å and Å. To make inputting these characters easier, you can use `UP(i, j)` in your keymap, where _i_ and _j_ are the mapping table indices of the lower and upper case character, respectively. If you're holding down Shift or have Caps Lock turned on when you press the key, the second (upper case) character will be inserted; otherwise, the first (lower case) version will appear. -This is most useful when creating a keymap for an international layout with special characters. Instead of having to put the lower and upper case versions of a character on separate keys, you can have them both on the same key by using `XP()`. This helps blend Unicode keys in with regular alphas. +This is most useful when creating a keymap for an international layout with special characters. Instead of having to put the lower and upper case versions of a character on separate keys, you can have them both on the same key by using `UP()`. This helps blend Unicode keys in with regular alphas. Due to keycode size constraints, _i_ and _j_ can each only refer to one of the first 128 characters in your `unicode_map`. In other words, 0 ≤ _i_ ≤ 127 and 0 ≤ _j_ ≤ 127. This is enough for most use cases, but if you'd like to customize the index calculation, you can override the [`unicodemap_index()`](https://github.com/qmk/qmk_firmware/blob/71f640d47ee12c862c798e1f56392853c7b1c1a8/quantum/process_keycode/process_unicodemap.c#L36) function. This also allows you to, say, check Ctrl instead of Shift/Caps. diff --git a/docs/feature_userspace.md b/docs/feature_userspace.md deleted file mode 100644 index 8c617fe33a06..000000000000 --- a/docs/feature_userspace.md +++ /dev/null @@ -1,255 +0,0 @@ -# Userspace: Sharing Code Between Keymaps - -If you use more than one keyboard with a similar keymap, you might see the benefit in being able to share code between them. Create your own folder in `users/` named the same as your keymap (ideally your GitHub username, ``) with the following structure: - -* `/users//` (added to the path automatically) - * `readme.md` (optional, recommended) - * `rules.mk` (included automatically) - * `config.h` (included automatically) - * `.h` (optional) - * `.c` (optional) - * `cool_rgb_stuff.c` (optional) - * `cool_rgb_stuff.h` (optional) - - -All this only happens when you build a keymap named ``, like this: - - make planck: - -For example, - - make planck:jack - -Will include the `/users/jack/` folder in the path, along with `/users/jack/rules.mk`. - -!> This `name` can be [overridden](#override-default-userspace), if needed. - -## `Rules.mk` - -The `rules.mk` is one of the two files that gets processed automatically. This is how you add additional source files (such as `.c`) will be added when compiling. - -It's highly recommended that you use `.c` as the default source file to be added. And to add it, you need to add it the SRC in `rules.mk` like this: - - SRC += .c - -Additional files may be added in the same way - it's recommended you have one named ``.c/.h to start off with, though. - -The `/users//rules.mk` file will be included in the build _after_ the `rules.mk` from your keymap. This allows you to have features in your userspace `rules.mk` that depend on individual QMK features that may or may not be available on a specific keyboard. - -For example, if you have RGB control features shared between all your keyboards that support RGB lighting, you can add support for that if the RGBLIGHT feature is enabled: -```make -ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) - # Include my fancy rgb functions source here - SRC += cool_rgb_stuff.c -endif -``` - -Alternatively, you can `define RGB_ENABLE` in your keymap's `rules.mk` and then check for the variable in your userspace's `rules.mk` like this: -```make -ifdef RGB_ENABLE - # Include my fancy rgb functions source here - SRC += cool_rgb_stuff.c -endif -``` - -### Override default userspace - -By default the userspace used will be the same as the keymap name. In some situations this isn't desirable. For instance, if you use the [layout](feature_layouts.md) feature you can't use the same name for different keymaps (e.g. ANSI and ISO). You can name your layouts `mylayout-ansi` and `mylayout-iso` and add the following line to your layout's `rules.mk`: - -``` -USER_NAME := mylayout -``` - -This is also useful if you have multiple different keyboards with different features physically present on the board (such as one with RGB Lights, and one with Audio, or different number of LEDs, or connected to a different PIN on the controller). - -## Configuration Options (`config.h`) - -Additionally, `config.h` here will be processed like the same file in your keymap folder. This is handled separately from the `.h` file. - -The reason for this, is that `.h` won't be added in time to add settings (such as `#define TAPPING_TERM 100`), and including the `` file in any `config.h` files will result in compile issues. - -!>You should use the `config.h` for [configuration options](config_options.md), and the `.h` file for user or keymap specific settings (such as the enum for layer or keycodes) - - -## Readme (`readme.md`) - -Please include authorship (your name, GitHub username, email), and optionally [a license that's GPL compatible](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses). - -You can use this as a template: -``` -Copyright @ - -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 . -``` - -You'd want to replace the year, name, email and GitHub username with your info. - -Additionally, this is a good place to document your code, if you wish to share it with others. - -## Build All Keyboards That Support a Specific Keymap - -Want to check all your keymaps build in a single command? You can run: - - make all: - -For example, - - make all:jack - -This is ideal for when you want ensure everything compiles successfully when preparing a [_Pull request_](https://github.com/qmk/qmk_firmware/pulls). - -## Examples - -For a brief example, checkout [`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/_example). -For a more complicated example, checkout [`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna)'s userspace. - - -### Customized Functions - -QMK has a bunch of [functions](custom_quantum_functions.md) that have [`_quantum`, `_kb`, and `_user` versions](custom_quantum_functions.md#a-word-on-core-vs-keyboards-vs-keymap) that you can use. You will pretty much always want to use the user version of these functions. But the problem is that if you use them in your userspace, then you don't have a version that you can use in your keymap. - -However, you can actually add support for keymap version, so that you can use it in both your userspace and your keymap! - - -For instance, let's look at the `layer_state_set_user()` function. You can enable the [Tri Layer State](ref_functions.md#olkb-tri-layers) functionality on all of your boards, while also retaining the Tri Layer functionality in your `keymap.c` files. - -In your `` file, you'd want to add this: -```c -__attribute__ ((weak)) -layer_state_t layer_state_set_keymap (layer_state_t state) { - return state; -} - -layer_state_t layer_state_set_user (layer_state_t state) { - state = update_tri_layer_state(state, 2, 3, 5); - return layer_state_set_keymap (state); -} -``` -The `__attribute__ ((weak))` part tells the compiler that this is a placeholder function that can then be replaced by a version in your `keymap.c`. That way, you don't need to add it to your `keymap.c`, but if you do, you won't get any conflicts because the function is the same name. - -The `_keymap` part here doesn't matter, it just needs to be something other than `_quantum`, `_kb`, or `_user`, since those are already in use. So you could use `layer_state_set_mine`, `layer_state_set_fn`, or anything else. - -You can see a list of this and other common functions in [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) in [`users/drashna`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna). - -### Custom Features - -Since the Userspace feature can support a staggering number of boards, you may have boards that you want to enable certain functionality for, but not for others. And you can actually create "features" that you can enable or disable in your own userspace. - -For instance, if you wanted to have a bunch of macros available, but only on certain boards (to save space), you could "hide" them being a `#ifdef MACROS_ENABLED`, and then enable it per board. To do this, add this to your rules.mk -```make -ifeq ($(strip $(MACROS_ENABLED)), yes) - OPT_DEFS += -DMACROS_ENABLED -endif -``` -The `OPT_DEFS` setting causes `MACROS_ENABLED` to be defined for your keyboards (note the `-D` in front of the name), and you could use `#ifdef MACROS_ENABLED` to check the status in your c/h files, and handle that code based on that. - -Then you add `MACROS_ENABLED = yes` to the `rules.mk` for you keymap to enable this feature and the code in your userspace. - -And in your `process_record_user` function, you'd do something like this: -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { -#ifdef MACROS_ENABLED - case MACRO1: - if (!record->event.pressed) { - SEND_STRING("This is macro 1!"); - } - break; - case MACRO2: - if (!record->event.pressed) { - SEND_STRING("This is macro 2!"); - } - break; -#endif - } - return true; -} -``` - - -### Consolidated Macros - -If you wanted to consolidate macros and other functions into your userspace for all of your keymaps, you can do that. This builds upon the [Customized Functions](#customized-functions) example above. This lets you maintain a bunch of macros that are shared between the different keyboards, and allow for keyboard specific macros, too. - -First, you'd want to go through all of your `keymap.c` files and replace `process_record_user` with `process_record_keymap` instead. This way, you can still use keyboard specific codes on those boards, and use your custom "global" keycodes as well. You'll also want to replace `SAFE_RANGE` with `NEW_SAFE_RANGE` so that you wont have any overlapping keycodes - -Then add `#include ".h"` to all of your keymap.c files. This allows you to use these new keycodes without having to redefine them in each keymap. - -Once you've done that, you'll want to set the keycode definitions that you need to the `.h` file. For instance: -```c -#pragma once - -#include "quantum.h" -#include "action.h" -#include "version.h" - -// Define all of -enum custom_keycodes { - KC_MAKE = SAFE_RANGE, - NEW_SAFE_RANGE //use "NEW_SAFE_RANGE" for keymap specific codes -}; -``` - -Now you want to create the `.c` file, and add this content to it: - -```c -#include ".h" - -__attribute__ ((weak)) -bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { - return true; -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader - if (!record->event.pressed) { - uint8_t temp_mod = get_mods(); - uint8_t temp_osm = get_oneshot_mods(); - clear_mods(); clear_oneshot_mods(); - SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP); - #ifndef FLASH_BOOTLOADER - if ((temp_mod | temp_osm) & MOD_MASK_SHIFT) - #endif - { - SEND_STRING(":flash"); - } - if ((temp_mod | temp_osm) & MOD_MASK_CTRL) { - SEND_STRING(" -j8 --output-sync"); - } - tap_code(KC_ENT); - set_mods(temp_mod); - } - break; - - } - return process_record_keymap(keycode, record); -} -``` - -For boards that may not have a shift button (such as on a macro pad), we need a way to always include the bootloader option. To do that, add the following to the `rules.mk` in your userspace folder: - -```make -ifeq ($(strip $(FLASH_BOOTLOADER)), yes) - OPT_DEFS += -DFLASH_BOOTLOADER -endif -``` - -This will add a new `KC_MAKE` keycode that can be used in any of your keymaps. And this keycode will output `make :`, making frequent compiling easier. And this will work with any keyboard and any keymap as it will output the current boards info, so that you don't have to type this out every time. - -Also, holding Shift will add the flash target (`:flash`) to the command. Holding Control will add some commands that will speed up compiling time by processing multiple files at once. - -And for the boards that lack a shift key, or that you want to always attempt the flashing part, you can add `FLASH_BOOTLOADER = yes` to the `rules.mk` of that keymap. - -?> This should flash the newly compiled firmware automatically, using the correct utility, based on the bootloader settings (or default to just generating the HEX file). However, it should be noted that this may not work on all systems. AVRDUDE doesn't work on WSL, namely. diff --git a/docs/feature_velocikey.md b/docs/feature_velocikey.md deleted file mode 100644 index aeb1865e8aff..000000000000 --- a/docs/feature_velocikey.md +++ /dev/null @@ -1,29 +0,0 @@ -# Velocikey - -Velocikey is a feature that lets you control the speed of lighting effects (like the Rainbow Swirl effect) with the speed of your typing. The faster you type, the faster the lights will go! - -## Usage -For Velocikey to take effect, there are two steps. First, when compiling your keyboard, you'll need to set `VELOCIKEY_ENABLE=yes` in `rules.mk`, e.g.: - -``` -MOUSEKEY_ENABLE = no -STENO_ENABLE = no -EXTRAKEY_ENABLE = yes -VELOCIKEY_ENABLE = yes -``` - -Then, while using your keyboard, you need to also turn it on with the `VK_TOGG` keycode, which toggles the feature on and off. - -The following light effects will all be controlled by Velocikey when it is enabled: - - RGB Breathing - - RGB Rainbow Mood - - RGB Rainbow Swirl - - RGB Snake - - RGB Knight - -Support for LED breathing effects is planned but not available yet. - - As long as Velocikey is enabled, it will control the speed regardless of any other speed setting that your RGB lights are currently on. - - ## Configuration - Velocikey doesn't currently support any configuration via keyboard settings. If you want to adjust something like the speed increase or decay rate, you would need to edit `velocikey.c` and adjust the values there to achieve the kinds of speeds that you like. diff --git a/docs/feature_wpm.md b/docs/feature_wpm.md deleted file mode 100644 index 4f4ed43739b8..000000000000 --- a/docs/feature_wpm.md +++ /dev/null @@ -1,76 +0,0 @@ -# Word Per Minute (WPM) Calculation - -The WPM feature uses time between keystrokes to compute a rolling average words per minute rate and makes this available for various uses. - -Enable the WPM system by adding this to your `rules.mk`: - - WPM_ENABLE = yes - -For split keyboards using soft serial, the computed WPM score will be available on the master AND slave half. - -## Configuration - -| Define | Default | Description | -|------------------------------|---------------|------------------------------------------------------------------------------------------| -| `WPM_ESTIMATED_WORD_SIZE` | `5` | This is the value used when estimating average word size (for regression and normal use) | -| `WPM_ALLOW_COUNT_REGRESSION` | _Not defined_ | If defined allows the WPM to be decreased when hitting Delete or Backspace | -| `WPM_UNFILTERED` | _Not defined_ | If undefined (the default), WPM values will be smoothed to avoid sudden changes in value | -| `WPM_SAMPLE_SECONDS` | `5` | This defines how many seconds of typing to average, when calculating WPM | -| `WPM_SAMPLE_PERIODS` | `25` | This defines how many sampling periods to use when calculating WPM | -| `WPM_LAUNCH_CONTROL` | _Not defined_ | If defined, WPM values will be calculated using partial buffers when typing begins | - -'WPM_UNFILTERED' is potentially useful if you're filtering data in some other way (and also because it reduces the code required for the WPM feature), or if reducing measurement latency to a minimum is important for you. - -Increasing 'WPM_SAMPLE_SECONDS' will give more smoothly changing WPM values at the expense of slightly more latency to the WPM calculation. - -Increasing 'WPM_SAMPLE_PERIODS' will improve the smoothness at which WPM decays once typing stops, at a cost of approximately this many bytes of firmware space. - -If 'WPM_LAUNCH_CONTROL' is defined, whenever WPM drops to zero, the next time typing begins WPM will be calculated based only on the time since that typing began, instead of the whole period of time specified by WPM_SAMPLE_SECONDS. This results in reaching an accurate WPM value much faster, even when filtering is enabled and a large WPM_SAMPLE_SECONDS value is specified. - -## Public Functions - -|Function |Description | -|--------------------------|--------------------------------------------------| -|`get_current_wpm(void)` | Returns the current WPM as a value between 0-255 | -|`set_current_wpm(x)` | Sets the current WPM to `x` (between 0-255) | - -## Callbacks - -By default, the WPM score only includes letters, numbers, space and some punctuation. If you want to change the set of characters considered as part of the WPM calculation, you can implement your own `bool wpm_keycode_user(uint16_t keycode)` and return true for any characters you would like included in the calculation, or false to not count that particular keycode. - -For instance, the default is: - -```c -bool wpm_keycode_user(uint16_t keycode) { - if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) { - keycode = keycode & 0xFF; - } else if (keycode > 0xFF) { - keycode = 0; - } - if ((keycode >= KC_A && keycode <= KC_0) || (keycode >= KC_TAB && keycode <= KC_SLSH)) { - return true; - } - - return false; -} -``` - -Additionally, if `WPM_ALLOW_COUNT_REGRESSION` is defined, there is the `uint8_t wpm_regress_count(uint16_t keycode)` function that allows you to decrease the WPM. This is useful if you want to be able to penalize certain keycodes (or even combinations). - -```c -__attribute__((weak)) uint8_t wpm_regress_count(uint16_t keycode) { - bool weak_modded = (keycode >= QK_LCTL && keycode < QK_LSFT) || (keycode >= QK_RCTL && keycode < QK_RSFT); - - if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) { - keycode = keycode & 0xFF; - } else if (keycode > 0xFF) { - keycode = 0; - } - if (((get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL} || weak_modded) && (keycode == KC_DEL || keycode == KC_BSPC)) { - return WPM_ESTIMATED_WORD_SIZE; - } - if (keycode == KC_DEL || keycode == KC_BSPC) { - return 1; - } -} -``` diff --git a/docs/flash_driver.md b/docs/flash_driver.md deleted file mode 100644 index fa7fed5171b1..000000000000 --- a/docs/flash_driver.md +++ /dev/null @@ -1,24 +0,0 @@ -# FLASH Driver Configuration :id=flash-driver-configuration - -The FLASH driver can be swapped out depending on the needs of the keyboard, or whether extra hardware is present. - -Driver | Description ------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -`FLASH_DRIVER = spi` | Supports writing to almost all NOR Flash chips. See the driver section below. - - -## SPI FLASH Driver Configuration :id=spi-flash-driver-configuration - -Currently QMK supports almost all NOR Flash chips over SPI. As such, requires a working spi_master driver configuration. You can override the driver configuration via your config.h: - -`config.h` override | Description | Default Value ------------------------------------------------|--------------------------------------------------------------------------------------|----------------- -`#define EXTERNAL_FLASH_SPI_SLAVE_SELECT_PIN` | SPI Slave select pin in order to inform that the FLASH is currently being addressed | _none_ -`#define EXTERNAL_FLASH_SPI_CLOCK_DIVISOR` | Clock divisor used to divide the peripheral clock to derive the SPI frequency | `8` -`#define EXTERNAL_FLASH_PAGE_SIZE` | The Page size of the FLASH in bytes, as specified in the datasheet | `256` -`#define EXTERNAL_FLASH_SECTOR_SIZE` | The sector size of the FLASH in bytes, as specified in the datasheet | `(4 * 1024)` -`#define EXTERNAL_FLASH_BLOCK_SIZE` | The block size of the FLASH in bytes, as specified in the datasheet | `(64 * 1024)` -`#define EXTERNAL_FLASH_SIZE` | The total size of the FLASH in bytes, as specified in the datasheet | `(512 * 1024)` -`#define EXTERNAL_FLASH_ADDRESS_SIZE` | The Flash address size in bytes, as specified in datasheet | `3` - -!> All the above default configurations are based on MX25L4006E NOR Flash. diff --git a/docs/flashing.md b/docs/flashing.md deleted file mode 100644 index 443fa3123e1b..000000000000 --- a/docs/flashing.md +++ /dev/null @@ -1,444 +0,0 @@ -# Flashing Instructions and Bootloader Information - -There are quite a few different types of bootloaders that keyboards use, and almost all of them use their own flashing method and tools. Luckily, projects like the [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) aim to support as many of them as possible, but this article will describe the different types of bootloaders, and available methods for flashing them. - -For AVR-based keyboards, QMK will automatically calculate if your `.hex` file is the right size to be flashed to the device based on the `BOOTLOADER` value set in `rules.mk`, and output the total size in bytes (along with the max). - -You will also be able to use the CLI to flash your keyboard, by running: -``` -$ qmk flash -kb -km -``` -See the [`qmk flash`](cli_commands.md#qmk-flash) documentation for more information. - -## Atmel DFU - -Atmel's DFU bootloader comes on all USB AVRs by default (except for 16/32U4RC), and is used by many keyboards that have their own ICs on their PCBs (older OLKB boards, Clueboards). Some keyboards may also use LUFA's DFU bootloader, or QMK's fork of it (newer OLKB boards), that adds in additional features specific to that hardware. - -To ensure compatibility with the DFU bootloader, make sure this block is present in your `rules.mk` (optionally with `lufa-dfu` or `qmk-dfu` instead): - -```make -# Bootloader selection -BOOTLOADER = atmel-dfu -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` target in QMK (recommended command line) - ``` - dfu-programmer erase --force - dfu-programmer flash --force - dfu-programmer reset - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Press the `QK_BOOT` keycode - * Press the `RESET` button on the PCB if available - * Short RST to GND quickly -2. Wait for the OS to detect the device -3. Erase the flash memory (will be done automatically if using the Toolbox or CLI/`make` command) -4. Flash a .hex file -5. Reset the device into application mode (will be done automatically as above) - -### QMK DFU - -QMK maintains [a fork of the LUFA DFU bootloader](https://github.com/qmk/lufa/tree/master/Bootloaders/DFU) that additionally performs a simple matrix scan for exiting the bootloader and returning to the application, as well as flashing an LED/making a ticking noise with a speaker when things are happening. To enable these features, add the following defines to your `config.h`: - -```c -#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW -#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW -// Optional: -//#define QMK_LED E6 -//#define QMK_SPEAKER C6 -``` -Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic Lite](feature_bootmagic.md), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader. - -The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string. - -To generate this bootloader, use the `bootloader` target, eg. `make planck/rev4:default:bootloader`. To generate a production-ready .hex file (combining QMK and the bootloader), use the `production` target, eg. `make planck/rev4:default:production`. - -### `make` Targets - -* `:dfu`: Checks every 5 seconds until a DFU device is available, and then flashes the firmware. -* `:dfu-split-left` and `:dfu-split-right`: Flashes the firmware as with `:dfu`, but also sets the handedness setting in EEPROM. This is ideal for Elite-C-based split keyboards. - -## Caterina - -Arduino boards and their clones use the [Caterina bootloader](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina) or a variant of it (any keyboard built with a Pro Micro or clone, and the Pololu A-Star), and uses the AVR109 protocol to communicate through virtual serial. - -To ensure compatibility with the Caterina bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = caterina -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) -* [avrdude](https://www.nongnu.org/avrdude/) with the `avr109` programmer / `:avrdude` target in QMK (recommended command line) - ``` - avrdude -p -c avr109 -P -U flash:w::i - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters; some variants may require you to reset twice within 750 milliseconds): - * Press the `QK_BOOT` keycode - * Press the `RESET` button on the PCB if available - * Short RST to GND quickly -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Wait for the device to reset automatically - -### `make` Targets - -* `:avrdude`: Checks every 5 seconds until a Caterina device is available (by detecting a new COM port), and then flashes the firmware. -* `:avrdude-loop`: Flashes the firmware as with `:avrdude`, but after each device is flashed, will attempt to flash again. This is useful for bulk flashing. Hit Ctrl+C to escape the loop. -* `:avrdude-split-left` and `:avrdude-split-right`: Flashes the firmware as with `:avrdude`, but also sets the handedness setting in EEPROM. This is ideal for Pro Micro-based split keyboards. - -## HalfKay - -HalfKay is a super-slim bootloader developed by PJRC that presents itself as an HID device (which requires no additional driver), and comes preflashed on all Teensys, namely the 2.0. It is currently closed-source, and thus once overwritten (eg. via ISP flashing another bootloader), cannot be restored. - -To ensure compatibility with the Halfkay bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = halfkay -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) -* [Teensy Loader Command Line](https://www.pjrc.com/teensy/loader_cli.html) / `:teensy` target in QMK (recommended command line) - ``` - teensy_loader_cli -v -mmcu= - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods (you only have 7 seconds to flash once it enters): - * Press the `QK_BOOT` keycode - * Press the `RESET` button on the Teensy or PCB if available - * short RST to GND quickly -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Reset the device into application mode (may be done automatically) - -## USBasploader - -USBasploader is a bootloader originally by [Objective Development](https://www.obdev.at/products/vusb/usbasploader.html). It emulates a USBasp ISP programmer and is used in some non-USB AVR chips such as the ATmega328P, which run V-USB. - -To ensure compatibility with the USBasploader bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = usbasploader -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) -* [avrdude](https://www.nongnu.org/avrdude/) with the `usbasp` programmer / `:usbasp` target in QMK (recommended command line) - ``` - avrdude -p -c usbasp -U flash:w::i - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Press the `QK_BOOT` keycode - * Keep the `BOOT` button held while quickly tapping the `RESET` button on the PCB -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Press the `RESET` button on the PCB or short RST to GND - -## BootloadHID - -BootloadHID is a USB bootloader for AVR microcontrollers. It presents itself as an HID input device, much like HalfKay, and can therefore be run without installing any driver on Windows. - -To ensure compatibility with the bootloadHID bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = bootloadhid -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) -* [bootloadHID CLI](https://www.obdev.at/products/vusb/bootloadhid.html) / `:bootloadhid` target in QMK (recommended command line) - ``` - bootloadHID -r - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Hold the salt key while plugging the keyboard in - for PS2AVRGB boards, this is usually the key connected to MCU pins A0 and B0, otherwise it will be documented in your keyboard's readme -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Reset the device into application mode (may be done automatically) - -### QMK HID - -QMK maintains [a fork of the LUFA HID bootloader](https://github.com/qmk/lufa/tree/master/Bootloaders/HID), which uses a USB HID Endpoint for flashing in the way that the PJRC's Teensy Loader flasher and HalfKay bootloader work. Additionally, it performs a simple matrix scan for exiting the bootloader and returning to the application, as well as flashing an LED/making a ticking noise with a speaker when things are happening. - -To ensure compatibility with the QMK HID bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = qmk-hid -``` - -To enable the additional features, add the following defines to your `config.h`: - -```c -#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW -#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW -// Optional: -//#define QMK_LED E6 -//#define QMK_SPEAKER C6 -``` - -Currently we do not recommend making `QMK_ESC` the same key as the one designated for [Bootmagic Lite](feature_bootmagic.md), as holding it down will cause the MCU to loop back and forth between entering and exiting the bootloader. - -The manufacturer and product strings are automatically pulled from `config.h`, with " Bootloader" appended to the product string. - -To generate this bootloader, use the `bootloader` target, eg. `make planck/rev4:default:bootloader`. To generate a production-ready .hex file (combining QMK and the bootloader), use the `production` target, eg. `make planck/rev4:default:production`. - -Compatible flashers: - -* TBD - * Currently, you need to either use the [Python script](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp_python), or compile [`hid_bootloader_cli`](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp), from the LUFA repo. Homebrew may (will) have support for this directly (via `brew install qmk/qmk/hid_bootloader_cli`). - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Press the `QK_BOOT` keycode - * Press the `RESET` button on the PCB if available - * short RST to GND quickly -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Reset the device into application mode (may be done automatically) - -### `make` Targets - -* `:qmk-hid`: Checks every 5 seconds until a DFU device is available, and then flashes the firmware. - -## STM32/APM32 DFU - -All STM32 and APM32 MCUs, except for F103 (see the [STM32duino section](#stm32duino)) come preloaded with a factory bootloader that cannot be modified nor deleted. - -To ensure compatibility with the STM32-DFU bootloader, make sure this block is present in your `rules.mk` (optionally with `apm32-dfu` instead): - -```make -# Bootloader selection -BOOTLOADER = stm32-dfu -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [dfu-util](https://dfu-util.sourceforge.net/) / `:dfu-util` target in QMK (recommended command line) - ``` - dfu-util -a 0 -d 0483:DF11 -s 0x8000000:leave -D - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode (may not work on STM32F042 devices) - * If a reset circuit is present, tap the `RESET` button on the PCB; some boards may also have a toggle switch that must be flipped - * Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge -2. Wait for the OS to detect the device -3. Flash a .bin file -4. Reset the device into application mode (may be done automatically) - -### `make` Targets - -* `:dfu-util`: Waits until an STM32 bootloader device is available, and then flashes the firmware. -* `:dfu-util-split-left` and `:dfu-util-split-right`: Flashes the firmware as with `:dfu-util`, but also sets the handedness setting in EEPROM. This is ideal for Proton-C-based split keyboards. -* `:st-link-cli`: Allows you to flash the firmware via the ST-Link CLI utility, rather than dfu-util. Requires an ST-Link dongle. -* `:st-flash`: Allows you to flash the firmware via the `st-flash` utility from [STLink Tools](https://github.com/stlink-org/stlink), rather than dfu-util. Requires an ST-Link dongle. - -## STM32duino - -This bootloader is used almost exclusively for STM32F103 boards, as they do not come with a USB DFU bootloader. The source code and prebuilt binaries can be found [here](https://github.com/rogerclarkmelbourne/STM32duino-bootloader). - -To ensure compatibility with the STM32duino bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = stm32duino -``` - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [dfu-util](https://dfu-util.sourceforge.net/) / `:dfu-util` target in QMK (recommended command line) - ``` - dfu-util -a 2 -d 1EAF:0003 -D - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * If a reset circuit is present, tap the `RESET` button on the PCB - * Otherwise, you need to bridge `BOOT0` to VCC (via `BOOT0` button or jumper), short `RESET` to GND (via `RESET` button or jumper), and then let go of the `BOOT0` bridge -2. Wait for the OS to detect the device -3. Flash a .bin file -4. Reset the device into application mode (may be done automatically) - -## Kiibohd DFU - -Keyboards produced by Input Club use NXP Kinetis microcontrollers rather than STM32, and come with their own [custom bootloader](https://github.com/kiibohd/controller/tree/master/Bootloader), however the process and protocol is largely the same. - -The `rules.mk` setting for this bootloader is `kiibohd`, but since this bootloader is limited to Input Club boards, it should not be necessary to set at keymap or user level. - -Compatible flashers: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (recommended GUI) -* [dfu-util](https://dfu-util.sourceforge.net/) / `:dfu-util` target in QMK (recommended command line) - ``` - dfu-util -a 0 -d 1C11:B007 -D - ``` - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Press the `RESET` button on the PCB -2. Wait for the OS to detect the device -3. Flash a .bin file -4. Reset the device into application mode (may be done automatically) - -## tinyuf2 - -Keyboards may opt into supporting the tinyuf2 bootloader. This is currently only supported on F303/F401/F411. - -The `rules.mk` setting for this bootloader is `tinyuf2`, and can be specified at the keymap or user level. - -To ensure compatibility with the tinyuf2 bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = tinyuf2 -``` - -Compatible flashers: - -* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_. - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Double-tap the `nRST` button on the PCB. -2. Wait for the OS to detect the device -3. Copy the .uf2 file to the new USB disk -4. Wait for the keyboard to become available - -or - -CLI Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Double-tap the `nRST` button on the PCB. -2. Wait for the OS to detect the device -3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/blackpill_f411_tinyuf2 --keymap default` -4. Wait for the keyboard to become available - -### `make` Targets - -* `:uf2-split-left` and `:uf2-split-right`: Flashes the firmware but also sets the handedness setting in EEPROM by generating a side specific firmware. - -## uf2boot - -Keyboards may opt into supporting the uf2boot bootloader. This is currently only supported on F103. - -The `rules.mk` setting for this bootloader is `uf2boot`, and can be specified at the keymap or user level. - -To ensure compatibility with the uf2boot bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = uf2boot -``` - -Compatible flashers: - -* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_. - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Double-tap the `nRST` button on the PCB. -2. Wait for the OS to detect the device -3. Copy the .uf2 file to the new USB disk -4. Wait for the keyboard to become available - -or - -CLI Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Double-tap the `nRST` button on the PCB. -2. Wait for the OS to detect the device -3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/bluepill_uf2boot --keymap default` -4. Wait for the keyboard to become available - -### `make` Targets - -* `:uf2-split-left` and `:uf2-split-right`: Flashes the firmware but also sets the handedness setting in EEPROM by generating a side specific firmware. - -## Raspberry Pi RP2040 UF2 - -The `rules.mk` setting for this bootloader is `rp2040`, and can be specified at the keymap or user level. - -To ensure compatibility with the rp2040 bootloader, make sure this block is present in your `rules.mk`: - -```make -# Bootloader selection -BOOTLOADER = rp2040 -``` - -Compatible flashers: - -* Any application able to copy a file from one place to another, such as _macOS Finder_ or _Windows Explorer_. - -Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Hold the `BOOTSEL` button on the PCB while plugin in the usb cable. - * Double-tap the `RESET` button on the PCB1. -2. Wait for the OS to detect the device -3. Copy the .uf2 file to the new USB disk -4. Wait for the keyboard to become available - -or - -CLI Flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode - * Hold the `BOOTSEL` button on the PCB while plugin in the usb cable. - * Double-tap the `RESET` button on the PCB1. -2. Wait for the OS to detect the device -3. Flash via QMK CLI eg. `qmk flash --keyboard handwired/onekey/rpi_pico --keymap default` -4. Wait for the keyboard to become available - -1: This works only if QMK was compiled with `RP2040_BOOTLOADER_DOUBLE_TAP_RESET` defined. diff --git a/docs/flashing_bootloadhid.md b/docs/flashing_bootloadhid.md deleted file mode 100644 index aacf2cc2c428..000000000000 --- a/docs/flashing_bootloadhid.md +++ /dev/null @@ -1,70 +0,0 @@ -# BootloadHID Flashing Instructions and Bootloader Information - -ps2avr(GB) boards use an ATmega32A microcontroller and a different bootloader. It is not flashable using the regular QMK methods. - -General flashing sequence: - -1. Enter the bootloader using any of the following methods: - * Tap the `QK_BOOT` keycode (may not work on all devices) - * Hold the salt key while plugging the keyboard in (usually documented within keyboard readme) -2. Wait for the OS to detect the device -3. Flash a .hex file -4. Reset the device into application mode (may be done automatically) - -## bootloadHID Flashing Target - -?> Using the QMK installation script, detailed [here](newbs_getting_started.md), the required bootloadHID tools should be automatically installed. - -To flash via the command line, use the target `:bootloadhid` by executing the following command: - - make ::bootloadhid - -## GUI Flashing - -### Windows -1. Download [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash). -2. Place your keyboard into reset. -3. Ensure the configured VendorID is `16c0` and ProductID is `05df` -4. Press the `Find Device` button and ensure that your keyboard is found. -5. Press the `Open .hex File` button and locate the `.hex` file you created. -6. Press the `Flash Device` button and wait for the process to complete. - -## Command Line Flashing - -1. Place your keyboard into reset. -2. Flash the board by typing `bootloadHID -r` followed by the path to your `.hex` file. - -### Windows Manual Installation -For MSYS2: -1. Download the BootloadHID firmware package from https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz. -2. Extract contents using a compatible tool, for example 7-Zip. -3. Add to the MSYS path by copying `commandline/bootloadHID.exe` from the extracted archive to your MSYS2 installation, typically `C:\msys64\usr\bin`. - -For native Windows flashing, the `bootloadHID.exe` can be used outside of the MSYS2 environment. - -### Linux Manual Installation -1. Install libusb development dependency: - ``` - # This depends on OS - for Debian the following works - sudo apt-get install libusb-dev - ``` -2. Download the BootloadHID firmware package: - ``` - wget https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -O - | tar -xz -C /tmp - ``` -3. Build the bootloadHID executable: - ``` - cd /tmp/bootloadHID.2012-12-08/commandline/ - make - sudo cp bootloadHID /usr/local/bin - ``` - -### MacOS Manual Installation -1. Install Homebrew by typing the following: - ``` - /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - ``` -2. Install the following packages: - ``` - brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb - ``` diff --git a/docs/fuse.txt b/docs/fuse.txt deleted file mode 100644 index ceb588be3d2a..000000000000 --- a/docs/fuse.txt +++ /dev/null @@ -1,49 +0,0 @@ -Atmega32u4 Fuse/Lock Bits for Planck/Atomic/Preonic -========================= - - Low Fuse: 0x5E - High Fuse: 0x99 - Extended Fuse: 0xF3 - Lock Byte: 0xFF - - -ATMega168P Fuse/Lock Bits -========================= -This configuration is from usbasploader's Makefile. - - HFUSE 0xD6 - LFUSE 0xDF - EFUSE 0x00 - LOCK 0x3F(intact) - -#--------------------------------------------------------------------- -# ATMega168P -#--------------------------------------------------------------------- -# Fuse extended byte: -# 0x00 = 0 0 0 0 0 0 0 0 <-- BOOTRST (boot reset vector at 0x1800) -# \+/ -# +------- BOOTSZ (00 = 2k bytes) -# Fuse high byte: -# 0xd6 = 1 1 0 1 0 1 1 0 -# ^ ^ ^ ^ ^ \-+-/ -# | | | | | +------ BODLEVEL 0..2 (110 = 1.8 V) -# | | | | + --------- EESAVE (preserve EEPROM over chip erase) -# | | | +-------------- WDTON (if 0: watchdog always on) -# | | +---------------- SPIEN (allow serial programming) -# | +------------------ DWEN (debug wire enable) -# +-------------------- RSTDISBL (reset pin is enabled) -# Fuse low byte: -# 0xdf = 1 1 0 1 1 1 1 1 -# ^ ^ \ / \--+--/ -# | | | +------- CKSEL 3..0 (external >8M crystal) -# | | +--------------- SUT 1..0 (crystal osc, BOD enabled) -# | +------------------ CKOUT (if 0: Clock output enabled) -# +-------------------- CKDIV8 (if 0: divide by 8) - - -# Lock Bits -# 0x3f = - - 1 1 1 1 1 1 -# \ / \-/ \-/ -# | | +----- LB 2..1 (No memory lock features enabled) -# | +--------- BLB0 2..1 (No restrictions for SPM or LPM accessing the Application section) -# +--------------- BLB1 2..1 (No restrictions for SPM or LPM accessing the Boot Loader section) diff --git a/docs/getting_started_docker.md b/docs/getting_started_docker.md deleted file mode 100644 index c4da8af968de..000000000000 --- a/docs/getting_started_docker.md +++ /dev/null @@ -1,55 +0,0 @@ -# Docker Quick Start - -This project includes a Docker workflow that will allow you to build a new firmware for your keyboard very easily without major changes to your primary operating system. This also ensures that when you clone the project and perform a build, you have the exact same environment as anyone else and the QMK build infrastructure. This makes it much easier for people to help you troubleshoot any issues you encounter. - -## Requirements - -The main prerequisite is a working `docker` or `podman` install. -* [Docker CE](https://docs.docker.com/install/#supported-platforms) -* [Podman](https://podman.io/getting-started/installation) - -## Usage - -Acquire a local copy of the QMK's repository (including submodules): - -``` -git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git -cd qmk_firmware -``` - -Run the following command to build a keymap: -``` -util/docker_build.sh : -# For example: util/docker_build.sh planck/rev6:default -``` - -This will compile the desired keyboard/keymap and leave the resulting `.hex` or `.bin` file in the QMK directory for you to flash. If `:keymap` is omitted, all keymaps are used. Note that the parameter format is the same as when building with `make`. - -There is also support for building _and_ flashing the keyboard straight from Docker by specifying the `target` as well: - -``` -util/docker_build.sh keyboard:keymap:target -# For example: util/docker_build.sh planck/rev6:default:flash -``` - -You can also start the script without any parameters, in which case it will ask you to input the build parameters one by one, which you may find easier to use: - -``` -util/docker_build.sh -# Reads parameters as input (leave blank for all keyboards/keymaps) -``` - -You can manually set which container runtime you want to use by setting the `RUNTIME` environment variable to it's name or path. -By default docker or podman are automatically detected and docker is preferred over podman. - -``` -RUNTIME="podman" util/docker_build.sh keyboard:keymap:target -``` - -## FAQ - -### Why can't I flash on Windows/macOS - -On Windows and macOS, it requires [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) to be running. This is tedious to set up, so it's not recommended; use [QMK Toolbox](https://github.com/qmk/qmk_toolbox) instead. - -!> Docker for Windows requires [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) to be enabled. This means that it cannot work on versions of Windows which don't have Hyper-V, such as Windows 7, Windows 8 and **Windows 10 Home**. diff --git a/docs/getting_started_github.md b/docs/getting_started_github.md deleted file mode 100644 index 9232bc62296c..000000000000 --- a/docs/getting_started_github.md +++ /dev/null @@ -1,64 +0,0 @@ -# How to Use GitHub with QMK - -GitHub can be a little tricky to those that aren't familiar with it - this guide will walk through each step of forking, cloning, and submitting a pull request with QMK. - -?> This guide assumes you're somewhat comfortable with running things at the command line, and have git installed on your system. - -Start on the [QMK GitHub page](https://github.com/qmk/qmk_firmware), and you'll see a button in the upper right that says "Fork": - -![Fork on GitHub](https://i.imgur.com/8Toomz4.jpg) - -If you're a part of an organization, you'll need to choose which account to fork it to. In most circumstances, you'll want to fork it to your personal account. Once your fork is completed (sometimes this takes a little while), click the "Clone or Download" button: - -![Download from GitHub](https://i.imgur.com/N1NYcSz.jpg) - -And be sure to select "HTTPS", and select the link and copy it: - -![HTTPS link](https://i.imgur.com/eGO0ohO.jpg) - -From here, enter `git clone --recurse-submodules ` into the command line, and then paste your link: - -``` -user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git -Cloning into 'qmk_firmware'... -remote: Enumerating objects: 9, done. -remote: Counting objects: 100% (9/9), done. -remote: Compressing objects: 100% (5/5), done. -remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 -Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. -Resolving deltas: 100% (119972/119972), done. -... -Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' -Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' -Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' -Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' -``` - -You now have your QMK fork on your local machine, and you can add your keymap, compile it and flash it to your board. Once you're happy with your changes, you can add, commit, and push them to your fork like this: - -``` -user@computer:~$ git add . -user@computer:~$ git commit -m "adding my keymap" -[master cccb1608] adding my keymap - 1 file changed, 1 insertion(+) - create mode 100644 keyboards/planck/keymaps/mine/keymap.c -user@computer:~$ git push -Counting objects: 1, done. -Delta compression using up to 4 threads. -Compressing objects: 100% (1/1), done. -Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. -Total 1 (delta 1), reused 0 (delta 0) -remote: Resolving deltas: 100% (1/1), completed with 1 local objects. -To https://github.com/whoeveryouare/qmk_firmware.git - + 20043e64...7da94ac5 master -> master -``` - -Your changes now exist on your fork on GitHub - if you go back there (`https://github.com//qmk_firmware`), you can create a "New Pull Request" by clicking this button: - -![New Pull Request](https://i.imgur.com/DxMHpJ8.jpg) - -Here you'll be able to see exactly what you've committed - if it all looks good, you can finalize it by clicking "Create Pull Request": - -![Create Pull Request](https://i.imgur.com/Ojydlaj.jpg) - -After submitting, we may talk to you about your changes, ask that you make changes, and eventually accept it! Thanks for contributing to QMK :) diff --git a/docs/getting_started_introduction.md b/docs/getting_started_introduction.md deleted file mode 100644 index 6dc51b82b735..000000000000 --- a/docs/getting_started_introduction.md +++ /dev/null @@ -1,60 +0,0 @@ -# Introduction - -This page attempts to explain the basic information you need to know to work with the QMK project. It assumes that you are familiar with navigating a Unix shell, but does not assume you are familiar with C or with compiling using make. - -## Basic QMK Structure - -QMK is a fork of [Jun Wako](https://github.com/tmk)'s [tmk_keyboard](https://github.com/tmk/tmk_keyboard) project. The original TMK code, with modifications, can be found in the `tmk_core` folder. The QMK additions to the project may be found in the `quantum` folder. Keyboard projects may be found in the `handwired` and `keyboard` folders. - -### Userspace Structure - -Within the folder `users` is a directory for each user. This is a place for users to put code that they might use between keyboards. See the docs for [Userspace feature](feature_userspace.md) for more information. - -### Keyboard Project Structure - -Within the folder `keyboards`, its subfolder `handwired` and its vendor and manufacture subdirectories e.g. `clueboard` is a directory for each keyboard project, for example `qmk_firmware/keyboards/clueboard/2x1800`. Within it, you'll find the following structure: - -* `keymaps/`: Different keymaps that can be built -* `rules.mk`: The file that sets the default "make" options. Do not edit this file directly, instead use a keymap specific `rules.mk`. -* `config.h`: The file that sets the default compile time options. Do not edit this file directly, instead use a keymap specific `config.h`. -* `info.json`: The file used for setting layout for QMK Configurator. See [Configurator Support](reference_configurator_support.md) for more information. -* `readme.md`: A brief overview of the keyboard. -* `.h`: This file is where the keyboard layout is defined against the keyboard's switch matrix. -* `.c`: This file is where you can find custom code for the keyboard. - -For more information on project structure, see [QMK Keyboard Guidelines](hardware_keyboard_guidelines.md). - -### Keymap Structure - -In every keymap folder, the following files may be found. Only `keymap.c` is required, and if the rest of the files are not found the default options will be chosen. - -* `config.h`: the options to configure your keymap -* `keymap.c`: all of your keymap code, required -* `rules.mk`: the features of QMK that are enabled -* `readme.md`: a description of your keymap, how others might use it, and explanations of features. Please upload images to a service like imgur. - -# The `config.h` File - -There are 3 possible `config.h` locations: - -* keyboard (`/keyboards//config.h`) -* userspace (`/users//config.h`) -* keymap (`/keyboards//keymaps//config.h`) - -The build system automatically picks up the config files in the above order. If you wish to override any setting set by a previous `config.h` you will need to first include some boilerplate code for the settings you wish to change. - -``` -#pragma once -``` - -Then to override a setting from the previous `config.h` file you must `#undef` and then `#define` the setting again. - -The boilerplate code and setting look like this together: - -``` -#pragma once - -// overrides go here! -#undef MY_SETTING -#define MY_SETTING 4 -``` diff --git a/docs/getting_started_make_guide.md b/docs/getting_started_make_guide.md index 1a7e276098a7..3d98e4602b48 100644 --- a/docs/getting_started_make_guide.md +++ b/docs/getting_started_make_guide.md @@ -109,7 +109,7 @@ This allows you to send Unicode characters using `UC()` in your keym `UNICODEMAP_ENABLE` -This allows you to send Unicode characters using `X()` in your keymap. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported. +This allows you to send Unicode characters using `UM()` in your keymap. You will need to maintain a mapping table in your keymap file. All possible code points (up to `0x10FFFF`) are supported. `UCIS_ENABLE` diff --git a/docs/gitbook/images/color-wheel.svg b/docs/gitbook/images/color-wheel.svg deleted file mode 100644 index 83e599477f70..000000000000 --- a/docs/gitbook/images/color-wheel.svg +++ /dev/null @@ -1,441 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -image/svg+xmlOpenclipart diff --git a/docs/gitbook/images/favicon.ico b/docs/gitbook/images/favicon.ico deleted file mode 100644 index 2b4e04abafb33adc0bdf4c8da56de2dd73cce097..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1150 zcmb_cy>5d*40hCPSt3>H+_5_oVnOM^8}I@wS=kw~u`uu?z)P@4VnqVh?)*x~wGSOi z$k7m~Am4Y`{`~ol1Araf$0N}A3Fke)2LODLk&8T&p8$Yj?}y36^FI$k5FnR)hD%vZ z(@tbpGTdOCce<_d0$0|*N!{+EWg%aTs`#3|<2YDV7505E z_+8gwp66)W_FWy7zG<2`3n`7)6oL;P;-U>AYv`=lF{L w*0U@5^ZDaGsOC4>)*27z|8^}rmwU5@GM^FYi~WfKE^m|3Pejb0A?Gvi7u3j=jsO4v diff --git a/docs/gitbook/images/favicon.png b/docs/gitbook/images/favicon.png deleted file mode 100644 index 509cebd8798b54b3b203cd3e45b0346dd795347d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 793 zcmV+!1LpjRP)g8{I#3Okck9IIj_rDcTW z<+w8Gg7SMG^Ck9pb}l5bN4yK2AQSj;GQ}7Hd<-%ovkwnm`ej9p{DGhRS#pxA$gEOC zV}&Fs^0-AUNcFhHgy?Y@X^Lk5|Mpc+40+4d?S5!@GK{xgXxxI*reS;@8b;{|tdDS! zt>otpVEA41&5GvQ2gf>`T~@T%4xDd5=Yty6qCb*V+>%JZ>j|_(pzRu(7Rx>R-RJlo z!fWzXSFpPWeRAHh^bIL>XUb$&=#&5e010qNS#tmY3ljhU3ljkVnw%H_00BKoL_t(I zjir-6Zo)7Whrf78GGyc)RPqK=5~%~Z1v4vRi@5>qz-gFz14~89kc}LGjYuGb^g1-= zPm`il{VkTC-_QR1{0w(mtya=!yq5={wSEQOfZ@-C4sC(Cwe|x*HNn1Sn!I;6Q4Q7* zAdX}5JO>~QL)PmxVHg6C=Q(j4UpH~rQH#aGbI~M8$g&K8D2f=3Mnq8rz+^HZNs=pu z^Qo@F^ie0lGkKne$nC67f~u+rf&kz5AI!e*69fTeS+)oO&{~VuTGBL?^Z6{h-A;@# zA|hgpk*ccXcs$B@JQkPhyblD2!-3gshEj^/gpio.h`. - -| Function | Description | Old AVR Examples | Old ChibiOS/ARM Examples | -|------------------------------|-----------------------------------------------------|-------------------------------------------------|--------------------------------------------------| -| `setPinInput(pin)` | Set pin as input with high impedance (High-Z) | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | -| `setPinInputHigh(pin)` | Set pin as input with builtin pull-up resistor | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | -| `setPinInputLow(pin)` | Set pin as input with builtin pull-down resistor | N/A (Not supported on AVR) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | -| `setPinOutput(pin)` | Set pin as output (alias of `setPinOutputPushPull`) | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `setPinOutputPushPull(pin)` | Set pin as output, push/pull mode | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `setPinOutputOpenDrain(pin)` | Set pin as output, open-drain mode | N/A (Not implemented on AVR) | `palSetLineMode(pin, PAL_MODE_OUTPUT_OPENDRAIN)` | -| `writePinHigh(pin)` | Set pin level as high, assuming it is an output | `PORTB \|= (1<<2)` | `palSetLine(pin)` | -| `writePinLow(pin)` | Set pin level as low, assuming it is an output | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | -| `writePin(pin, level)` | Set pin level, assuming it is an output | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | -| `readPin(pin)` | Returns the level of the pin | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | -| `togglePin(pin)` | Invert pin level, assuming it is an output | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | - -## Advanced Settings :id=advanced-settings - -Each microcontroller can have multiple advanced settings regarding its GPIO. This abstraction layer does not limit the use of architecture-specific functions. Advanced users should consult the datasheet of their desired device and include any needed libraries. For AVR, the standard avr/io.h library is used; for STM32, the ChibiOS [PAL library](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html) is used. - -## Atomic Operation - -The above functions are not always guaranteed to work atomically. Therefore, if you want to prevent interruptions in the middle of operations when using multiple combinations of the above functions, use the following `ATOMIC_BLOCK_FORCEON` macro. - -eg. -```c -void some_function(void) { - // some process - ATOMIC_BLOCK_FORCEON { - // Atomic Processing - } - // some process -} -``` - -`ATOMIC_BLOCK_FORCEON` forces interrupts to be disabled before the block is executed, without regard to whether they are enabled or disabled. Then, after the block is executed, the interrupt is enabled. - -Note that `ATOMIC_BLOCK_FORCEON` can therefore be used if you know that interrupts are enabled before the execution of the block, or if you know that it is OK to enable interrupts at the completion of the block. diff --git a/docs/hand_wire.md b/docs/hand_wire.md deleted file mode 100644 index 06809254df23..000000000000 --- a/docs/hand_wire.md +++ /dev/null @@ -1,249 +0,0 @@ -# Hand-Wiring Guide - -## Parts list - -You will need: (where *x* is the number of keys on your planned keyboard) - -* QMK compatible microcontroller board (Teensy, Pro-Micro, QMK Proton C etc.) -* *x* keyswitches (MX, Matias, Gateron, etc) -* *x* through hole diodes -* Keyboard plate and plate mount stabilisers -* Wire -* Soldering iron -* Rosin-cored solder -* Adequate ventilation/a fan -* Wire cutters/snippers - -Optional but useful: - -* Wire strippers/a sharp knife -* Tweezers and/or small needle nose pliers -* Soldering station/Helping hands - -## Starting the build - -There are many ways to hand wire a PCB matrix, this guide will describe the fundamentals as well as some recommended ways to go about it. - -As we are dealing with hand wiring, it is assumed that you already have a plate. If you are planning a completely custom layout, tools such as [ai03 Plate Generator](https://kbplate.ai03.me/) and [Swillkb Plate & Case Builder](http://builder.swillkb.com/) can help when designing one. - -Start by installing the switches and stabilisers in the plate. Depending on the thickness and material this may also involve hot gluing it in place. - -## Planning the matrix - -If you are following a pre-existing handwire guide (e.g. for the keyboards in the [handwire firmware section](https://github.com/qmk/qmk_firmware/tree/master/keyboards/handwired) you can skip this step, just ensure you wire the matrix as described. - -What you want to achieve is one leg from each switch being attached to the corresponding switches next to it (rows) and the other leg being attached to the switches above and below it (columns) and a diode to one of the legs, mosy commonly this will be the leg attached to the rows, and the diode will face away from it (Column to Row) i.e. with the wire furthest from the black line on the diode connected to the switch (as current will only travel in one direction through a diode). - -It is fairly simple to plan for an ortholinear keyboard (like a Planck). - -![Example Planck matrix](https://i.imgur.com/FRShcLD.png) -Image from [RoastPotatoes' "How to hand wire a Planck"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/) - -But the larger and more complicated your keyboard, the more complex the matrix. [Keyboard Firmware Builder](https://kbfirmware.com/) can help you plan your matrix layout (shown here with a basic fullsize ISO keyboard imported from [Keyboard Layout Editor](https://www.keyboard-layout-editor.com). - -![Example ISO matrix](https://i.imgur.com/UlJ4ZDP.png) - -Bear in mind that the number of rows plus the number of columns can not exceed the number of I/O pins on your controller. So the fullsize matrix shown above would be possible on a Proton C or Teensy++, but not on a regular Teensy or Pro Micro. - -### Common Microcontroller Boards - -| Board | Controller | # I/O | Pinout | -| :------------ |:-------------:| ------:| ------ | -| Pro Micro* | ATmega32u4 | 20 | [link](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro#Teensy++_2.0) | -| Teensy 2.0 | ATmega32u4 | 25 | [link](https://www.pjrc.com/teensy/pinout.html) | -| [QMK Proton C](https://qmk.fm/proton-c/) | STM32F303xC | 36 | [link 1](https://i.imgur.com/RhtrAlc.png), [2](https://deskthority.net/wiki/QMK_Proton_C) | -| Teensy++ 2.0 | AT90USB1286 | 46 | [link](https://www.pjrc.com/teensy/pinout.html#Teensy_2.0) | - -*Elite C is essentially the same as a Pro Micro with a USB-C instead of Micro-USB - -There are also a number of boards designed specifically for handwiring that mount directly to a small number of switches and offer pinouts for the rest. Though these are generally more expensive and may be more difficult to get hold of. - -Postage board mini mounted in place - -| Board | Controller | # I/O | -| :------------ |:-------------:| ------:| -| [Swiss helper](https://www.reddit.com/r/MechanicalKeyboards/comments/8jg5d6/hand_wiring_this_might_help/) | ATmega32u4 | 20 | -| [Postage board](https://github.com/LifeIsOnTheWire/Postage-Board/)| ATmega32u4| 25 | -| [Postage board mini](https://geekhack.org/index.php?topic=101460.0)| ATmega32u4| 25 | - -## Wiring the matrix - -There is no one right way to do this. What you want to achieve is good connection at all of the joints planned and no unintentional shorts. - -Established materials and techniques include: - -| Technique | Examples | Pros | Cons | Image -| :-----------| :------- | :------ | :--- | :--- -| Lengths of wire with stripped segments | [Sasha Solomon's Dactyl](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) and [Cribbit's modern hand wire](https://geekhack.org/index.php?topic=87689.0) | Neat and tidy | Some effort in stripping the wire | ![Stripped wire](https://i.imgur.com/0GNIYY0.jpg) -| Short lengths of wire | [u/xicolinguada's ortho build](https://www.reddit.com/r/MechanicalKeyboards/comments/c39k4f/my_first_hand_wired_keyboard_its_not_perfect_but/) | Easier to strip the wire | More difficult to place | ![individual wire lengths](https://i.imgur.com/mBe5vkL.jpg) -| Magnet/Enamelled wire | [fknraiden's custom board](https://geekhack.org/index.php?topic=74223.0) | Can be directly soldered onto (insulation burns off with heat) | Appearance? | ![Magnet wire](https://i.imgur.com/b4b7KDb.jpg) -| Bending the legs of the diodes for the rows | [Matt3o's Brownfox](https://deskthority.net/viewtopic.php?f=7&t=6050) | Fewer solder joints required | Uninsulated | ![Bent diode legs](https://i.imgur.com/aTnG8TV.jpg) -| Using rigid wiring (e.g. brass tube) | [u/d_stilgar's invisible hardline](https://www.reddit.com/r/MechanicalKeyboards/comments/8aw5j2/invisible_hardline_keyboard_progress_update_april/) and [u/jonasfasler's first attempt](https://www.reddit.com/r/MechanicalKeyboards/comments/de1jyv/my_first_attempt_at_handwiring_a_keyboard/) | Very pretty | More difficult. No physical insulation | ![Hardline hand wire](https://i.imgur.com/CnASmPo.jpg) -| Bare wire with insulation added after (e.g. kapton tape) | [Matt3o's 65% on his website](https://matt3o.com/hand-wiring-a-custom-keyboard/) | Easier (no wire stripping required) | Not as attractive | ![Bare wire](https://i.imgur.com/AvXZShD.jpg) -| Copper tape | [ManuForm Dactyl](https://github.com/tshort/dactyl-keyboard) | Very easy | Only really works when your plate/case aligns with the bottom of your switches | ![Copper tape](https://i.imgur.com/RFyNMlL.jpg) - - -Note that these methods can be combined. Prepare your lengths of wire before moving on to soldering. - - -### A note on split keyboards - -If you are planning a split keyboard (e.g. Dactyl) each half will require a controller and a means of communicating between them (like a TRRS or hardwired cable). Further information can be found in the [QMK split keyboard documentation.](feature_split_keyboard.md) - - -### Soldering - -There are a lot of soldering guides and tips available elsewhere but here are some of the most useful and relevant for hand wiring: - -To ensure a strong solder joint you want a good amount of contact between the solder and the two pieces of metal you are connecting. A good way of doing this (though not required) is looping around pins or twisting wires together before applying solder. - -Looped around rod Looped diode leg - -If your diodes are on a packaging strip and need a bend in them (either the start of a loop or for connecting to its neighbour) this can easily done by bending it over something straight like the edge of a box, table, or ruler. This also helps keep track of the direction of the diode as all the bends will be on the same side. - -Bent diode legs - -If your iron has temperature control, set it to 315ºC (600ºF). - -Once heated, tin your soldering iron - this means melting a small amount of solder on the end of the iron and then quickly wiping it off on a wet sponge or wire cleaning pad, leaving a shiny silvery coating on the end which helps keep oxidisation at bay and helps solder to flow. - -When you come to apply the solder, hold the soldering iron against the two surfaces for a second to heat it, then apply a small amount of solder to join the two pieces together. Heating the surfaces ensures that the solder adheres to it and that it does not cool too quickly. - -Don't hold the iron on the solder/joint longer than necessary. Heat will be conducted through the surfaces and can damage components (melt switch housings etc.). Also, solder contains flux, which aids in ["wetting"](https://en.m.wikipedia.org/wiki/Wetting). The longer heat is applied to the solder the more flux will evaporate meaning you may end up with a bad solder joint with peaks which, apart from looking bad, may also increase the risk of electrical shorts. - -#### Soldering the Diodes - -Starting at the top-left switch, place the diode (with tweezers if you have them) on the switch so that the diode itself is vertically aligned, and the black line is facing toward you. Make sure the diodes are soldered in parallel (diode outputs shouldn't connect to diode inputs). The input lead of the diode should be touching the left contact on the switch, and the bent, output end should be facing to the right and resting on the switch there, like this: - -![soldering-diodes-01.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-01.png) - -Letting the diode rest, grab your solder, and touch both it and the soldering iron to the left contact at the same time - the rosin in the solder should make it easy for the solder to flow over both the diode and the keyswitch contact. The diode may move a little, and if it does, carefully position it back it place by grabbing the bent end of the diode - the other end will become hot very quickly. If you find that it's moving too much, using needle-nose pliers of some sort may help to keep the diode still when soldering. - -The smoke that the rosin releases is harmful, so be careful not to breath it or get it in your eyes/face. - -After soldering things in place, it may be helpful to blow on the joint to push the smoke away from your face, and cool the solder quicker. You should see the solder develop a matte (not shiny) surface as it solidifies. Keep in mind that it will still be very hot afterwards, and will take a couple minutes to be cool to touch. Blowing on it will accelerate this process. - -When the first diode is complete, the next one will need to be soldered to both the keyswitch, and the previous diode at the new elbow. That will look something like this: - -![soldering-diodes-02.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-02.png) - -After completing a row, use the wire cutters to trim the excess wire from the tops of the diodes, and from the right side on the final switch. This process will need to completed for each row you have. - -When all of the diodes are completely soldered, it's a good idea to quickly inspect each one to ensure that your solder joints are solid and sturdy - repairing things after this is possible, but more difficult. - -#### Soldering the Columns - -You'll have some options in the next process - it's a good idea to insulate the column wires (since the diodes aren't), but if you're careful enough, you can use exposed wires for the columns - it's not recommended, though. If you're using single-cored wire, stripping the plastic off of the whole wire and feeding it back on is probably the best option, but can be difficult depending on the size and materials. You'll want to leave parts of the wire exposed where you're going to be solder it onto the keyswitch. - -If you're using stranded wire, it's probably easiest to just use a lot of small wires to connect each keyswitch along the column. It's possible to use one and melt through the insulation, but this isn't recommended, will produce even more harmful fumes, and can ruin your soldering iron. - -Before beginning to solder, it helps to have your wire pre-bent (if using single-cored), or at least have an idea of how you're going to route the column (especially if you're making a staggered board). Where you go in particular doesn't matter too much, as we'll be basing our keymap definitions on how it was wired - just make sure every key in a particular row is in a unique column, and that they're in order from left to right. - -If you're not using any insulation, you can try to keep the column wires elevated, and solder them near the tips of the keyswitch contacts - if the wires are sturdy enough, they won't short out to the row wiring an diodes. - -## Wiring up the controller - -Now that the matrix itself is complete, it's time to connect what you've done to the microcontroller board. - -Place the microcontroller where you want it to be located, give thought to mounting and case alignment. Bear in mind that the location of the USB socket can be different from the controller by using a short male to female cable if required,. - -Find the pinout/documentation for your microcontroller board ([links here](#common-microcontroller-boards)) and make a note of all the digital I/O pins on it (note that on some controllers, like the teensy, analogue I/O can double as digital) as these are the pins you want to connect your wires to. - ----- - -### Specific instructions for the Teensy 2.0 - -There are some pins on the Teensy that are special, like D6 (the LED on the chip), or some of the UART, SPI, I2C, or PWM channels, but only avoid those if you're planning something in addition to a keyboard. If you're unsure about wanting to add something later, you should have enough pins in total to avoid a couple. - -The pins you'll absolutely have to avoid, as with any controller, are: GND, VCC, AREF, and RST - all the others are usable and accessible in the firmware. - ----- - - -Cut wires to the length of the distance from the a point on each column/row to the controller. You can solder anywhere along the row, as long as it's after the diode - soldering before the diode (on the keyswitch side) will cause that row not to work. - -Ribbon cable can be used to keep this extra tidy. You may also want to consider routing the wires beneath the exisiting columns/rows. - -Ribbon Cable - -As you solder the wires to the controller make a note of which row/column is going to which pin on the controller as we'll use this data to setup the matrix when we create the firmware. - -As you move along, be sure that the controller is staying in place - recutting and soldering the wires is a pain! - - -## Getting Some Basic Firmware Set Up - -From here, you should have a working keyboard once you program a firmware. - -Simple firmware can be created easily using the [Keyboard Firmware Builder](https://kbfirmware.com/) website. Recreate your layout using [Keyboard Layout Editor](https://www.keyboard-layout-editor.com), import it and recreate the matrix (if not already done as part of [planning the matrix](#planning-the-matrix). - -Go through the rest of the tabs, assigning keys until you get to the last one where you can compile and download your firmware. The .hex file can be flashed straight onto your keyboard, or for advanced functionality, compiled locally after [Setting up Your Environment](newbs_getting_started.md). - -The source given by Keyboard Firmware Builder is QMK, but is based on a version of QMK from early 2017. To compile the firmware in a modern version of QMK Firmware, you'll need to export via the `Save Configuration` button, then run: - - qmk import-kbfirmware /path/to/export.json - -For example: - -``` -$ qmk import-kbfirmware ~/Downloads/gh62.json -Ψ Importing gh62.json. - -⚠ Support here is basic - Consider using 'qmk new-keyboard' instead -Ψ Imported a new keyboard named gh62. -Ψ To start working on things, `cd` into keyboards/gh62, -Ψ or open the directory in your preferred text editor. -Ψ And build with qmk compile -kb gh62 -km default. -``` - - -## Flashing the Firmware - -Install [QMK Toolbox](https://github.com/qmk/qmk_toolbox). - -![QMK Toolbox](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/qmk_toolbox.png "QMK Toolbox 0.0.16 on Windows 8.1") - -Under "Local File" navigate to your newly created .hex file. Under "Microcontroller", select the corresponding one for your controller board (common ones available [here](#common-microcontroller-boards)). - -Plug in your keyboard and press the reset button (or short the Reset and Ground pins if there is no button) and click the "Flash" button in QMK toolbox. - - -## Testing Your Firmware - -Use a website such as [QMK Configurator's Keyboard Tester](https://config.qmk.fm/#/test), [Keyboard Tester](https://www.keyboardtester.com/tester.html), or [Keyboard Checker](https://keyboardchecker.com/) or just open a text editor and try typing - you should get the characters that you put into your keymap. Test each key, and make a note of the ones that aren't working. Here's a quick trouble-shooting guide for non-working keys: - -1. Flip the keyboard back over and short the keyswitch's contacts with a piece wire - this will eliminate the possibility of the keyswitch being bad and needing to be replaced. -2. Check the solder points on the keyswitch - these need to be plump and whole. If you touch it with a moderate amount of force and it comes apart, it's not strong enough. -3. Check the solder joints on the diode - if the diode is loose, part of your row may register, while the other may not. -4. Check the solder joints on the columns - if your column wiring is loose, part or all of the column may not work. -5. Check the solder joints on both sides of the wires going to/from the Teensy - the wires need to be fully soldered and connect to both sides. -6. Check the `.h` file for errors and incorrectly placed `KC_NO`s - if you're unsure where they should be, instead duplicate a k*xy* variable. -7. Check to make sure you actually compiled the firmware and flashed the Teensy correctly. Unless you got error messages in the terminal, or a pop-up during flashing, you probably did everything correctly. -8. Use a multimeter to check that the switch is actually closing when actuated (completing the circuit when pressed down). - -If you've done all of these things, keep in mind that sometimes you might have had multiple things affecting the keyswitch, so it doesn't hurt to test the keyswitch by shorting it out at the end. - -## Finishing up - -Once you have confirmed that the keyboard is working, if you have used a seperate (non handwire specific) controller you will want to secure it in place. This can be done in many different ways e.g. hot glue, double sided sticky tape, 3D printed caddy, electrical tape. - -If you found this fullfilling you could experiment by adding additional features such as [in switch LEDs](https://geekhack.org/index.php?topic=94258.0), [in switch RGB](https://www.reddit.com/r/MechanicalKeyboards/comments/5s1l5u/photoskeyboard_science_i_made_a_handwired_rgb/), [RGB underglow](https://medium.com/@DavidNZ/hand-wired-custom-keyboard-cdd14429c7b3#.7a1ovebsk) or even an [OLED display!](https://www.reddit.com/r/olkb/comments/5zy7og/adding_ssd1306_oled_display_to_your_build/) - -There are a lot of possibilities inside the firmware - explore [docs.qmk.fm](https://docs.qmk.fm) for a full feature list, and dive into the different keyboards to see how people use all of them. You can always stop by [the OLKB subreddit](https://reddit.com/r/olkb) or [QMK Discord](https://discord.gg/Uq7gcHh) for help! - -## Links to Other Guides - -- [matt3o's step by step guide (BrownFox build)](https://deskthority.net/viewtopic.php?f=7&t=6050) also his [website](https://matt3o.com/hand-wiring-a-custom-keyboard/) and [video guide](https://www.youtube.com/watch?v=LVzpsjFWPP4) -- [Cribbit's "Modern hand wiring guide - stronger, cleaner, easier"](https://geekhack.org/index.php?topic=87689.0) -- [Sasha Solomon's "Building my first Keyboard"](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) -- [RoastPotatoes' "How to hand wire a Planck"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/) -- [Masterzen's "Handwired keyboard build log"](https://www.masterzen.fr/2018/12/16/handwired-keyboard-build-log-part-1/) - - -# Legacy Content - -This page used to include more content. We have moved a section that used to be part of this page its own page. Everything below this point is simply a redirect so that people following old links on the web find what they're looking for. - -## Preamble: How a Keyboard Matrix Works (and why we need diodes) :id=preamble-how-a-keyboard-matrix-works-and-why-we-need-diodes - -* [How a Keyboard Matrix Works](how_a_matrix_works.md) diff --git a/docs/hardware_drivers.md b/docs/hardware_drivers.md deleted file mode 100644 index a157501326db..000000000000 --- a/docs/hardware_drivers.md +++ /dev/null @@ -1,35 +0,0 @@ -# QMK Hardware Drivers - -QMK is used on a lot of different hardware. While support for the most common MCU's and matrix configurations is built-in there are a number of drivers that can be added to a keyboard to support additional hardware. Examples include mice and other pointing devices, i/o expanders for split keyboards, bluetooth modules, and LCD, OLED, and TFT screens. - - - -# Available Drivers - -## ProMicro (AVR Only) - -Support for addressing pins on the ProMicro by their Arduino name rather than their AVR name. This needs to be better documented, if you are trying to do this and reading the code doesn't help please [open an issue](https://github.com/qmk/qmk_firmware/issues/new) and we can help you through the process. - -## SSD1306 OLED Driver - -Support for SSD1306 based OLED displays. For more information see the [OLED Driver Feature](feature_oled_driver.md) page. - -## WS2812 - -Support for WS2811/WS2812{a,b,c} LED's. For more information see the [RGB Light](feature_rgblight.md) page. - -## IS31FL3731 - -Support for up to 2 drivers. Each driver impliments 2 charlieplex matrices to individually address LEDs using I2C. This allows up to 144 same color LEDs or 32 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. - -## IS31FL3733 - -Support for up to a single driver with room for expansion. Each driver can control 192 individual LEDs or 64 RGB LEDs. For more information on how to setup the driver see the [RGB Matrix](feature_rgb_matrix.md) page. - -## 24xx series external I2C EEPROM - -Support for an external I2C-based EEPROM instead of using the on-chip EEPROM. For more information on how to setup the driver see the [EEPROM Driver](eeprom_driver.md) page. diff --git a/docs/hardware_keyboard_guidelines.md b/docs/hardware_keyboard_guidelines.md deleted file mode 100644 index fb434e157652..000000000000 --- a/docs/hardware_keyboard_guidelines.md +++ /dev/null @@ -1,263 +0,0 @@ -# QMK Keyboard Guidelines - -Since starting, QMK has grown by leaps and bounds thanks to people like you who contribute to creating and maintaining our community keyboards. As we've grown we've discovered some patterns that work well, and ask that you conform to them to make it easier for other people to benefit from your hard work. - - -## Use QMK Lint - -We have provided a tool, `qmk lint`, which will let you check over your keyboard for problems. We suggest using it frequently while working on your keyboard and keymap. - -Example passing check: - -``` -$ qmk lint -kb rominronin/katana60/rev2 -Ψ Lint check passed! -``` - -Example failing check: - -``` -$ qmk lint -kb clueboard/66/rev3 -☒ Missing keyboards/clueboard/66/rev3/readme.md -☒ Lint check failed! -``` - -## Naming Your Keyboard/Project - -All keyboard names are in lower case, consisting only of letters, numbers, and underscore (`_`). Names may not begin with an underscore. Forward slash (`/`) is used as a sub-folder separation character. - -The names `test`, `keyboard`, and `all` are reserved for make commands and may not be used as a keyboard or subfolder name. - -Valid Examples: - -* `412_64` -* `chimera_ortho` -* `clueboard/66/rev3` -* `planck` -* `v60_type_r` - -## Sub-folders - -QMK uses sub-folders both for organization and to share code between revisions of the same keyboard. You can nest folders up to 4 levels deep: - - qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4 - -If a sub-folder has a `rules.mk` file it will be considered a compilable keyboard. It will be available in QMK Configurator and tested with `make all`. If you are using a folder to organize several keyboards from the same maker you should not have a `rules.mk` file. - -Example: - -Clueboard uses sub-folders for both purposes, organization and keyboard revisions. - -* [`qmk_firmware`](https://github.com/qmk/qmk_firmware/tree/master) - * [`keyboards`](https://github.com/qmk/qmk_firmware/tree/master/keyboards) - * [`clueboard`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard) ← This is the organization folder, there's no `rules.mk` file - * [`60`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/60) ← This is a compilable keyboard, it has a `rules.mk` file - * [`66`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66) ← This is also compilable- it uses `DEFAULT_FOLDER` to specify `rev3` as the default revision - * [`rev1`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev1) ← compilable: `make clueboard/66/rev1` - * [`rev2`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev2) ← compilable: `make clueboard/66/rev2` - * [`rev3`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev3) ← compilable: `make clueboard/66/rev3` or `make clueboard/66` - -## Keyboard Folder Structure - -Your keyboard should be located in `qmk_firmware/keyboards/` and the folder name should be your keyboard's name as described in the previous section. Inside this folder should be several files: - -* `readme.md` -* `info.json` -* `config.h` -* `rules.mk` -* `.c` -* `.h` - -### `readme.md` - -All projects need to have a `readme.md` file that explains what the keyboard is, who made it and where it's available. If applicable, it should also contain links to more information, such as the maker's website. Please follow the [published template](documentation_templates.md#keyboard-readmemd-template). - -### `info.json` - -This file is used by the [QMK API](https://github.com/qmk/qmk_api). It contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard. You can also set metadata here. For more information see the [reference page](reference_info_json.md). - -### `config.h` - -All projects need to have a `config.h` file that sets things like the matrix size, product name, USB VID/PID, description and other settings. In general, use this file to set essential information and defaults for your keyboard that will always work. - -The `config.h` files can also be placed in sub-folders, and the order in which they are read is as follows: - -* `keyboards/top_folder/config.h` - * `keyboards/top_folder/sub_1/config.h` - * `keyboards/top_folder/sub_1/sub_2/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/config.h` - * [`.build/objs_/src/info_config.h`](data_driven_config.md#add-code-to-generate-it) see [Data Driven Configuration](data_driven_config.md) - * `users/a_user_folder/config.h` - * `keyboards/top_folder/keymaps/a_keymap/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/post_config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/post_config.h` - * `keyboards/top_folder/sub_1/sub_2/post_config.h` - * `keyboards/top_folder/sub_1/post_config.h` -* `keyboards/top_folder/post_config.h` - -The `post_config.h` file can be used for additional post-processing, depending on what is specified in the `config.h` file. For example, if you define the `IOS_DEVICE_ENABLE` macro in your keymap-level `config.h` file as follows, you can configure more detailed settings accordingly in the `post_config.h` file: - -* `keyboards/top_folder/keymaps/a_keymap/config.h` - ```c - #define IOS_DEVICE_ENABLE - ``` -* `keyboards/top_folder/post_config.h` - ```c - #ifndef IOS_DEVICE_ENABLE - // USB_MAX_POWER_CONSUMPTION value for this keyboard - #define USB_MAX_POWER_CONSUMPTION 400 - #else - // fix iPhone and iPad power adapter issue - // iOS device need lessthan 100 - #define USB_MAX_POWER_CONSUMPTION 100 - #endif - - #ifdef RGBLIGHT_ENABLE - #ifndef IOS_DEVICE_ENABLE - #define RGBLIGHT_LIMIT_VAL 200 - #define RGBLIGHT_VAL_STEP 17 - #else - #define RGBLIGHT_LIMIT_VAL 35 - #define RGBLIGHT_VAL_STEP 4 - #endif - #ifndef RGBLIGHT_HUE_STEP - #define RGBLIGHT_HUE_STEP 10 - #endif - #ifndef RGBLIGHT_SAT_STEP - #define RGBLIGHT_SAT_STEP 17 - #endif - #endif - ``` - -?> If you define options using `post_config.h` as in the above example, you should not define the same options in the keyboard- or user-level `config.h`. - -### `rules.mk` - -The presence of this file means that the folder is a keyboard target and can be used in `make` commands. This is where you setup the build environment for your keyboard and configure the default set of features. - -The `rules.mk` file can also be placed in a sub-folder, and its reading order is as follows: - -* `keyboards/top_folder/rules.mk` - * `keyboards/top_folder/sub_1/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/rules.mk` - * `keyboards/top_folder/keymaps/a_keymap/rules.mk` - * `users/a_user_folder/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/post_rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/post_rules.mk` - * `keyboards/top_folder/sub_1/sub_2/post_rules.mk` - * `keyboards/top_folder/sub_1/post_rules.mk` -* `keyboards/top_folder/post_rules.mk` -* `common_features.mk` - -Many of the settings written in the `rules.mk` file are interpreted by `common_features.mk`, which sets the necessary source files and compiler options. - -The `post_rules.mk` file can interpret `features` of a keyboard-level before `common_features.mk`. For example, when your designed keyboard has the option to implement backlighting or underglow using rgblight.c, writing the following in the `post_rules.mk` makes it easier for the user to configure the `rules.mk`. - -* `keyboards/top_folder/keymaps/a_keymap/rules.mk` - ```make - # Please set the following according to the selection of the hardware implementation option. - RGBLED_OPTION_TYPE = backlight ## none, backlight or underglow - ``` -* `keyboards/top_folder/post_rules.mk` - ```make - ifeq ($(filter $(strip $(RGBLED_OPTION_TYPE))x, nonex backlightx underglowx x),) - $(error unknown RGBLED_OPTION_TYPE value "$(RGBLED_OPTION_TYPE)") - endif - - ifeq ($(strip $(RGBLED_OPTION_TYPE)),backlight) - RGBLIGHT_ENABLE = yes - OPT_DEFS += -DRGBLED_NUM=30 - endif - ifeq ($(strip $(RGBLED_OPTION_TYPE)),underglow) - RGBLIGHT_ENABLE = yes - OPT_DEFS += -DRGBLED_NUM=6 - endif - ``` - -?> See `build_keyboard.mk` and `common_features.mk` for more details. - -### `` - -This is where you will write custom code for your keyboard. Typically you will write code to initialize and interface with the hardware in your keyboard. If your keyboard consists of only a key matrix with no LEDs, speakers, or other auxiliary hardware this file can be blank. - -The following functions are typically defined in this file: - -* `void matrix_init_kb(void)` -* `void matrix_scan_kb(void)` -* `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` -* `bool led_update_kb(led_t led_state)` - -### `` - -This file is used to define the matrix for your keyboard. You should define at least one C macro which translates an array into a matrix representing the physical switch matrix for your keyboard. If it's possible to build your keyboard with multiple layouts you should define additional macros. - -If you have only a single layout you should call this macro `LAYOUT`. - -When defining multiple layouts you should have a base layout, named `LAYOUT_all`, that supports all possible switch positions on your matrix, even if that layout is impossible to build physically. This is the macro you should use in your `default` keymap. You should then have additional keymaps named `default_` that use your other layout macros. This will make it easier for people to use the layouts you define. - -Layout macro names are entirely lowercase, except for the word `LAYOUT` at the front. - -As an example, if you have a 60% PCB that supports ANSI and ISO you might define the following layouts and keymaps: - -| Layout Name | Keymap Name | Description | -|-------------|-------------|-------------| -| LAYOUT_all | default | A layout that supports both ISO and ANSI | -| LAYOUT_ansi | default_ansi | An ANSI layout | -| LAYOUT_iso | default_iso | An ISO layout | - -?> Providing only `LAYOUT_all` is invalid - especially when implementing the additional layouts within 3rd party tooling. - -## Image/Hardware Files - -In an effort to keep the repo size down we're no longer accepting binary files of any format, with few exceptions. Hosting them elsewhere (such as ) and linking them in the `readme.md` is preferred. - -Hardware files (such as plates, cases, pcb) can be contributed to the [qmk.fm repo](https://github.com/qmk/qmk.fm) and they will be made available on [qmk.fm](https://qmk.fm). Downloadable files are stored in `//` (name follows the same format as above) which are served at `https://qmk.fm//`, and pages are generated from `/_pages//` which are served at the same location (.md files are generated into .html files through Jekyll). Check out the `lets_split` folder for an example. - -## Keyboard Defaults - -Given the amount of functionality that QMK exposes it's very easy to confuse new users. When putting together the default firmware for your keyboard we recommend limiting your enabled features and options to the minimal set needed to support your hardware. Recommendations for specific features follow. - -### Magic Keycodes and Command - -[Magic Keycodes](keycodes_magic.md) and [Command](feature_command.md) are two related features that allow a user to control their keyboard in non-obvious ways. We recommend you think long and hard about if you're going to enable either feature, and how you will expose this functionality. Keep in mind that users who want this functionality can enable it in their personal keymaps without affecting all the novice users who may be using your keyboard as their first programmable board. - -By far the most common problem new users encounter is accidentally triggering Bootmagic while they're plugging in their keyboard. They're holding the keyboard by the bottom, unknowingly pressing in alt and spacebar, and then they find that these keys have been swapped on them. We recommend leaving this feature disabled by default, but if you do turn it on consider setting `BOOTMAGIC_KEY_SALT` to a key that is hard to press while plugging your keyboard in. - -If your keyboard does not have 2 shift keys you should provide a working default for `IS_COMMAND`, even when you have set `COMMAND_ENABLE = no`. This will give your users a default to conform to if they do enable Command. - -## Custom Keyboard Programming - -As documented on [Customizing Functionality](custom_quantum_functions.md) you can define custom functions for your keyboard. Please keep in mind that your users may want to customize that behavior as well, and make it possible for them to do that. If you are providing a custom function, for example `process_record_kb()`, make sure that your function calls the `_user()` version of the call too. You should also take into account the return value of the `_user()` version, and only run your custom code if the user returns `true`. - -## Non-Production/Handwired Projects - -We're happy to accept any project that uses QMK, including prototypes and handwired ones, but we have a separate `/keyboards/handwired/` folder for them, so the main `/keyboards/` folder doesn't get overcrowded. If a prototype project becomes a production project at some point in the future, we'd be happy to move it to the main `/keyboards/` folder! - -## Warnings as Errors - -When developing your keyboard, keep in mind that all warnings will be treated as errors - these small warnings can build-up and cause larger errors down the road (and keeping them is generally a bad practice). - -## Copyright Blurb - -If you're adapting your keyboard's setup from another project, but not using the same code, be sure to update the copyright header at the top of the files to show your name, in this format: - - Copyright 2017 Your Name - -If you are modifying someone else's code and have made only trivial changes you should leave their name in the copyright statement. If you have done significant work on the file you should add your name to theirs, like so: - - Copyright 2017 Their Name Your Name - -The year should be the first year the file is created. If work was done to that file in later years you can reflect that by appending the second year to the first, like so: - - Copyright 2015-2017 Your Name - -## License - -The core of QMK is licensed under the [GNU General Public License](https://www.gnu.org/licenses/licenses.en.html). If you are shipping binaries for AVR processors you may choose either [GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) or [GPLv3](https://www.gnu.org/licenses/gpl.html). If you are shipping binaries for ARM processors you must choose [GPL Version 3](https://www.gnu.org/licenses/gpl.html) to comply with the [ChibiOS](https://www.chibios.org) GPLv3 license. - -## Technical Details - -If you're looking for more information on making your keyboard work with QMK, [check out the hardware section](hardware.md)! diff --git a/docs/how_a_matrix_works.md b/docs/how_a_matrix_works.md deleted file mode 100644 index 48e41e5c7ded..000000000000 --- a/docs/how_a_matrix_works.md +++ /dev/null @@ -1,99 +0,0 @@ -# How a Keyboard Matrix Works - -Keyboard switch matrices are arranged in rows and columns. Without a matrix circuit, each switch would require its own wire directly to the controller. - -When the circuit is arranged in rows and columns, if a key is pressed, a column wire makes contact with a row wire and completes a circuit. The keyboard controller detects this closed circuit and registers it as a key press. - -The microcontroller will be set up via the firmware to send a logical 1 to the columns, one at a time, and read from the rows, all at once - this process is called matrix scanning. The matrix is a bunch of open switches that, by default, don't allow any current to pass through - the firmware will read this as no keys being pressed. As soon as you press one key down, the logical 1 that was coming from the column the keyswitch is attached to gets passed through the switch and to the corresponding row - check out the following 2x2 example: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - row0 ---(key0)---(key1) row0 ---(key0)---(key1) - | | | | - row1 ---(key2)---(key3) row1 ---(key2)---(key3) - -The `x` represents that the column/row associated has a value of 1, or is HIGH. Here, we see that no keys are being pressed, so no rows get an `x`. For one keyswitch, keep in mind that one side of the contacts is connected to its row, and the other, its column. - -When we press `key0`, `col0` gets connected to `row0`, so the values that the firmware receives for that row is `0b01` (the `0b` here means that this is a bit value, meaning all of the following digits are bits - 0 or 1 - and represent the keys in that column). We'll use this notation to show when a keyswitch has been pressed, to show that the column and row are being connected: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1) - | | | | - row1 ---(key2)---(key3) row1 ---(key2)---(key3) - -We can now see that `row0` has an `x`, so has the value of 1. As a whole, the data the firmware receives when `key0` is pressed is: - - col0: 0b01 - col1: 0b00 - │└row0 - └row1 - -A problem arises when you start pressing more than one key at a time. Looking at our matrix again, it should become pretty obvious: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1) - | | | | - x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3) - - Remember that this ^ is still connected to row1 - -The data we get from that is: - - col0: 0b11 - col1: 0b11 - │└row0 - └row1 - -Which isn't accurate, since we only have 3 keys pressed down, not all 4. This behavior is called ghosting, and only happens in odd scenarios like this, but can be much more common on a bigger keyboard. The way we can get around this is by placing a diode after the keyswitch, but before it connects to its row. A diode only allows current to pass through one way, which will protect our other columns/rows from being activated in the previous example. We'll represent a dioded matrix like this; - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - │ │ | │ - (key0) (key1) (key0) (key1) - ! │ ! │ ! | ! │ - row0 ─────┴────────┘ │ row0 ─────┴────────┘ │ - │ │ | │ - (key2) (key3) (key2) (key3) - ! ! ! ! - row1 ─────┴────────┘ row1 ─────┴────────┘ - -In practical applications, the black line of the diode will be placed facing the row, and away from the keyswitch - the `!` in this case is the diode, where the gap represents the black line. A good way to remember this is to think of this symbol: `>|` - -Now when we press the three keys, invoking what would be a ghosting scenario: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - │ │ │ │ - (┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1) - ! │ ! │ ! │ ! │ - x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │ - │ │ │ │ - (key2) (┌─┘3) (key2) (┌─┘3) - ! ! ! ! - row1 ─────┴────────┘ x row1 ─────┴────────┘ - -Things act as they should! Which will get us the following data: - - col0: 0b01 - col1: 0b11 - │└row0 - └row1 - -The firmware can then use this correct data to detect what it should do, and eventually, what signals it needs to send to the OS. - -Further reading: -- [Wikipedia article](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit) -- [Deskthority article](https://deskthority.net/wiki/Keyboard_matrix) -- [Keyboard Matrix Help by Dave Dribin (2000)](https://www.dribin.org/dave/keyboard/one_html/) -- [How Key Matrices Works by PCBheaven](https://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (animated examples) -- [How keyboards work - QMK documentation](how_keyboards_work.md) diff --git a/docs/how_keyboards_work.md b/docs/how_keyboards_work.md deleted file mode 100644 index 0f4b039fd4f6..000000000000 --- a/docs/how_keyboards_work.md +++ /dev/null @@ -1,76 +0,0 @@ -# How Keys Are Registered, and Interpreted by Computers - -In this file, you can will learn the concepts of how keyboards work over USB, -and you'll be able to better understand what you can expect from changing your -firmware directly. - -## Schematic View - -Whenever you type on 1 particular key, here is the chain of actions taking -place: - -``` -+------+ +-----+ +----------+ +----------+ +----+ -| User |-------->| Key |------>| Firmware |----->| USB wire |---->| OS | -+------+ +-----+ +----------+ +----------+ +----+ -``` - -This scheme is a very simple view of what's going on, and more details follow -in the next sections. - -## 1. You Press a Key - -Whenever you press a key, the firmware of your keyboard can register this event. -It can register when the key is pressed, held and released. - -This usually happens with a periodic scan of key presses. This speed often is limited by the mechanical key response time, the protocol to transfer those key presses (here USB HID), and by the software it is used in. - -## 2. What the Firmware Sends - -The [HID specification](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) tells what a keyboard can actually send through USB to have a chance to be properly recognised. This includes a pre-defined list of scancodes which are simple numbers from `0x00` to `0xE7`. The firmware assigns a scancode to each key of the keyboard. - -The firmware does not send actual letters or characters, but only scancodes. -Thus, by modifying the firmware, you can only modify what scancode is sent over -USB for a given key. - -## 3. What the Event Input/Kernel Does - -The *scancode* is mapped to a *keycode* dependent on the keyboard [60-keyboard.hwdb at Main](https://github.com/systemd/systemd/blob/main/hwdb.d/60-keyboard.hwdb). Without this mapping, the operating system will not receive a valid keycode and will be unable to do anything useful with that key press. - -## 4. What the Operating System Does - -Once the keycode reaches the operating system, a piece of software has to have -it match an actual character thanks to a keyboard layout. For example, if your -layout is set to QWERTY, a sample of the matching table is as follows: - -| keycode | character | -|---------|-----------| -| 0x04 | a/A | -| 0x05 | b/B | -| 0x06 | c/C | -| ... | ... | -| 0x1C | y/Y | -| 0x1D | z/Z | -| ... | ... | - -## Back to the Firmware - -As the layout is generally fixed (unless you create your own), the firmware can actually call a keycode by its layout name directly to ease things for you. This is exactly what is done here with `KC_A` actually representing `0x04` in QWERTY. The full list can be found in [keycodes](keycodes.md). - -## List of Characters You Can Send - -Putting aside shortcuts, having a limited set of keycodes mapped to a limited layout means that **the list of characters you can assign to a given key are only the ones present in the layout**. - -For example, this means that if you have a QWERTY US layout, and you want to assign one key to produce `€` (euro currency symbol), you are unable to do so, because the QWERTY US layout does not have such mapping. You could fix that by using a QWERTY UK layout, or a QWERTY US International. - -You may wonder why a keyboard layout containing all of Unicode is not devised then? The limited number of keycodes available through USB simply disallows such a thing. - -## How to (Maybe) Enter Unicode Characters - -You can have the firmware send *sequences of keys* to use the [software Unicode Input Method](https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_input) of the target operating system, thus effectively entering characters independently of the layout defined in the OS. - -Yet, it does come with multiple disadvantages: - - - Tied to a specific OS at a time (need recompilation when changing OS); - - Within a given OS, does not work in all software; - - Limited to a subset of Unicode on some systems. diff --git a/docs/i2c_driver.md b/docs/i2c_driver.md deleted file mode 100644 index f4e6c6619e64..000000000000 --- a/docs/i2c_driver.md +++ /dev/null @@ -1,278 +0,0 @@ -# I2C Master Driver :id=i2c-master-driver - -The I2C Master drivers used in QMK have a set of common functions to allow portability between MCUs. - -## I2C Addressing :id=note-on-i2c-addresses - -All of the addresses expected by this driver should be pushed to the upper 7 bits of the address byte. Setting -the lower bit (indicating read/write) will be done by the respective functions. Almost all I2C addresses listed -on datasheets and the internet will be represented as 7 bits occupying the lower 7 bits and will need to be -shifted to the left (more significant) by one bit. This is easy to do via the bitwise shift operator `<< 1`. - -You can either do this on each call to the functions below, or once in your definition of the address. For example, if your device has an address of `0x18`: - -```c -#define MY_I2C_ADDRESS (0x18 << 1) -``` - -See https://www.robot-electronics.co.uk/i2c-tutorial for more information about I2C addressing and other technical details. - -## AVR Configuration :id=avr-configuration - -The following defines can be used to configure the I2C master driver: - -|`config.h` Override|Description |Default | -|-------------------|---------------------|--------| -|`F_SCL` |Clock frequency in Hz|`400000`| - -No further setup is required - just connect the `SDA` and `SCL` pins of your I2C devices to the matching pins on the MCU: - -|MCU |`SCL`|`SDA`| -|------------------|-----|-----| -|ATmega16/32U4 |`D0` |`D1` | -|AT90USB64/128 |`D0` |`D1` | -|ATmega32A |`C0` |`C1` | -|ATmega328/P |`C5` |`C4` | - -?> The ATmega16/32U2 does not possess I2C functionality, and so cannot use this driver. - -## ChibiOS/ARM Configuration :id=arm-configuration - -You'll need to determine which pins can be used for I2C -- a an example, STM32 parts generally have multiple I2C peripherals, labeled I2C1, I2C2, I2C3 etc. - -To enable I2C, modify your board's `halconf.h` to enable I2C: - -```c -#define HAL_USE_I2C TRUE -``` - -Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: - -```c -#undef STM32_I2C_USE_I2C2 -#define STM32_I2C_USE_I2C2 TRUE -``` - -|`mcuconf.h` Setting |Description |Default| -|----------------------------|----------------------------------------------------------------------------------|-------| -|`STM32_I2C_BUSY_TIMEOUT` |Time in milliseconds until the I2C command is aborted if no response is received |`50` | -|`STM32_I2C_XXX_IRQ_PRIORITY`|Interrupt priority for hardware driver XXX (THIS IS AN EXPERT SETTING) |`10` | -|`STM32_I2C_USE_DMA` |Enable/Disable the ability of the MCU to offload the data transfer to the DMA unit|`TRUE` | -|`STM32_I2C_XXX_DMA_PRIORITY`|Priority of DMA unit for hardware driver XXX (THIS IS AN EXPERT SETTING) |`1` | - -Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. - -|`config.h` Overrride |Description |Default| -|------------------------|--------------------------------------------------------------|-------| -|`I2C_DRIVER` |I2C peripheral to use - I2C1 -> `I2CD1`, I2C2 -> `I2CD2` etc. |`I2CD1`| -|`I2C1_SCL_PIN` |The pin definition for SCL |`B6` | -|`I2C1_SCL_PAL_MODE` |The alternate function mode for SCL |`4` | -|`I2C1_SDA_PIN` |The pin definition for SDA |`B7` | -|`I2C1_SDA_PAL_MODE` |The alternate function mode for SDA |`4` | - -The following configuration values depend on the specific MCU in use. - -### I2Cv1 :id=i2cv1 - -* STM32F1xx -* STM32F2xx -* STM32F4xx -* STM32L0xx -* STM32L1xx - -See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#7_I2Cv1_configuration_structure) for the I2Cv1 configuration structure. - -|`config.h` Override|Default | -|-------------------|----------------| -|`I2C1_OPMODE` |`OPMODE_I2C` | -|`I2C1_CLOCK_SPEED` |`100000` | -|`I2C1_DUTY_CYCLE` |`STD_DUTY_CYCLE`| - -### I2Cv2 :id=i2cv2 - -* STM32F0xx -* STM32F3xx -* STM32F7xx -* STM32L4xx - -See [this page](https://www.playembedded.org/blog/stm32-i2c-chibios/#8_I2Cv2_I2Cv3_configuration_structure) for the I2Cv2 configuration structure. - -|`config.h` Override |Default| -|---------------------|-------| -|`I2C1_TIMINGR_PRESC` |`0U` | -|`I2C1_TIMINGR_SCLDEL`|`7U` | -|`I2C1_TIMINGR_SDADEL`|`0U` | -|`I2C1_TIMINGR_SCLH` |`38U` | -|`I2C1_TIMINGR_SCLL` |`129U` | - -## Functions :id=functions - -### `void i2c_init(void)` - -Initialize the I2C driver. This function must be called only once, before any of the below functions can be called. - -This function is weakly defined, meaning it can be overridden if necessary for your particular use case: - -```c -void i2c_init(void) { - setPinInput(B6); // Try releasing special pins for a short time - setPinInput(B7); - wait_ms(10); // Wait for the release to happen - - palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function - palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function -} -``` - ---- - -### `i2c_status_t i2c_start(uint8_t address, uint16_t timeout)` - -Start an I2C transaction. - -#### Arguments - - - `uint8_t address` - The 7-bit I2C address of the device (ie. without the read/write bit - this will be set automatically). - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_transmit(uint8_t address, uint8_t *data, uint16_t length, uint16_t timeout)` - -Send multiple bytes to the selected I2C device. - -#### Arguments - - - `uint8_t address` - The 7-bit I2C address of the device. - - `uint8_t *data` - A pointer to the data to transmit. - - `uint16_t length` - The number of bytes to write. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout)` - -Receive multiple bytes from the selected I2C device. - -#### Arguments - - - `uint8_t address` - The 7-bit I2C address of the device. - - `uint8_t *data` - A pointer to the buffer to read into. - - `uint16_t length` - The number of bytes to read. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` - -Writes to a register with an 8-bit address on the I2C device. - -#### Arguments - - - `uint8_t devaddr` - The 7-bit I2C address of the device. - - `uint8_t regaddr` - The register address to write to. - - `uint8_t *data` - A pointer to the data to transmit. - - `uint16_t length` - The number of bytes to write. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_writeReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` - -Writes to a register with a 16-bit address (big endian) on the I2C device. - -#### Arguments - - - `uint8_t devaddr` - The 7-bit I2C address of the device. - - `uint16_t regaddr` - The register address to write to. - - `uint8_t *data` - A pointer to the data to transmit. - - `uint16_t length` - The number of bytes to write. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` - -Reads from a register with an 8-bit address on the I2C device. - -#### Arguments - - - `uint8_t devaddr` - The 7-bit I2C address of the device. - - `uint8_t regaddr` - The register address to read from. - - `uint16_t length` - The number of bytes to read. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_readReg16(uint8_t devaddr, uint16_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout)` - -Reads from a register with a 16-bit address (big endian) on the I2C device. - -#### Arguments - - - `uint8_t devaddr` - The 7-bit I2C address of the device. - - `uint16_t regaddr` - The register address to read from. - - `uint16_t length` - The number of bytes to read. Take care not to overrun the length of `data`. - - `uint16_t timeout` - The time in milliseconds to wait for a response from the target device. - -#### Return Value - -`I2C_STATUS_TIMEOUT` if the timeout period elapses, `I2C_STATUS_ERROR` if some other error occurs, otherwise `I2C_STATUS_SUCCESS`. - ---- - -### `i2c_status_t i2c_stop(void)` - -Stop the current I2C transaction. diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 4827024bdc7b..000000000000 --- a/docs/index.html +++ /dev/null @@ -1,147 +0,0 @@ - - - - - QMK Firmware - - - - - - - - - - - - - - - - - -
- - - - - - - - - - - - - - - diff --git a/docs/internals/defines.md b/docs/internals/defines.md deleted file mode 100644 index fdcb553589bd..000000000000 --- a/docs/internals/defines.md +++ /dev/null @@ -1,78 +0,0 @@ -# group `defines` {#group__defines} - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`define `[`SYSEX_BEGIN`](#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79) | -`define `[`SYSEX_END`](#group__defines_1ga753706d1d28e6f96d7caf1973e80feed) | -`define `[`MIDI_STATUSMASK`](#group__defines_1gab78a1c818a5f5dab7a8946543f126c69) | -`define `[`MIDI_CHANMASK`](#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909) | -`define `[`MIDI_CC`](#group__defines_1ga45f116a1daab76b3c930c2cecfaef215) | -`define `[`MIDI_NOTEON`](#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7) | -`define `[`MIDI_NOTEOFF`](#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc) | -`define `[`MIDI_AFTERTOUCH`](#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f) | -`define `[`MIDI_PITCHBEND`](#group__defines_1gabcc799504e8064679bca03f232223af4) | -`define `[`MIDI_PROGCHANGE`](#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42) | -`define `[`MIDI_CHANPRESSURE`](#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe) | -`define `[`MIDI_CLOCK`](#group__defines_1gafa5e4e295aafd15ab7893344599b3b89) | -`define `[`MIDI_TICK`](#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7) | -`define `[`MIDI_START`](#group__defines_1ga8233631c85823aa546f932ad8975caa4) | -`define `[`MIDI_CONTINUE`](#group__defines_1gab24430f0081e27215b0da84dd0ee745c) | -`define `[`MIDI_STOP`](#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62) | -`define `[`MIDI_ACTIVESENSE`](#group__defines_1gacd88ed42dba52bb4b2052c5656362677) | -`define `[`MIDI_RESET`](#group__defines_1ga02947f30ca62dc332fdeb10c5868323b) | -`define `[`MIDI_TC_QUARTERFRAME`](#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31) | -`define `[`MIDI_SONGPOSITION`](#group__defines_1ga412f6ed33a2150051374bee334ee1705) | -`define `[`MIDI_SONGSELECT`](#group__defines_1gafcab254838b028365ae0259729e72c4e) | -`define `[`MIDI_TUNEREQUEST`](#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795) | -`define `[`SYSEX_EDUMANUFID`](#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f) | - -## Members - -#### `define `[`SYSEX_BEGIN`](#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79) {#group__defines_1ga1a3c39bb790dda8a368c4247caabcf79} - -#### `define `[`SYSEX_END`](#group__defines_1ga753706d1d28e6f96d7caf1973e80feed) {#group__defines_1ga753706d1d28e6f96d7caf1973e80feed} - -#### `define `[`MIDI_STATUSMASK`](#group__defines_1gab78a1c818a5f5dab7a8946543f126c69) {#group__defines_1gab78a1c818a5f5dab7a8946543f126c69} - -#### `define `[`MIDI_CHANMASK`](#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909) {#group__defines_1ga239edc0a6f8405d3a8f2804f1590b909} - -#### `define `[`MIDI_CC`](#group__defines_1ga45f116a1daab76b3c930c2cecfaef215) {#group__defines_1ga45f116a1daab76b3c930c2cecfaef215} - -#### `define `[`MIDI_NOTEON`](#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7) {#group__defines_1gafd416f27bf3590868c0c1f55c30be4c7} - -#### `define `[`MIDI_NOTEOFF`](#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc) {#group__defines_1gabed24bea2d989fd655e2ef2ad0765adc} - -#### `define `[`MIDI_AFTERTOUCH`](#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f) {#group__defines_1ga3a322d8cfd53576a2e167c1840551b0f} - -#### `define `[`MIDI_PITCHBEND`](#group__defines_1gabcc799504e8064679bca03f232223af4) {#group__defines_1gabcc799504e8064679bca03f232223af4} - -#### `define `[`MIDI_PROGCHANGE`](#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42) {#group__defines_1gaefb3f1595ffbb9db66b46c2c919a3d42} - -#### `define `[`MIDI_CHANPRESSURE`](#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe) {#group__defines_1gaeb3281cc7fcd0daade8ed3d2dfc33dbe} - -#### `define `[`MIDI_CLOCK`](#group__defines_1gafa5e4e295aafd15ab7893344599b3b89) {#group__defines_1gafa5e4e295aafd15ab7893344599b3b89} - -#### `define `[`MIDI_TICK`](#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7) {#group__defines_1ga3b99408ff864613765d4c3c2ceb52aa7} - -#### `define `[`MIDI_START`](#group__defines_1ga8233631c85823aa546f932ad8975caa4) {#group__defines_1ga8233631c85823aa546f932ad8975caa4} - -#### `define `[`MIDI_CONTINUE`](#group__defines_1gab24430f0081e27215b0da84dd0ee745c) {#group__defines_1gab24430f0081e27215b0da84dd0ee745c} - -#### `define `[`MIDI_STOP`](#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62) {#group__defines_1ga3af9271d4b1f0d22904a0b055f48cf62} - -#### `define `[`MIDI_ACTIVESENSE`](#group__defines_1gacd88ed42dba52bb4b2052c5656362677) {#group__defines_1gacd88ed42dba52bb4b2052c5656362677} - -#### `define `[`MIDI_RESET`](#group__defines_1ga02947f30ca62dc332fdeb10c5868323b) {#group__defines_1ga02947f30ca62dc332fdeb10c5868323b} - -#### `define `[`MIDI_TC_QUARTERFRAME`](#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31) {#group__defines_1gaaa072f33590e236d1bfd8f28e833ae31} - -#### `define `[`MIDI_SONGPOSITION`](#group__defines_1ga412f6ed33a2150051374bee334ee1705) {#group__defines_1ga412f6ed33a2150051374bee334ee1705} - -#### `define `[`MIDI_SONGSELECT`](#group__defines_1gafcab254838b028365ae0259729e72c4e) {#group__defines_1gafcab254838b028365ae0259729e72c4e} - -#### `define `[`MIDI_TUNEREQUEST`](#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795) {#group__defines_1ga8100b907b8c0a84e58b1c53dcd9bd795} - -#### `define `[`SYSEX_EDUMANUFID`](#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f) {#group__defines_1ga5ef855ed955b00a2239ca16afbeb164f} - diff --git a/docs/internals/input_callback_reg.md b/docs/internals/input_callback_reg.md deleted file mode 100644 index 4ea132a83a84..000000000000 --- a/docs/internals/input_callback_reg.md +++ /dev/null @@ -1,169 +0,0 @@ -# group `input_callback_reg` {#group__input__callback__reg} - -These are the functions you use to register your input callbacks. - -The functions are called when the appropriate midi message is matched on the associated device's input. - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a control change message (cc) callback. -`public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a note on callback. -`public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a note off callback. -`public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register an after touch callback. -`public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a pitch bend callback. -`public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` | Register a song position callback. -`public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a program change callback. -`public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a channel pressure callback. -`public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a song select callback. -`public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` | Register a tc quarter frame callback. -`public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` | Register a realtime callback. -`public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` | Register a tune request callback. -`public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_sysex_func_t func)` | Register a sysex callback. -`public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` | Register fall through callback. -`public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` | Register a catch all callback. - -## Members - -#### `public void `[`midi_register_cc_callback`](#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga64ab672abbbe393c9c4a83110c8df718} - -Register a control change message (cc) callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_noteon_callback`](#group__input__callback__reg_1ga3962f276c17618923f1152779552103e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga3962f276c17618923f1152779552103e} - -Register a note on callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_noteoff_callback`](#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gac847b66051bd6d53b762958be0ec4c6d} - -Register a note off callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_aftertouch_callback`](#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaa95bc901bd9edff956a667c9a69dd01f} - -Register an after touch callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_pitchbend_callback`](#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1ga071a28f02ba14f53de219be70ebd9a48} - -Register a pitch bend callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_songposition_callback`](#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_three_byte_func_t func)` {#group__input__callback__reg_1gaf2adfd79637f3553d8f26deb1ca22ed6} - -Register a song position callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_progchange_callback`](#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gae6ba1a35a4cde9bd15dd42f87401d127} - -Register a program change callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_chanpressure_callback`](#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga39b31f1f4fb93917ce039b958f21b4f5} - -Register a channel pressure callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_songselect_callback`](#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1gaf9aafc76a2dc4b9fdbb4106cbda6ce72} - -Register a song select callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_tc_quarterframe_callback`](#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_two_byte_func_t func)` {#group__input__callback__reg_1ga0a119fada2becc628cb15d753b257e6e} - -Register a tc quarter frame callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_realtime_callback`](#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1ga764f440e857b89084b1a07f9da2ff93a} - -Register a realtime callback. - -The callback will be called for all of the real time message types. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_tunerequest_callback`](#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_one_byte_func_t func)` {#group__input__callback__reg_1gae40ff3ce20bda79fef87da24b8321cb1} - -Register a tune request callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_sysex_callback`](#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_sysex_func_t func)` {#group__input__callback__reg_1ga63ce9631b025785c1848d0122d4c4c48} - -Register a sysex callback. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_fallthrough_callback`](#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga7ed189164aa9682862b3181153afbd94} - -Register fall through callback. - -This is only called if a more specific callback is not matched and called. For instance, if you don't register a note on callback but you get a note on message the fall through callback will be called, if it is registered. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - -#### `public void `[`midi_register_catchall_callback`](#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t func)` {#group__input__callback__reg_1ga9dbfed568d047a6cd05708f11fe39e99} - -Register a catch all callback. - -If registered, the catch all callback is called for every message that is matched, even if a more specific or the fallthrough callback is registered. - -#### Parameters -* `device` the device associate with - -* `func` the callback function to register - diff --git a/docs/internals/midi_device.md b/docs/internals/midi_device.md deleted file mode 100644 index 5b57abd45469..000000000000 --- a/docs/internals/midi_device.md +++ /dev/null @@ -1,143 +0,0 @@ -# group `midi_device` {#group__midi__device} - -You use the functions when you are implementing your own midi device. - -You set a send function to actually send bytes via your device, this method is called when you call a send function with this device, for instance midi_send_cc - -You use the midi_device_input to process input data from the device and pass it through the device's associated callbacks. - -You use the midi_device_set_pre_input_process_func if you want to have a function called at the beginning of the device's process function, generally to poll for input and pass that into midi_device_input - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`define `[`MIDI_INPUT_QUEUE_LENGTH`](#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8) | -`enum `[`input_state_t`](#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621) | -`public void `[`midi_device_input`](#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t cnt,uint8_t * input)` | Process input bytes. This function parses bytes and calls the appropriate callbacks associated with the given device. You use this function if you are creating a custom device and you want to have midi input. -`public void `[`midi_device_set_send_func`](#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t send_func)` | Set the callback function that will be used for sending output data bytes. This is only used if you're creating a custom device. You'll most likely want the callback function to disable interrupts so that you can call the various midi send functions without worrying about locking. -`public void `[`midi_device_set_pre_input_process_func`](#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_no_byte_func_t pre_process_func)` | Set a callback which is called at the beginning of the midi_device_process call. This can be used to poll for input data and send the data through the midi_device_input function. You'll probably only use this if you're creating a custom device. -`struct `[`_midi_device`](docs/api_midi_device.md#struct__midi__device) | This structure represents the input and output functions and processing data for a midi device. - -## Members - -#### `define `[`MIDI_INPUT_QUEUE_LENGTH`](#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8) {#group__midi__device_1ga4aaa419caebdca2bbdfc1331e79781a8} - -#### `enum `[`input_state_t`](#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621) {#group__midi__device_1gac203e877d3df4275ceb8e7180a61f621} - - Values | Descriptions ---------------------------------|--------------------------------------------- -IDLE | -ONE_BYTE_MESSAGE | -TWO_BYTE_MESSAGE | -THREE_BYTE_MESSAGE | -SYSEX_MESSAGE | - -#### `public void `[`midi_device_input`](#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t cnt,uint8_t * input)` {#group__midi__device_1gad8d3db8eb35d9cfa51ef036a0a9d70db} - -Process input bytes. This function parses bytes and calls the appropriate callbacks associated with the given device. You use this function if you are creating a custom device and you want to have midi input. - -#### Parameters -* `device` the midi device to associate the input with - -* `cnt` the number of bytes you are processing - -* `input` the bytes to process - -#### `public void `[`midi_device_set_send_func`](#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_var_byte_func_t send_func)` {#group__midi__device_1ga59f5a46bdd4452f186cc73d9e96d4673} - -Set the callback function that will be used for sending output data bytes. This is only used if you're creating a custom device. You'll most likely want the callback function to disable interrupts so that you can call the various midi send functions without worrying about locking. - -#### Parameters -* `device` the midi device to associate this callback with - -* `send_func` the callback function that will do the sending - -#### `public void `[`midi_device_set_pre_input_process_func`](#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69)`(`[`MidiDevice`](#struct__midi__device)` * device,midi_no_byte_func_t pre_process_func)` {#group__midi__device_1ga4de0841b87c04fc23cb56b6451f33b69} - -Set a callback which is called at the beginning of the midi_device_process call. This can be used to poll for input data and send the data through the midi_device_input function. You'll probably only use this if you're creating a custom device. - -#### Parameters -* `device` the midi device to associate this callback with - -* `midi_no_byte_func_t` the actual callback function - -# struct `_midi_device` {#struct__midi__device} - -This structure represents the input and output functions and processing data for a midi device. - -A device can represent an actual physical device [serial port, usb port] or something virtual. You should not need to modify this structure directly. - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`public midi_var_byte_func_t `[`send_func`](docs/api_midi_device.md#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9) | -`public midi_three_byte_func_t `[`input_cc_callback`](docs/api_midi_device.md#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1) | -`public midi_three_byte_func_t `[`input_noteon_callback`](docs/api_midi_device.md#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c) | -`public midi_three_byte_func_t `[`input_noteoff_callback`](docs/api_midi_device.md#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84) | -`public midi_three_byte_func_t `[`input_aftertouch_callback`](docs/api_midi_device.md#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f) | -`public midi_three_byte_func_t `[`input_pitchbend_callback`](docs/api_midi_device.md#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18) | -`public midi_three_byte_func_t `[`input_songposition_callback`](docs/api_midi_device.md#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586) | -`public midi_two_byte_func_t `[`input_progchange_callback`](docs/api_midi_device.md#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da) | -`public midi_two_byte_func_t `[`input_chanpressure_callback`](docs/api_midi_device.md#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7) | -`public midi_two_byte_func_t `[`input_songselect_callback`](docs/api_midi_device.md#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f) | -`public midi_two_byte_func_t `[`input_tc_quarterframe_callback`](docs/api_midi_device.md#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0) | -`public midi_one_byte_func_t `[`input_realtime_callback`](docs/api_midi_device.md#struct__midi__device_1a9448eba4afb7e43650434748db3777be) | -`public midi_one_byte_func_t `[`input_tunerequest_callback`](docs/api_midi_device.md#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d) | -`public midi_sysex_func_t `[`input_sysex_callback`](docs/api_midi_device.md#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2) | -`public midi_var_byte_func_t `[`input_fallthrough_callback`](docs/api_midi_device.md#struct__midi__device_1abb974ec6d734001b4a0e370f292be503) | -`public midi_var_byte_func_t `[`input_catchall_callback`](docs/api_midi_device.md#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8) | -`public midi_no_byte_func_t `[`pre_input_process_callback`](docs/api_midi_device.md#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754) | -`public uint8_t `[`input_buffer`](docs/api_midi_device.md#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a) | -`public input_state_t `[`input_state`](docs/api_midi_device.md#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39) | -`public uint16_t `[`input_count`](docs/api_midi_device.md#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d) | -`public uint8_t `[`input_queue_data`](docs/api_midi_device.md#struct__midi__device_1ada41de021135dc423abedcbb30f366ff) | -`public `[`byteQueue_t`](#structbyte_queue__t)` `[`input_queue`](#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f) | - -## Members - -#### `public midi_var_byte_func_t `[`send_func`](docs/api_midi_device.md#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9) {#struct__midi__device_1a25d4c94b4bbccd5b98f1032b469f3ff9} - -#### `public midi_three_byte_func_t `[`input_cc_callback`](docs/api_midi_device.md#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1) {#struct__midi__device_1a6da5236c1bc73877728df92d213a78d1} - -#### `public midi_three_byte_func_t `[`input_noteon_callback`](docs/api_midi_device.md#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c) {#struct__midi__device_1aa10b15cf1a7fb825a5df0d2abbe34a1c} - -#### `public midi_three_byte_func_t `[`input_noteoff_callback`](docs/api_midi_device.md#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84) {#struct__midi__device_1aaf290043078534d3a5a0ea4c840eba84} - -#### `public midi_three_byte_func_t `[`input_aftertouch_callback`](docs/api_midi_device.md#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f) {#struct__midi__device_1acb0b4901c545cec4b28b126f2d8c315f} - -#### `public midi_three_byte_func_t `[`input_pitchbend_callback`](docs/api_midi_device.md#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18) {#struct__midi__device_1a305fea672caeb996f2233bf8cd2bef18} - -#### `public midi_three_byte_func_t `[`input_songposition_callback`](docs/api_midi_device.md#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586) {#struct__midi__device_1a5f3f13638b3fef3fc561ed1bf301d586} - -#### `public midi_two_byte_func_t `[`input_progchange_callback`](docs/api_midi_device.md#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da) {#struct__midi__device_1adaf1da617c9a10a9dcad00ab1959d3da} - -#### `public midi_two_byte_func_t `[`input_chanpressure_callback`](docs/api_midi_device.md#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7) {#struct__midi__device_1ab7ca2925c539915d43974eff604d85f7} - -#### `public midi_two_byte_func_t `[`input_songselect_callback`](docs/api_midi_device.md#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f) {#struct__midi__device_1a89bed8a5a55376120cfc0a62b42f057f} - -#### `public midi_two_byte_func_t `[`input_tc_quarterframe_callback`](docs/api_midi_device.md#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0) {#struct__midi__device_1ad9813e75d22e284f9f65a907d20600f0} - -#### `public midi_one_byte_func_t `[`input_realtime_callback`](docs/api_midi_device.md#struct__midi__device_1a9448eba4afb7e43650434748db3777be) {#struct__midi__device_1a9448eba4afb7e43650434748db3777be} - -#### `public midi_one_byte_func_t `[`input_tunerequest_callback`](docs/api_midi_device.md#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d) {#struct__midi__device_1a0cb8fd53e00cf1d4202d4fa04d038e8d} - -#### `public midi_sysex_func_t `[`input_sysex_callback`](docs/api_midi_device.md#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2) {#struct__midi__device_1afff9a0ce641762aaef24c1e6953ec9a2} - -#### `public midi_var_byte_func_t `[`input_fallthrough_callback`](docs/api_midi_device.md#struct__midi__device_1abb974ec6d734001b4a0e370f292be503) {#struct__midi__device_1abb974ec6d734001b4a0e370f292be503} - -#### `public midi_var_byte_func_t `[`input_catchall_callback`](docs/api_midi_device.md#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8) {#struct__midi__device_1aae0d535129d4fd650edc98eb3f7584f8} - -#### `public midi_no_byte_func_t `[`pre_input_process_callback`](docs/api_midi_device.md#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754) {#struct__midi__device_1aeb0bb8923d66c23d874e177dc4265754} - -#### `public uint8_t `[`input_buffer`](docs/api_midi_device.md#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a) {#struct__midi__device_1a7c5684857d6af4ebc4dc12da27bd6b2a} - -#### `public input_state_t `[`input_state`](docs/api_midi_device.md#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39) {#struct__midi__device_1a69a687d2d1c449ec15a11c07a5722e39} - -#### `public uint16_t `[`input_count`](docs/api_midi_device.md#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d) {#struct__midi__device_1a68dea8e7b6151e89c85c95caa612ee5d} - -#### `public uint8_t `[`input_queue_data`](docs/api_midi_device.md#struct__midi__device_1ada41de021135dc423abedcbb30f366ff) {#struct__midi__device_1ada41de021135dc423abedcbb30f366ff} - -#### `public `[`byteQueue_t`](#structbyte_queue__t)` `[`input_queue`](#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f) {#struct__midi__device_1a49c8538a8a02193c58e28a56eb695d8f} - diff --git a/docs/internals/midi_device_setup_process.md b/docs/internals/midi_device_setup_process.md deleted file mode 100644 index ae82197c5c83..000000000000 --- a/docs/internals/midi_device_setup_process.md +++ /dev/null @@ -1,31 +0,0 @@ -# group `midi_device_setup_process` {#group__midi__device__setup__process} - -These are method that you must use to initialize and run a device. - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`public void `[`midi_device_init`](#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Initialize a device. -`public void `[`midi_device_process`](#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Process input data. - -## Members - -#### `public void `[`midi_device_init`](#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__midi__device__setup__process_1gaf29deddc94ea98a59daa0bde1aefd9d9} - -Initialize a device. - -You must call this before using the device in question. - -#### Parameters -* `device` the device to initialize - -#### `public void `[`midi_device_process`](#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__midi__device__setup__process_1gaa3d5993d0e998a1b59bbf5ab9c7b492b} - -Process input data. - -This method drives the input processing, you must call this method frequently if you expect to have your input callbacks called. - -#### Parameters -* `device` the device to process - diff --git a/docs/internals/midi_util.md b/docs/internals/midi_util.md deleted file mode 100644 index 97821bd18063..000000000000 --- a/docs/internals/midi_util.md +++ /dev/null @@ -1,54 +0,0 @@ -# group `midi_util` {#group__midi__util} - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`enum `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e) | An enumeration of the possible packet length values. -`public bool `[`midi_is_statusbyte`](#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5)`(uint8_t theByte)` | Test to see if the byte given is a status byte. -`public bool `[`midi_is_realtime`](#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7)`(uint8_t theByte)` | Test to see if the byte given is a realtime message. -`public `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e)` `[`midi_packet_length`](#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175)`(uint8_t status)` | Find the length of the packet associated with the status byte given. - -## Members - -#### `enum `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e) {#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e} - - Values | Descriptions ---------------------------------|--------------------------------------------- -UNDEFINED | -ONE | -TWO | -THREE | - -An enumeration of the possible packet length values. - -#### `public bool `[`midi_is_statusbyte`](#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5)`(uint8_t theByte)` {#group__midi__util_1ga12e3b42ff9cbb4b4f2bc455fc8743ee5} - -Test to see if the byte given is a status byte. - -#### Parameters -* `theByte` the byte to test - -#### Returns -true if the byte given is a midi status byte - -#### `public bool `[`midi_is_realtime`](#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7)`(uint8_t theByte)` {#group__midi__util_1gad2f52c363e34a8000d80c983c324e2d7} - -Test to see if the byte given is a realtime message. - -#### Parameters -* `theByte` the byte to test - -#### Returns -true if it is a realtime message, false otherwise - -#### `public `[`midi_packet_length_t`](#group__midi__util_1gae29ff56aee2b430ffe53933b97e5e79e)` `[`midi_packet_length`](#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175)`(uint8_t status)` {#group__midi__util_1gaa168b43af6ae9de0debce1625e4b8175} - -Find the length of the packet associated with the status byte given. - -#### Parameters -* `status` the status byte - -#### Returns -the length of the packet, will return UNDEFINED if the byte is not a status byte or if it is a sysex status byte - diff --git a/docs/internals/send_functions.md b/docs/internals/send_functions.md deleted file mode 100644 index b331508008a5..000000000000 --- a/docs/internals/send_functions.md +++ /dev/null @@ -1,241 +0,0 @@ -# group `send_functions` {#group__send__functions} - -These are the functions you use to send midi data through a device. - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`public void `[`midi_send_cc`](#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t val)` | Send a control change message (cc) via the given device. -`public void `[`midi_send_noteon`](#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` | Send a note on message via the given device. -`public void `[`midi_send_noteoff`](#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` | Send a note off message via the given device. -`public void `[`midi_send_aftertouch`](#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t note_num,uint8_t amt)` | Send an after touch message via the given device. -`public void `[`midi_send_pitchbend`](#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,int16_t amt)` | Send a pitch bend message via the given device. -`public void `[`midi_send_programchange`](#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num)` | Send a program change message via the given device. -`public void `[`midi_send_channelpressure`](#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t amt)` | Send a channel pressure message via the given device. -`public void `[`midi_send_clock`](#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a clock message via the given device. -`public void `[`midi_send_tick`](#group__send__functions_1ga2b43c7d433d940c5b907595aac947972)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a tick message via the given device. -`public void `[`midi_send_start`](#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a start message via the given device. -`public void `[`midi_send_continue`](#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a continue message via the given device. -`public void `[`midi_send_stop`](#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a stop message via the given device. -`public void `[`midi_send_activesense`](#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send an active sense message via the given device. -`public void `[`midi_send_reset`](#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a reset message via the given device. -`public void `[`midi_send_tcquarterframe`](#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t time)` | Send a tc quarter frame message via the given device. -`public void `[`midi_send_songposition`](#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t pos)` | Send a song position message via the given device. -`public void `[`midi_send_songselect`](#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t song)` | Send a song select message via the given device. -`public void `[`midi_send_tunerequest`](#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656)`(`[`MidiDevice`](#struct__midi__device)` * device)` | Send a tune request message via the given device. -`public void `[`midi_send_byte`](#group__send__functions_1ga857e85eb90b288385642d4d991e09881)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t b)` | Send a byte via the given device. -`public void `[`midi_send_data`](#group__send__functions_1ga36e2f2e45369d911b76969361679054b)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t count,uint8_t byte0,uint8_t byte1,uint8_t byte2)` | Send up to 3 bytes of data. -`public void `[`midi_send_array`](#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t count,uint8_t * array)` | Send an array of formatted midi data. - -## Members - -#### `public void `[`midi_send_cc`](#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t val)` {#group__send__functions_1gaaf884811c92df405ca8fe1a00082f960} - -Send a control change message (cc) via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `num` the cc num - -* `val` the value of that cc num - -#### `public void `[`midi_send_noteon`](#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` {#group__send__functions_1ga467bcf46dbf03ec269ce565b46bc2775} - -Send a note on message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `num` the note number - -* `vel` the note velocity - -#### `public void `[`midi_send_noteoff`](#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num,uint8_t vel)` {#group__send__functions_1gaedb7d8805425eef5d47d57ddcb4c7a49} - -Send a note off message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `num` the note number - -* `vel` the note velocity - -#### `public void `[`midi_send_aftertouch`](#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t note_num,uint8_t amt)` {#group__send__functions_1ga0014847571317a0e34b2ef46a6bc584f} - -Send an after touch message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `note_num` the note number - -* `amt` the after touch amount - -#### `public void `[`midi_send_pitchbend`](#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,int16_t amt)` {#group__send__functions_1gae5a4a1e71611e7534be80af9ce3d3491} - -Send a pitch bend message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `amt` the bend amount range: -8192..8191, 0 means no bend - -#### `public void `[`midi_send_programchange`](#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t num)` {#group__send__functions_1ga7b15588ef25e5e1ff09c2afc3151ce86} - -Send a program change message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `num` the program to change to - -#### `public void `[`midi_send_channelpressure`](#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t chan,uint8_t amt)` {#group__send__functions_1gaf23e69fdf812e89c0036f51f88ab2e1b} - -Send a channel pressure message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `chan` the channel to send on, 0-15 - -* `amt` the amount of channel pressure - -#### `public void `[`midi_send_clock`](#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga4e1b11a7cdb0875f6e03ce7c79c581aa} - -Send a clock message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_tick`](#group__send__functions_1ga2b43c7d433d940c5b907595aac947972)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga2b43c7d433d940c5b907595aac947972} - -Send a tick message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_start`](#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga1569749a8d58ccc56789289d7c7245cc} - -Send a start message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_continue`](#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1gaed5dc29d754a27372e89ab8bc20ee120} - -Send a continue message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_stop`](#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga026e1a620276cb653ac501aa0d12a988} - -Send a stop message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_activesense`](#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga9b6e4c6ce4719d2604187b325620db37} - -Send an active sense message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_reset`](#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga3671e39a6d93ca9568fc493001af1b1b} - -Send a reset message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_tcquarterframe`](#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t time)` {#group__send__functions_1ga5b85639910eec280bb744c934d0fd45a} - -Send a tc quarter frame message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `time` the time of this quarter frame, range 0..16383 - -#### `public void `[`midi_send_songposition`](#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t pos)` {#group__send__functions_1gab1c9eeef3b57a8cd2e6128d18e85eb7f} - -Send a song position message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `pos` the song position - -#### `public void `[`midi_send_songselect`](#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t song)` {#group__send__functions_1ga42de7838ba70d949af9a50f9facc3c50} - -Send a song select message via the given device. - -#### Parameters -* `device` the device to use for sending - -* `song` the song to select - -#### `public void `[`midi_send_tunerequest`](#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656)`(`[`MidiDevice`](#struct__midi__device)` * device)` {#group__send__functions_1ga8db6c7e04d48e4d2266dd59118ca0656} - -Send a tune request message via the given device. - -#### Parameters -* `device` the device to use for sending - -#### `public void `[`midi_send_byte`](#group__send__functions_1ga857e85eb90b288385642d4d991e09881)`(`[`MidiDevice`](#struct__midi__device)` * device,uint8_t b)` {#group__send__functions_1ga857e85eb90b288385642d4d991e09881} - -Send a byte via the given device. - -This is a generic method for sending data via the given midi device. This would be useful for sending sysex data or messages that are not implemented in this API, if there are any. Please contact the author if you find some so we can add them. - -#### Parameters -* `device` the device to use for sending - -* `b` the byte to send - -#### `public void `[`midi_send_data`](#group__send__functions_1ga36e2f2e45369d911b76969361679054b)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t count,uint8_t byte0,uint8_t byte1,uint8_t byte2)` {#group__send__functions_1ga36e2f2e45369d911b76969361679054b} - -Send up to 3 bytes of data. - -% 4 is applied to count so that you can use this to pass sysex through - -#### Parameters -* `device` the device to use for sending - -* `count` the count of bytes to send, %4 is applied - -* `byte0` the first byte - -* `byte1` the second byte, ignored if cnt % 4 != 2 - -* `byte2` the third byte, ignored if cnt % 4 != 3 - -#### `public void `[`midi_send_array`](#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead)`(`[`MidiDevice`](#struct__midi__device)` * device,uint16_t count,uint8_t * array)` {#group__send__functions_1ga245243cb1da18d2cea18d4b18d846ead} - -Send an array of formatted midi data. - -Can be used for sysex. - -#### Parameters -* `device` the device to use for sending - -* `count` the count of bytes to send - -* `array` the array of bytes - diff --git a/docs/internals/sysex_tools.md b/docs/internals/sysex_tools.md deleted file mode 100644 index 55dbe9e16443..000000000000 --- a/docs/internals/sysex_tools.md +++ /dev/null @@ -1,61 +0,0 @@ -# group `sysex_tools` {#group__sysex__tools} - -## Summary - - Members | Descriptions ---------------------------------|--------------------------------------------- -`public uint16_t `[`sysex_encoded_length`](#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a)`(uint16_t decoded_length)` | Compute the length of a message after it is encoded. -`public uint16_t `[`sysex_decoded_length`](#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0)`(uint16_t encoded_length)` | Compute the length of a message after it is decoded. -`public uint16_t `[`sysex_encode`](#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742)`(uint8_t * encoded,const uint8_t * source,uint16_t length)` | Encode data so that it can be transmitted safely in a sysex message. -`public uint16_t `[`sysex_decode`](#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229)`(uint8_t * decoded,const uint8_t * source,uint16_t length)` | Decode encoded data. - -## Members - -#### `public uint16_t `[`sysex_encoded_length`](#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a)`(uint16_t decoded_length)` {#group__sysex__tools_1ga061e5607030412d6e62e2390d8013f0a} - -Compute the length of a message after it is encoded. - -#### Parameters -* `decoded_length` The length, in bytes, of the message to encode. - -#### Returns -The length, in bytes, of the message after encodeing. - -#### `public uint16_t `[`sysex_decoded_length`](#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0)`(uint16_t encoded_length)` {#group__sysex__tools_1ga121fc227d3acc1c0ea08c9a5c26fa3b0} - -Compute the length of a message after it is decoded. - -#### Parameters -* `encoded_length` The length, in bytes, of the encoded message. - -#### Returns -The length, in bytes, of the message after it is decoded. - -#### `public uint16_t `[`sysex_encode`](#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742)`(uint8_t * encoded,const uint8_t * source,uint16_t length)` {#group__sysex__tools_1ga54d77f8d32f92a6f329daefa2b314742} - -Encode data so that it can be transmitted safely in a sysex message. - -#### Parameters -* `encoded` The output data buffer, must be at least sysex_encoded_length(length) bytes long. - -* `source` The input buffer of data to be encoded. - -* `length` The number of bytes from the input buffer to encode. - -#### Returns -number of bytes encoded. - -#### `public uint16_t `[`sysex_decode`](#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229)`(uint8_t * decoded,const uint8_t * source,uint16_t length)` {#group__sysex__tools_1gaaad1d9ba2d5eca709a0ab4ba40662229} - -Decode encoded data. - -#### Parameters -* `decoded` The output data buffer, must be at least sysex_decoded_length(length) bytes long. - -* `source` The input buffer of data to be decoded. - -* `length` The number of bytes from the input buffer to decode. - -#### Returns -number of bytes decoded. - diff --git a/docs/isp_flashing_guide.md b/docs/isp_flashing_guide.md deleted file mode 100644 index 80fd1ddda125..000000000000 --- a/docs/isp_flashing_guide.md +++ /dev/null @@ -1,387 +0,0 @@ -# ISP Flashing Guide - -In order to flash a microcontroller over USB, it needs something called a bootloader. This bootloader lives in a specific section of the flash memory, and allows you to load the actual application firmware (in this case, QMK) into the rest of the flash. - -However, it can sometimes happen that the bootloader becomes corrupted and needs reflashing, or you may want to change the bootloader to another one. It's not possible to do this with the existing bootloader, because, of course, it is already running, and cannot overwrite itself. Instead, you will need to ISP flash the microcontroller. - -There are several different kinds of bootloaders available for AVR microcontrollers. Most STM32 ARM-based microcontrollers already have a USB-capable bootloader in ROM, so generally do not need to be ISP flashed. The one current exception is the [STM32F103](#flashing-stm32duino-bootloader). - -## Hardware - -One of the following devices is required to perform the ISP flashing. The product links are to the official versions, however you can certainly source them elsewhere. - -You'll also need some jumper wires to connect the ISP flasher and the target board. Some boards have an ISP header with the necessary pins broken out. If not, then you will need to temporarily solder the wires to the PCB -- usually to switch pins or directly to the MCU. -The wiring is fairly straightforward; for the most part, you'll be connecting like to like. Refer to the target MCU's datasheet for the exact `RESET`, `SCLK`, `MOSI` and `MISO` pins. - -### Pro Micro as ISP - -[SparkFun Pro Micro](https://www.sparkfun.com/products/12640) - -To use a 5V/16MHz Pro Micro as an ISP flashing tool, you will first need to load a [special firmware](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) onto it that emulates a hardware ISP flasher. - -**AVRDUDE Programmer**: `avrisp` -**AVRDUDE Port**: Serial - -#### Wiring - -|Pro Micro |Keyboard| -|-----------|--------| -|`VCC` |`VCC` | -|`GND` |`GND` | -|`10` (`B6`)|`RESET` | -|`15` (`B1`)|`SCLK` | -|`16` (`B2`)|`MOSI` | -|`14` (`B3`)|`MISO` | - -!> Note that the `10` pin on the Pro Micro should be wired to the `RESET` pin on the keyboard's controller. ***DO NOT*** connect the `RESET` pin on the Pro Micro to the `RESET` on the keyboard. - - -### Arduino Uno / Micro as ISP - -[Arduino Uno](https://store.arduino.cc/products/arduino-uno-rev3) -[Arduino Micro](https://store.arduino.cc/products/arduino-micro) - -A standard Uno or Micro can be used as an ISP flashing tool using the [example "ArduinoISP" sketch](https://docs.arduino.cc/built-in-examples/arduino-isp/ArduinoISP#load-the-sketch) to emulate an STK500 ISP. Also works with Sparkfun Pro Micros and clones. - -**AVRDUDE Programmer**: `stk500v1` -**AVRDUDE Port**: Serial - -#### Wiring - -|Uno |Keyboard| -|-----------|--------| -|`5V` |`VCC` | -|`GND` |`GND` | -|`10` (`B2`)|`RESET` | -|`13` (`B5`)|`SCLK` | -|`11` (`B3`)|`MOSI` | -|`12` (`B4`)|`MISO` | - -|Micro |Keyboard| -|-----------|--------| -|`5V` |`VCC` | -|`GND` |`GND` | -|`10` (`B6`)|`RESET` | -|`15` (`B1`)|`SCLK` | -|`16` (`B2`)|`MOSI` | -|`14` (`B3`)|`MISO` | - -!> Note that the `10` pin on the Uno/Micro should be wired to the `RESET` pin on the keyboard's controller. ***DO NOT*** connect the `RESET` pin on the Uno/Micro to the `RESET` on the keyboard. - - -### Teensy 2.0 as ISP - -[PJRC Teensy 2.0](https://www.pjrc.com/store/teensy.html) - -To use a Teensy 2.0 as an ISP flashing tool, you will first need to load a [special firmware](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) onto it that emulates a hardware ISP flasher. - -**AVRDUDE Programmer**: `avrisp` -**AVRDUDE Port**: Serial - -#### Wiring - -|Teensy|Keyboard| -|------|--------| -|`VCC` |`VCC` | -|`GND` |`GND` | -|`B0` |`RESET` | -|`B1` |`SCLK` | -|`B2` |`MOSI` | -|`B3` |`MISO` | - -!> Note that the `B0` pin on the Teensy should be wired to the `RESET` pin on the keyboard's controller. ***DO NOT*** connect the `RESET` pin on the Teensy to the `RESET` on the keyboard. - - -### SparkFun PocketAVR / USBtinyISP - -[SparkFun PocketAVR](https://www.sparkfun.com/products/9825) -[Adafruit USBtinyISP](https://www.adafruit.com/product/46) - -!> SparkFun PocketAVR and USBtinyISP **DO NOT support** AVR chips with more than 64 KiB of flash (e.g., the AT90USB128 series). This limitation is mentioned on the [shop page for SparkFun PocketAVR](https://www.sparkfun.com/products/9825) and in the [FAQ for USBtinyISP](https://learn.adafruit.com/usbtinyisp/f-a-q#faq-2270879). If you try to use one of these programmers with AT90USB128 chips, you will get verification errors from `avrdude`, and the bootloader won't be flashed properly (e.g., see the [issue #3286](https://github.com/qmk/qmk_firmware/issues/3286)). - -**AVRDUDE Programmer**: `usbtiny` -**AVRDUDE Port**: `usb` - -#### Wiring - -|ISP |Keyboard| -|---------|--------| -|`VCC` |`VCC` | -|`GND` |`GND` | -|`RST` |`RESET` | -|`SCLK` |`SCLK` | -|`MOSI` |`MOSI` | -|`MISO` |`MISO` | - - -### USBasp - -[Thomas Fischl's USBasp](https://www.fischl.de/usbasp/) - -**AVRDUDE Programmer**: `usbasp` -**AVRDUDE Port**: `usb` - -#### Wiring - -|ISP |Keyboard| -|---------|--------| -|`VCC` |`VCC` | -|`GND` |`GND` | -|`RST` |`RESET` | -|`SCLK` |`SCLK` | -|`MOSI` |`MOSI` | -|`MISO` |`MISO` | - - -### Bus Pirate - -[Adafruit Bus Pirate](https://www.adafruit.com/product/237) - -!> The 5-pin "ICSP" header is for ISP flashing the PIC microcontroller of the Bus Pirate. Connect your target board to the 10-pin header opposite the USB connector instead. - -**AVRDUDE Programmer**: `buspirate` -**AVRDUDE Port**: Serial - -#### Wiring - -|Bus Pirate|Keyboard| -|----------|--------| -|`+5V` |`VCC` | -|`GND` |`GND` | -|`RST` |`RESET` | -|`CLK` |`SCLK` | -|`MOSI` |`MOSI` | -|`MISO` |`MISO` | - -## Software - -[QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) supports flashing both the ISP firmware and bootloader, but note that it cannot (currently) set the AVR fuse bytes for the actual ISP flashing step, so you may want to work with `avrdude` directly instead. - -Setting up the [QMK environment](newbs.md) is highly recommended, as it automatically installs `avrdude` along with a host of other tools. - -## Bootloader Firmware - -One of these files is what you will be ISP flashing onto the board. The default fuses are also listed. - -If you're not sure what your board uses, look in the `rules.mk` file for the keyboard in QMK. The `MCU` and `BOOTLOADER` lines will have the values you need. It may differ between different versions of the board. - -### Atmel DFU - -These are the [factory default bootloaders](https://www.microchip.com/content/dam/mchp/documents/OTH/ProductDocuments/SoftwareLibraries/Firmware/megaUSB_DFU_Bootloaders.zip) shipped by Atmel (now Microchip). Note that the AT90USB64 and AT90USB128 bootloaders are [slightly modified](https://github.com/qmk/qmk_firmware/pull/14064), due to a bug causing them to not enumerate properly in Windows 8 and later. - -|MCU |Low |High |Extended|USB ID | -|--------------------------------------------------------------------------------------------------|------|-------------------------------|--------|-----------| -|[ATmega16U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega16u4_1.0.1.hex)|`0x5E`|`0x99` / `0xD9` (JTAG disabled)|`0xF3` |`03EB:2FF3`| -|[ATmega32U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1.0.0.hex)|`0x5E`|`0x99` / `0xD9` (JTAG disabled)|`0xF3` |`03EB:2FF4`| -|[AT90USB64](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb64_1.0.0.hex) |`0x5E`|`0x9B` / `0xDB` (JTAG disabled)|`0xF3` |`03EB:2FF9`| -|[AT90USB128](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128_1.0.1.hex)|`0x5E`|`0x99` / `0xD9` (JTAG disabled)|`0xF3` |`03EB:2FFB`| - -### Caterina - -This is the default Arduino-style bootloader derived from the [LUFA CDC bootloader](https://github.com/abcminiuser/lufa/tree/master/Bootloaders/CDC), and is only for the ATmega32U4. - -There are several variants depending on the vendor, but they all mostly work the same way. The SparkFun variants, for example, require the `RESET` pin to be [grounded twice quickly](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide#ts-reset) in order to stay in bootloader mode for more than 750 ms. - -|MCU |Low |High |Extended|USB ID | -|-----------------------------------------------------------------------------------------------------------------------------------------------------------------|------|------|--------|-----------| -|[SparkFun Pro Micro (3V3/8MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro8.hex) |`0xFF`|`0xD8`|`0xFE` |`1B4F:9203`| -|[SparkFun Pro Micro (5V/16MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro16.hex) |`0xFF`|`0xD8`|`0xFB` |`1B4F:9205`| -|[SparkFun LilyPadUSB (and some Pro Micro clones)](https://github.com/sparkfun/Arduino_Boards/blob/main/sparkfun/avr/bootloaders/caterina/Caterina-lilypadusb.hex)|`0xFF`|`0xD8`|`0xFE` |`1B4F:9207`| -|[Pololu A-Star 32U4](https://github.com/pololu/a-star/blob/master/bootloaders/caterina/Caterina-A-Star.hex)* |`0xFF`|`0xD0`|`0xF8` |`1FFB:0101`| -|[Adafruit Feather 32U4](https://github.com/adafruit/Caterina-Bootloader/blob/master/Built%20Firmwares/Caterina-Feather32u4.hex) |`0xFF`|`0xD8`|`0xFB` |`239A:000C`| -|[Adafruit ItsyBitsy 32U4 (3V3/8MHz)](https://github.com/adafruit/Caterina-Bootloader/blob/master/Caterina_itsybitsy3V.hex)* |`0xFF`|`0xD8`|`0xFB` |`239A:000D`| -|[Adafruit ItsyBitsy 32U4 (5V/16MHz)](https://github.com/adafruit/Caterina-Bootloader/blob/master/Caterina_itsybitsy5V.hex) |`0xFF`|`0xD8`|`0xFB` |`239A:000E`| -|[Arduino Leonardo](https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/caterina/Caterina-Leonardo.hex)* |`0xFF`|`0xD8`|`0xFB` |`2341:0036`| -|[Arduino Micro](https://github.com/arduino/ArduinoCore-avr/blob/master/bootloaders/caterina/Caterina-Micro.hex)* |`0xFF`|`0xD8`|`0xFB` |`2341:0037`| - -?> Files marked with a * have combined Arduino sketches, which runs by default and also appears as a serial port. However, this is *not* the bootloader device. - -### BootloadHID (PS2AVRGB) - -This bootloader is primarily for keyboards originally designed for the PS2AVRGB firmware and Bootmapper Client. It is not recommended for use in new designs. - -|MCU |Low |High |USB ID | -|-----------------------------------------------------------------------------------------------------------|------|------|-----------| -|[ATmega32A](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_ps2avrgb_bootloadhid_1.0.1.hex)|`0x0F`|`0xD0`|`16C0:05DF`| - -### USBaspLoader - -USBaspLoader is a bootloader based on V-USB that emulates a hardware USBasp device. It runs on ATmega32A and ATmega328P MCUs. - -Precompiled `.hex` files are generally not available, but you can compile it yourself by setting up the QMK environment and following Coseyfannitutti's guide for the appropriate MCU: - -|MCU |Low |High |Extended|USB ID | -|-------------------------------------------------------------------------------------|------|------|--------|-----------| -|[ATmega32A](https://github.com/coseyfannitutti/discipline/tree/master/doc/bootloader)|`0x1F`|`0xC0`|*n/a* |`16C0:05DC`| -|[ATmega328P](https://github.com/coseyfannitutti/discipad/tree/master/doc/bootloader) |`0xD7`|`0xD0`|`0x04` |`16C0:05DC`| - -Note that some boards may have their own specialized build of this bootloader in a separate repository. This will usually be linked to in the board's readme. - -## Flashing the Bootloader - -Open a new Terminal window - if you are on Windows, use MSYS2 or QMK MSYS, not the Command Prompt. Navigate to the directory your bootloader `.hex` is in. Now it's time to run the `avrdude` command. - -The syntax of `avrdude` is: - -``` -avrdude -c -P -p -U flash:w::i -``` - - * `` corresponds to the programmer type listed for each ISP flasher in the [Hardware](#hardware) section, for example `avrisp`. - * `` is the serial port that appears when you plug the ISP flasher in, if any. For some programmers this is simply `usb` (or you can omit the `-P` argument completely) since they do not operate as a serial device. - * Windows: `COMx` - check Device Manager, under the "Ports (COM & LPT)" section - * Linux: `/dev/ttyACMx` - * macOS: `/dev/tty.usbmodemXXXXXX` - * `` should be the lowercase name of the target AVR microcontroller, for example `atmega32u4`. - * `` is the absolute or relative path to the bootloader to be flashed, for example `Caterina-Micro.hex`. - -You can also run `man avrdude` for more information. - -If all goes well, you should get output similar to the following: - -``` -avrdude: AVR device initialized and ready to accept instructions - -Reading | ################################################## | 100% 0.00s - -avrdude: Device signature = 0x1e9587 (probably m32u4) -avrdude: NOTE: "flash" memory has been specified, an erase cycle will be performed - To disable this feature, specify the -D option. -avrdude: erasing chip -avrdude: reading input file "Caterina-Micro.hex" -avrdude: writing flash (32730 bytes): - -Writing | ################################################## | 100% 11.58s - -avrdude: 32730 bytes of flash written -avrdude: verifying flash memory against Caterina-Micro.hex: -avrdude: load data flash data from input file Caterina-Micro.hex: -avrdude: input file Caterina-Micro.hex contains 32730 bytes -avrdude: reading on-chip flash data: - -Reading | ################################################## | 100% 10.33s - -avrdude: verifying ... -avrdude: 32730 bytes of flash verified - -avrdude: safemode: Fuses OK (E:CB, H:D8, L:FF) - -avrdude done. Thank you. -``` - -### Setting the Fuses - -This is a slightly more advanced topic, but may be necessary if you are switching from one bootloader to another (for example, Caterina to Atmel/QMK DFU on a Pro Micro). Fuses control some of the low-level functionality of the AVR microcontroller, such as clock speed, whether JTAG is enabled, and the size of the section of flash memory reserved for the bootloader, among other things. You can find a fuse calculator for many AVR parts [here](https://www.engbedded.com/conffuse/). - -!> **WARNING:** Setting incorrect fuse values, in particular the clock-related bits, may render the MCU practically unrecoverable without high voltage programming (not covered here)! Make sure to double check the commands you enter before you execute them. - -To set the fuses, add the following to the `avrdude` command: - -``` --U lfuse:w:0xXX:m -U hfuse:w:0xXX:m -U efuse:w:0xXX:m -``` - -where the `lfuse`, `hfuse` and `efuse` arguments represent the low, high and extended fuse bytes as listed in the [Hardware](#hardware) section. - -?> You may get a warning from `avrdude` that the extended fuse byte does not match what you provided when reading it back. If the second hex digit matches, this can usually be safely ignored, because the top four bits of this fuse do not actually exist on many AVR parts, and may read back as anything. - -## Creating a "Production" Firmware - -For mass production purposes, it is possible to join the bootloader and QMK firmware together into a single file, due to the way the [Intel Hex format](https://en.wikipedia.org/wiki/Intel_HEX) works: - - 1. Open the QMK firmware and bootloader `.hex` files in a text editor. - 2. Remove the last line of the QMK firmware (which should be `:00000001FF` - this is just an "end of file" marker). - 3. Paste the contents of the bootloader `.hex` file onto a new line at the end of the QMK firmware file, with no empty lines between. - 4. Save it as a new file, for example `__production.hex`. - -You can then ISP flash this combined firmware instead, which allows you to skip the extra step of flashing the QMK firmware over USB. - -## Flashing STM32Duino Bootloader - -As mentioned above, *most* supported STM32 devices already possess a USB DFU bootloader which cannot be overwritten, however the ROM bootloader in the STM32F103 used on the Bluepill is not USB capable. In this case an ST-Link V2 dongle is required to upload the STM32Duino bootloader to the device. These can be readily purchased for relatively cheap on eBay and other places. - -This bootloader is a descendant of the Maple bootloader by Leaflabs, and is compatible with dfu-util. - -### Software - -To communicate with the ST-Link, you must install the following packages: - -* **macOS:** `brew install stlink openocd` -* **Windows (MSYS2):** `pacman -S mingw-w64-x86_64-stlink mingw-w64-x86_64-openocd` -* **Linux:** will vary by distribution, but will likely be `stlink` and `openocd` through your particular package manager - -Additionally, you may need to update the ST-Link's firmware with the [`STSW-LINK007`](https://www.st.com/en/development-tools/stsw-link007.html) application. Note you will be asked to provide your name and email address if you do not have an ST.com account (this does not create one). - -Finally, the bootloader binary itself can be downloaded from [here](https://github.com/rogerclarkmelbourne/STM32duino-bootloader/blob/master/bootloader_only_binaries/generic_boot20_pc13.bin). - -### Wiring - -Connect the four-pin header on the end of the Bluepill to the matching pins on the ST-Link (the pinout will usually be printed on the side): - -|ST-Link |Bluepill| -|-------------|--------| -|`GND` (6) |`GND` | -|`SWCLK` (2) |`DCLK` | -|`SWDIO` (4) |`DIO` | -|`3.3V` (8) |`3.3` | - -### Flashing - -Firstly, make sure both jumpers on the Bluepill are set to 0. - -Check that the ST-Link can talk to the Bluepill by running `st-info --probe`: - -``` -Found 1 stlink programmers - version: V2J37S7 - serial: 2C1219002B135937334D4E00 - flash: 65536 (pagesize: 1024) - sram: 20480 - chipid: 0x0410 - descr: F1xx Medium-density -``` - -If the reported `chipid` is `0x0410`, everything is working. If it is `0x0000`, check your wiring, and try swapping the `SWDIO` and `SWCLK` pins, as some ST-Link dongles may have incorrect pinouts. - -Next, run the following command: - -``` -st-flash --reset --format binary write 0x08000000 -``` - -where `` is the path to the bootloader `.bin` file above. You can run this command from the directory you downloaded it to, so that you can simply pass in the filename. - -If all goes well, you should get output similar to the following: - -``` -st-flash 1.7.0 -2022-03-08T12:16:30 INFO common.c: F1xx Medium-density: 20 KiB SRAM, 64 KiB flash in at least 1 KiB pages. -file generic_boot20_pc13.bin md5 checksum: 333c30605e739ce9bedee5999fdaf81b, stlink checksum: 0x0008e534 -2022-03-08T12:16:30 INFO common.c: Attempting to write 7172 (0x1c04) bytes to stm32 address: 134217728 (0x8000000) -2022-03-08T12:16:30 INFO common.c: Flash page at addr: 0x08000000 erased -2022-03-08T12:16:30 INFO common.c: Flash page at addr: 0x08000400 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08000800 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08000c00 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08001000 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08001400 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08001800 erased -2022-03-08T12:16:31 INFO common.c: Flash page at addr: 0x08001c00 erased -2022-03-08T12:16:31 INFO common.c: Finished erasing 8 pages of 1024 (0x400) bytes -2022-03-08T12:16:31 INFO common.c: Starting Flash write for VL/F0/F3/F1_XL -2022-03-08T12:16:31 INFO flash_loader.c: Successfully loaded flash loader in sram -2022-03-08T12:16:31 INFO flash_loader.c: Clear DFSR - 8/ 8 pages written -2022-03-08T12:16:31 INFO common.c: Starting verification of write complete -2022-03-08T12:16:31 INFO common.c: Flash written and verified! jolly good! -2022-03-08T12:16:31 WARN common.c: NRST is not connected -``` - -Otherwise, if you receive an `Unknown memory region` error, run the following command to unlock the STM32F103: - -``` -openocd -f interface/stlink.cfg -f target/stm32f1x.cfg -c "init; reset halt; stm32f1x unlock 0; reset halt; exit" -``` - -Then re-plug the ST-Link and try again. - -After all of this, unplug the Bluepill from the ST-Link and connect it to USB. It should now be ready to flash using dfu-util, the QMK CLI or Toolbox. diff --git a/docs/ja/README.md b/docs/ja/README.md deleted file mode 100644 index aefacbc414aa..000000000000 --- a/docs/ja/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# Quantum Mechanical Keyboard Firmware - - - -[![現在のバージョン](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) -[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) -[![ドキュメントの状態](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) -[![GitHub 貢献者](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) -[![GitHub フォーク](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) - -## QMK ファームウェアとは何でしょうか? - -QMK (*Quantum Mechanical Keyboard*)は、コンピュータ入力デバイスの開発を中心としたオープンソースコミュニティです。コミュニティには、キーボード、マウス、MIDI デバイスなど、全ての種類の入力デバイスが含まれます。協力者の中心グループは、[QMK ファームウェア](https://github.com/qmk/qmk_firmware)、[QMK Configurator](https://config.qmk.fm)、[QMK ツールボックス](https://github.com/qmk/qmk_toolbox)、[qmk.fm](https://qmk.fm)、そして、このドキュメントを、あなたのようなコミュニティメンバーの助けを借りて保守しています。 - -## 始めましょう - -QMK は初めてですか?始めるには2つの方法があります: - -* 基本: [QMK Configurator](https://config.qmk.fm) - * ドロップダウンからあなたのキーボードを選択し、キーボードをプログラムします。 - * 見ることができる [紹介ビデオ](https://www.youtube.com/watch?v=-imgglzDMdY) があります。 - * 読むことができる概要 [ドキュメント](ja/newbs_building_firmware_configurator.md) があります。 -* 発展: [ソースを使用します](ja/newbs.md) - * より強力ですが、使うのはより困難です。 - -## 自分用にアレンジします - -QMK には、探求すべき多くの[機能](ja/features.md)と、深く知るためのリファレンスドキュメントがたくさんあります。ほとんどの機能は[キーマップ](ja/keymap.md)を変更し、[キーコード](ja/keycodes.md)を変更することで活用されます。 - -## 手助けが必要ですか? - -[サポートページ](ja/support.md) をチェックして、QMK の使い方について手助けを得る方法を確認してください。 - -## 貢献する - -QMK コミュニティに貢献する方法はたくさんあります。始める最も簡単な方法は、それを使って友人に QMK という単語を広めることです。 - -* フォーラムやチャットルームで人々を支援します: - * [/r/olkb](https://www.reddit.com/r/olkb/) - * [Discord サーバ](https://discord.gg/Uq7gcHh) -* 下にある「Edit This Page」をクリックしてドキュメントに貢献します -* [ドキュメントをあなたの言語に翻訳します](ja/translating.md) -* [バグを報告します](https://github.com/qmk/qmk_firmware/issues/new/choose) -* [プルリクエストを開きます](ja/contributing.md) diff --git a/docs/ja/_summary.md b/docs/ja/_summary.md deleted file mode 100644 index 4d6f2348d5cf..000000000000 --- a/docs/ja/_summary.md +++ /dev/null @@ -1,181 +0,0 @@ -* チュートリアル - * [入門](ja/newbs.md) - * [セットアップ](ja/newbs_getting_started.md) - * [初めてのファームウェアの構築](ja/newbs_building_firmware.md) - * [ファームウェアのフラッシュ](ja/newbs_flashing.md) - * [手助けを得る/サポート](ja/support.md) - * [他のリソース](ja/newbs_learn_more_resources.md) - * [シラバス](ja/syllabus.md) - -* FAQ - * [一般的な FAQ](ja/faq_general.md) - * [QMK のビルド/コンパイル](ja/faq_build.md) - * [QMK のデバッグ](ja/faq_debug.md) - * [QMK のトラブルシューティング](ja/faq_misc.md) - * [キーマップ FAQ](ja/faq_keymap.md) - * [用語](ja/reference_glossary.md) - -* Configurator - * [概要](ja/newbs_building_firmware_configurator.md) - * [ステップ・バイ・ステップ](ja/configurator_step_by_step.md) - * [トラブルシューティング](ja/configurator_troubleshooting.md) - * QMK API - * [概要](ja/api_overview.md) - * [API ドキュメント](ja/api_docs.md) - * [キーボードサポート](ja/reference_configurator_support.md) - * [デフォルトキーマップの追加](ja/configurator_default_keymaps.md) - -* CLI - * [概要](ja/cli.md) - * [設定](ja/cli_configuration.md) - * [コマンド](ja/cli_commands.md) - * [Tab 補完](ja/cli_tab_complete.md) - -* QMK を使う - * ガイド - * [機能のカスタマイズ](ja/custom_quantum_functions.md) - * [Zadig を使ったドライバのインストール](ja/driver_installation_zadig.md) - * [キーマップの概要](ja/keymap.md) - * 開発環境 - * [Docker のガイド](ja/getting_started_docker.md) - * 書き込み - * [書き込み](ja/flashing.md) - * [ATmega32A の書き込み (ps2avrgb)](ja/flashing_bootloadhid.md) - * IDE - * [QMK での Eclipse の使用](ja/other_eclipse.md) - * [QMK での VSCode の使用](ja/other_vscode.md) - * Git のベストプラクティス - * [入門](ja/newbs_git_best_practices.md) - * [フォーク](ja/newbs_git_using_your_master_branch.md) - * [マージの競合の解決](ja/newbs_git_resolving_merge_conflicts.md) - * [ブランチの修正](ja/newbs_git_resynchronize_a_branch.md) - * キーボードを作る - * [Hand Wiring ガイド](ja/hand_wire.md) - * [ISP 書き込みガイド](ja/isp_flashing_guide.md) - - * 単純なキーコード - * [完全なリスト](ja/keycodes.md) - * [基本的なキーコード](ja/keycodes_basic.md) - * [言語固有のキーコード](ja/reference_keymap_extras.md) - * [修飾キー](ja/feature_advanced_keycodes.md) - * [Quantum キーコード](ja/quantum_keycodes.md) - - * 高度なキーコード - * [コマンド](ja/feature_command.md) - * [動的マクロ](ja/feature_dynamic_macros.md) - * [グレイブ エスケープ](ja/feature_grave_esc.md) - * [リーダーキー](ja/feature_leader_key.md) - * [モッドタップ](ja/mod_tap.md) - * [マクロ](ja/feature_macros.md) - * [マウスキー](ja/feature_mouse_keys.md) - * [Repeat Key](ja/feature_repeat_key.md) - * [Space Cadet Shift](ja/feature_space_cadet.md) - * [US ANSI シフトキー](ja/keycodes_us_ansi_shifted.md) - - * ソフトウェア機能 - * [自動シフト](ja/feature_auto_shift.md) - * [コンボ](ja/feature_combo.md) - * [デバウンス API](ja/feature_debounce_type.md) - * [キーロック](ja/feature_key_lock.md) - * [レイヤー](ja/feature_layers.md) - * [ワンショットキー](ja/one_shot_keys.md) - * [ポインティング デバイス](ja/feature_pointing_device.md) - * [ロー HID](ja/feature_rawhid.md) - * [シーケンサー](ja/feature_sequencer.md) - * [スワップハンド](ja/feature_swap_hands.md) - * [タップダンス](ja/feature_tap_dance.md) - * [タップホールド設定](ja/tap_hold.md) - * [ユニコード](ja/feature_unicode.md) - * [ユーザスペース](ja/feature_userspace.md) - * [WPM 計算](ja/feature_wpm.md) - - * ハードウェア機能 - * 表示 - * [HD44780 LCD コントローラ](ja/feature_hd44780.md) - * [OLED ドライバ](ja/feature_oled_driver.md) - * 電飾 - * [バックライト](ja/feature_backlight.md) - * [LED マトリックス](ja/feature_led_matrix.md) - * [RGB ライト](ja/feature_rgblight.md) - * [RGB マトリックス](ja/feature_rgb_matrix.md) - * [オーディオ](ja/feature_audio.md) - * [Bluetooth](ja/feature_bluetooth.md) - * [ブートマジック](ja/feature_bootmagic.md) - * [カスタムマトリックス](ja/custom_matrix.md) - * [DIP スイッチ](ja/feature_dip_switch.md) - * [エンコーダ](ja/feature_encoders.md) - * [触覚フィードバック](ja/feature_haptic_feedback.md) - * [ジョイスティック](ja/feature_joystick.md) - * [LED インジケータ](ja/feature_led_indicators.md) - * [Proton C 変換](ja/proton_c_conversion.md) - * [PS/2 マウス](ja/feature_ps2_mouse.md) - * [分割キーボード](ja/feature_split_keyboard.md) - * [速記](ja/feature_stenography.md) - * [感熱式プリンタ](ja/feature_thermal_printer.md) - * [Velocikey](ja/feature_velocikey.md) - -* QMK の開発 - * [PR チェックリスト](ja/pr_checklist.md) - * 互換性を破る変更/Breaking changes - * [概要](ja/breaking_changes.md) - * [プルリクエストにフラグが付けられた](ja/breaking_changes_instructions.md) - * [最近の変更履歴](ChangeLog/20210227.md "QMK v0.12.0 - 2021 Feb 27") - * [過去の互換性を破る変更](ja/breaking_changes_history.md) - - * C 開発 - * [ARM デバッグ ガイド](ja/arm_debugging.md) - * [AVR プロセッサ](ja/hardware_avr.md) - * [コーディング規約](ja/coding_conventions_c.md) - * [互換性のあるマイクロコントローラ](ja/compatible_microcontrollers.md) - * [ドライバ](ja/hardware_drivers.md) - * [ADC ドライバ](ja/adc_driver.md) - * [オーディオドライバ](ja/audio_driver.md) - * [I2C ドライバ](ja/i2c_driver.md) - * [SPI ドライバ](ja/spi_driver.md) - * [WS2812 ドライバ](ja/ws2812_driver.md) - * [EEPROM ドライバ](ja/eeprom_driver.md) - * [シリアル ドライバ](ja/serial_driver.md) - * [UART ドライバ](ja/uart_driver.md) - * [GPIO 制御](ja/gpio_control.md) - * [キーボード ガイドライン](ja/hardware_keyboard_guidelines.md) - - * Python 開発 - * [コーディング規約](ja/coding_conventions_python.md) - * [QMK CLI 開発](ja/cli_development.md) - - * Configurator 開発 - * QMK API - * [開発環境](ja/api_development_environment.md) - * [アーキテクチャの概要](ja/api_development_overview.md) - - * ハードウェアプラットフォーム開発 - * Arm/ChibiOS - * [MCU の選択](ja/platformdev_selecting_arm_mcu.md) - * [早期初期化](ja/platformdev_chibios_earlyinit.md) - - * QMK Reference - * [QMK への貢献](ja/contributing.md) - * [QMK ドキュメントの翻訳](ja/translating.md) - * [設定オプション](ja/config_options.md) - * [データ駆動型コンフィギュレーション](ja/data_driven_config.md) - * [Make ドキュメント](ja/getting_started_make_guide.md) - * [ドキュメント ベストプラクティス](ja/documentation_best_practices.md) - * [ドキュメント テンプレート](ja/documentation_templates.md) - * [コミュニティレイアウト](ja/feature_layouts.md) - * [ユニットテスト](ja/unit_testing.md) - * [便利な関数](ja/ref_functions.md) - * [info.json 形式](ja/reference_info_json.md) - - * より深く知るために - * [キーボードがどのように動作するか](ja/how_keyboards_work.md) - * [マトリックスがどのように動作するか](ja/how_a_matrix_works.md) - * [QMK を理解する](ja/understanding_qmk.md) - - * QMK の内部詳細(作成中) - * [定義](ja/internals/defines.md) - * [入力コールバック登録](ja/internals/input_callback_reg.md) - * [Midi デバイス](ja/internals/midi_device.md) - * [Midi デバイスのセットアップ手順](ja/internals/midi_device_setup_process.md) - * [Midi ユーティリティ](ja/internals/midi_util.md) - * [Midi 送信関数](ja/internals/send_functions.md) - * [Sysex Tools](ja/internals/sysex_tools.md) diff --git a/docs/ja/adc_driver.md b/docs/ja/adc_driver.md deleted file mode 100644 index 0a531c8db9a1..000000000000 --- a/docs/ja/adc_driver.md +++ /dev/null @@ -1,155 +0,0 @@ -# ADC ドライバ - - - -QMK は対応している MCU のアナログ・デジタルコンバータ(ADC) を使用し、特定のピンの電圧を計測することができます。この機能はデジタル出力の[ロータリーエンコーダ](ja/feature_encoders.md)などではなく、アナログ計測が必要な可変抵抗器を使用したボリュームコントロールや Bluetooth キーボードのバッテリー残量表示などの実装に役立ちます。 - -このドライバは現在 AVR と一部の ARM デバイスをサポートしています。返される値は 0V と VCC (通常 AVR の場合は 5V または 3.3V、ARM の場合は 3.3V)の間でマッピングされた 10ビットの整数 (0-1023) ですが、ARM の場合、もしもより精度が必要であれば `#define` を使うと操作をより柔軟に制御できます。 - -## 使い方 - -このドライバを使うには、`rules.mk` に以下を追加します: - -```make -SRC += analog.c -``` - -そして、コードの先頭に以下の include を置きます: - -```c -#include "analog.h" -``` - -## チャンネル - -### AVR - -|Channel|AT90USB64/128|ATmega16/32U4|ATmega32A|ATmega328/P| -|-------|-------------|-------------|---------|-----------| -|0 |`F0` |`F0` |`A0` |`C0` | -|1 |`F1` |`F1` |`A1` |`C1` | -|2 |`F2` | |`A2` |`C2` | -|3 |`F3` | |`A3` |`C3` | -|4 |`F4` |`F4` |`A4` |`C4` | -|5 |`F5` |`F5` |`A5` |`C5` | -|6 |`F6` |`F6` |`A6` |* | -|7 |`F7` |`F7` |`A7` |* | -|8 | |`D4` | | | -|9 | |`D6` | | | -|10 | |`D7` | | | -|11 | |`B4` | | | -|12 | |`B5` | | | -|13 | |`B6` | | | - -\* ATmega328/P には余分な2つの ADC チャンネルがありますが、DIP ピンアウトには存在せず、GPIO ピンとは共有されません。これらに直接アクセスするために、`adc_read()` を使えます。 - -### ARM - -これらのピンの一部は同じチャンネルを使って ADC 上でダブルアップされることに注意してください。これは、これらのピンがどちらかの ADC に使われる可能性があるからです。 - -また、F0 と F3 は異なるナンバリングスキーマを使うことに注意してください。F0 には1つの ADC があり、チャンネルは0から始まるインデックスですが、F3 には4つの ADC があり、チャンネルは1から始まるインデックスです。これは、F0 が ADC の `ADCv1` 実装を使用するのに対し、F3 が `ADCv3` 実装を使用するためです。 - -|ADC|Channel|STM32F0xx|STM32F3xx| -|---|-------|---------|---------| -|1 |0 |`A0` | | -|1 |1 |`A1` |`A0` | -|1 |2 |`A2` |`A1` | -|1 |3 |`A3` |`A2` | -|1 |4 |`A4` |`A3` | -|1 |5 |`A5` |`F4` | -|1 |6 |`A6` |`C0` | -|1 |7 |`A7` |`C1` | -|1 |8 |`B0` |`C2` | -|1 |9 |`B1` |`C3` | -|1 |10 |`C0` |`F2` | -|1 |11 |`C1` | | -|1 |12 |`C2` | | -|1 |13 |`C3` | | -|1 |14 |`C4` | | -|1 |15 |`C5` | | -|1 |16 | | | -|2 |1 | |`A4` | -|2 |2 | |`A5` | -|2 |3 | |`A6` | -|2 |4 | |`A7` | -|2 |5 | |`C4` | -|2 |6 | |`C0` | -|2 |7 | |`C1` | -|2 |8 | |`C2` | -|2 |9 | |`C3` | -|2 |10 | |`F2` | -|2 |11 | |`C5` | -|2 |12 | |`B2` | -|2 |13 | | | -|2 |14 | | | -|2 |15 | | | -|2 |16 | | | -|3 |1 | |`B1` | -|3 |2 | |`E9` | -|3 |3 | |`E13` | -|3 |4 | | | -|3 |5 | | | -|3 |6 | |`E8` | -|3 |7 | |`D10` | -|3 |8 | |`D11` | -|3 |9 | |`D12` | -|3 |10 | |`D13` | -|3 |11 | |`D14` | -|3 |12 | |`B0` | -|3 |13 | |`E7` | -|3 |14 | |`E10` | -|3 |15 | |`E11` | -|3 |16 | |`E12` | -|4 |1 | |`E14` | -|4 |2 | |`B12` | -|4 |3 | |`B13` | -|4 |4 | |`B14` | -|4 |5 | |`B15` | -|4 |6 | |`E8` | -|4 |7 | |`D10` | -|4 |8 | |`D11` | -|4 |9 | |`D12` | -|4 |10 | |`D13` | -|4 |11 | |`D14` | -|4 |12 | |`D8` | -|4 |13 | |`D9` | -|4 |14 | | | -|4 |15 | | | -|4 |16 | | | - -## 関数 - -### AVR - -|関数 |説明 | -|----------------------------|------------------------------------------------------------------------------------------------------------------------------------| -|`analogReference(mode)` |アナログの電圧リファレンスソースを設定する。`ADC_REF_EXTERNAL`、`ADC_REF_POWER`、`ADC_REF_INTERNAL` のいずれかでなければなりません。| -|`analogReadPin(pin)` |指定されたピンから値を読み取ります。例えば、ATmega32U4 の ADC6 の場合 `F6`。 | -|`pinToMux(pin)` |指定されたピンを mux 値に変換します。サポートされていないピンが指定された場合、"0V (GND)" の mux 値を返します。 | -|`adc_read(mux)` |指定された mux に従って ADC から値を読み取ります。詳細は、MCU のデータシートを見てください。 | - -### ARM - -|関数 |説明 | -|----------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|`analogReadPin(pin)` |指定されたピンから値を読み取ります。STM32F0 では チャンネル 0 の `A0`、STM32F3 ではチャンネル 1 の ADC1。ピンを複数の ADC に使える場合は、この関数のために番号の小さい ADC が選択されることに注意してください。例えば、`C0` は、ADC2 にも使える場合、ADC1 のチャンネル 6 になります。 | -|`analogReadPinAdc(pin, adc)`|指定されたピンと ADC から値を読み取ります。例えば、`C0, 1` は、ADC1 ではなく ADC2 のチャンネル 6 から読み取ります。この関数では、ADC はインデックス 0 から始まることに注意してください。 | -|`pinToMux(pin)` |指定されたピンをチャンネルと ADC の組み合わせに変換します。サポートされていないピンが指定された場合、"0V (GND)" の mux 値を返します。 | -|`adc_read(mux)` |指定されたピンと ADC の組み合わせに応じて ADC から値を読み取ります。詳細は、MCU のデータシートを見てください。 | - -## 設定 - -## ARM - -ADC の ARM 実装には、独自のキーボードとキーマップでオーバーライドして動作方法を変更できる幾つかの追加オプションがあります。利用可能なオプションの詳細については、特定のマイクロコントローラについて ChibiOS の対応する `hal_adc_lld.h` を調べてください。 - -|`#define` |型 |既定値 |説明 | -|---------------------|------|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -|`ADC_CIRCULAR_BUFFER`|`bool`|`false` |`true` の場合、この実装は循環バッファを使います。 | -|`ADC_NUM_CHANNELS` |`int` |`1` |ADC 動作の一部としてスキャンされるチャンネル数を設定します。現在の実装は `1` のみをサポートします。 | -|`ADC_BUFFER_DEPTH` |`int` |`2` |各結果の深さを設定します。デフォルトでは12ビットの結果しか取得できないため、これを2バイトに設定して1つの値を含めることができます。8ビット以下の結果を選択した場合は、これを 1 に設定できます。 | -|`ADC_SAMPLING_RATE` |`int` |`ADC_SMPR_SMP_1P5` |ADC のサンプリングレートを設定します。デフォルトでは、最も速い設定に設定されています。 | -|`ADC_RESOLUTION` |`int` |`ADC_CFGR1_RES_12BIT`|結果の分解能。デフォルトでは12ビットを選択しますが、12、10、8、6ビットを選択できます。 | diff --git a/docs/ja/api_development_environment.md b/docs/ja/api_development_environment.md deleted file mode 100644 index 8dce1ba2fd6e..000000000000 --- a/docs/ja/api_development_environment.md +++ /dev/null @@ -1,8 +0,0 @@ -# 開発環境のセットアップ - - - -開発環境をセットアップするには、[qmk_web_stack](https://github.com/qmk/qmk_web_stack) に行ってください。 diff --git a/docs/ja/api_development_overview.md b/docs/ja/api_development_overview.md deleted file mode 100644 index 0612507b4d80..000000000000 --- a/docs/ja/api_development_overview.md +++ /dev/null @@ -1,49 +0,0 @@ -# QMK コンパイラ開発ガイド - - - -このページでは、開発者に QMK コンパイラを紹介しようと思います。コードを読まなければならないような核心となる詳細に立ち入って調べることはしません。ここで得られるものは、コードを読んで理解を深めるためのフレームワークです。 - -# 概要 - -QMK Compile API は、いくつかの可動部分からできています: - -![構造図](https://raw.githubusercontent.com/qmk/qmk_api/master/docs/architecture.svg) - -API クライアントは API サービスと排他的にやりとりをします。ここでジョブをサブミットし、状態を調べ、結果をダウンロードします。API サービスはコンパイルジョブを [Redis Queue](https://python-rq.org) に挿入し、それらのジョブの結果について RQ と S3 の両方を調べます。 - -ワーカーは RQ から新しいコンパイルジョブを取り出し、ソースとバイナリを S3 互換のストレージエンジンにアップロードします。 - -# ワーカー - -QMK コンパイラワーカーは実際のビルド作業に責任を持ちます。ワーカーは RQ からジョブを取り出し、ジョブを完了するためにいくつかの事を行います: - -* 新しい qmk_firmware のチェックアウトを作成する -* 指定されたレイヤーとキーボードメタデータを使って `keymap.c` をビルドする -* ファームウェアをビルドする -* ソースのコピーを zip 形式で圧縮する -* ファームウェア、ソースの zip ファイル、メタデータファイルを S3 にアップロードする -* ジョブの状態を RQ に送信する - -# API サービス - -API サービスは比較的単純な Flask アプリケーションです。理解しておくべきことが幾つかあります。 - -## @app.route('/v1/compile', methods=['POST']) - -これは API の主なエントリーポイントです。クライアントとのやりとりはここから開始されます。クライアントはキーボードを表す JSON ドキュメントを POST し、API はコンパイルジョブをサブミットする前にいくらかの(とても)基本的な検証を行います。 - -## @app.route('/v1/compile/<string:job_id>', methods=['GET']) - -これは最もよく呼ばれるエンドポイントです。ジョブの詳細が redis から利用可能であればそれを取り出し、そうでなければ S3 からキャッシュされたジョブの詳細を取り出します。 - -## @app.route('/v1/compile/<string:job_id>/download', methods=['GET']) - -このメソッドによりユーザはコンパイルされたファームウェアファイルをダウンロードすることができます。 - -## @app.route('/v1/compile/<string:job_id>/source', methods=['GET']) - -このメソッドによりユーザはファームウェアのソースをダウンロードすることができます。 diff --git a/docs/ja/api_docs.md b/docs/ja/api_docs.md deleted file mode 100644 index 19d52a724a16..000000000000 --- a/docs/ja/api_docs.md +++ /dev/null @@ -1,73 +0,0 @@ -# QMK API - - - -このページは QMK API の使い方を説明します。もしあなたがアプリケーション開発者であれば、全ての [QMK](https://qmk.fm) キーボードのファームウェアをコンパイルするために、この API を使うことができます。 - -## 概要 - -このサービスは、カスタムキーマップをコンパイルするための非同期 API です。API に 何らかの JSON を POST し、定期的に状態をチェックし、ファームウェアのコンパイルが完了していれば、結果のファームウェアと(もし希望すれば)そのファームウェアのソースコードをダウンロードすることができます。 - -#### JSON ペイロードの例: - -```json -{ - "keyboard": "clueboard/66/rev2", - "keymap": "my_awesome_keymap", - "layout": "LAYOUT_all", - "layers": [ - ["KC_GRV","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_GRV","KC_BSPC","KC_PGUP","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_PGDN","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_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"], - ["KC_ESC","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_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SCRL","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"], - ["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","QK_BOOT","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"] - ] -} -``` - -ご覧のとおり、ペイロードにはファームウェアを作成および生成するために必要なキーボードの全ての側面を記述します。各レイヤーは QMK キーコードの1つのリストで、キーボードの `LAYOUT` マクロと同じ長さです。もしキーボードが複数の `LAYOUT` マクロをサポートする場合、どのマクロを使うかを指定することができます。 - -## コンパイルジョブのサブミット - -キーマップをファームウェアにコンパイルするには、単純に JSON を `/v1/compile` エンドポイントに POST します。以下の例では、JSON ペイロードを `json_data` という名前のファイルに配置しています。 - -``` -$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" https://api.qmk.fm/v1/compile -{ - "enqueued": true, - "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6" -} -``` - -## 状態のチェック - -キーマップをサブミットした後で、簡単な HTTP GET 呼び出しを使って状態をチェックすることができます: - -``` -$ curl https://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6 -{ - "created_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "id": "f5f9b992-73b4-479b-8236-df1deb37c163", - "status": "running", - "result": null -} -``` - -これは、ジョブをキューに入れることに成功し、現在実行中であることを示しています。5つの状態がありえます: - -* **failed**: なんらかの理由でコンパイルサービスが失敗しました。 -* **finished**: コンパイルが完了し、結果を見るには `result` をチェックする必要があります。 -* **queued**: キーマップはコンパイルサーバが利用可能になるのを待っています。 -* **running**: コンパイルが進行中で、まもなく完了するはずです。 -* **unknown**: 深刻なエラーが発生し、[バグを報告](https://github.com/qmk/qmk_compiler/issues)する必要があります。 - -## 完了した結果を検証 - -コンパイルジョブが完了したら、`result` キーをチェックします。このキーの値は幾つかの情報を含むハッシュです: - -* `firmware_binary_url`: 書き込み可能なファームウェアの URL のリスト -* `firmware_keymap_url`: `keymap.c` の URL のリスト -* `firmware_source_url`: ファームウェアの完全なソースコードの URL のリスト -* `output`: このコンパイルジョブの stdout と stderr。エラーはここで見つけることができます。 diff --git a/docs/ja/api_overview.md b/docs/ja/api_overview.md deleted file mode 100644 index e563bdd10350..000000000000 --- a/docs/ja/api_overview.md +++ /dev/null @@ -1,20 +0,0 @@ -# QMK API - - - -QMK API は、Web と GUI ツールが [QMK](https://qmk.fm/) によってサポートされるキーボード用の任意のキーマップをコンパイルするために使うことができる、非同期 API を提供します。標準のキーマップテンプレートは、C コードのサポートを必要としない全ての QMK キーコードをサポートします。キーボードのメンテナは独自のカスタムテンプレートを提供して、より多くの機能を実現することができます。 - -## アプリケーション開発者 - -もしあなたがアプリケーションでこの API を使うことに興味があるアプリケーション開発者であれば、[API の使用](ja/api_docs.md) に行くべきです。 - -## キーボードのメンテナ - -もし QMK Compiler API でのあなたのキーボードのサポートを強化したい場合は、[キーボードサポート](ja/reference_configurator_support.md) の節に行くべきです。 - -## バックエンド開発者 - -もし API 自体に取り組むことに興味がある場合は、[開発環境](ja/api_development_environment.md)のセットアップから始め、それから [API のハッキング](ja/api_development_overview.md) を調べるべきです。 diff --git a/docs/ja/arm_debugging.md b/docs/ja/arm_debugging.md deleted file mode 100644 index afb5c4e0e6a8..000000000000 --- a/docs/ja/arm_debugging.md +++ /dev/null @@ -1,92 +0,0 @@ -# Eclipse を使った ARM デバッグ - - - -このページでは、SWD アダプタとオープンソース/フリーツールを使って ARM MCU をデバッグするためのセットアップ方法について説明します。このガイドでは、GNU MCU Eclipse IDE for C/C++ Developers および OpenOCD を必要な依存関係と一緒にインストールします。 - -このガイドは上級者向けであり、あなたのマシンで、MAKE フローを使って、ARM 互換キーボードをコンパイルできることを前提にしています。 - -## ソフトウェアのインストール - -ここでの主な目的は MCU Eclipse IDE を正しくマシンにインストールすることです。必要な手順は[この](https://gnu-mcu-eclipse.github.io/install/)インストールガイドから派生しています。 - -### xPack マネージャ - -このツールはソフトウェアパッケージマネージャであり、必要な依存関係を取得するために使われます。 - -XPM は Node.js を使って実行されるため、[ここ](https://nodejs.org/en/)から取得してください。インストール後に、ターミナルを開き `npm -v` と入力します。バージョン番号が返ってくるとインストールは成功です。 - -XPM のインストール手順は[ここ](https://www.npmjs.com/package/xpm)で見つけることができ、OS 固有のものです。ターミナルに `xpm --version` と入力すると、ソフトウェアのバージョンが返ってくるはずです。 - -### ARM ツールチェーン - -XPM を使うと、ARM ツールチェーンをとても簡単にインストールできます。`xpm install --global @xpack-dev-tools/arm-none-eabi-gcc` とコマンドを入力します。 - -### Windows ビルドツール - -Windows を使っている場合は、これをインストールする必要があります! - -`xpm install --global @gnu-mcu-eclipse/windows-build-tools` - -### プログラマ/デバッガドライバ - -プログラマのドライバをインストールします。このチュートリアルはほとんどどこでも入手できる ST-Link v2 を使って作成されました。 -ST-Link を持っている場合は、ドライバは[ここ](https://www.st.com/en/development-tools/stsw-link009.html)で見つけることができます。そうでない場合はツールの製造元にお問い合わせください。 - -### OpenOCD - -この依存関係により、SWD は GDB からアクセスでき、デバッグに不可欠です。`xpm install --global @xpack-dev-tools/openocd` を実行します。 - -### Java - -Java は Eclipse で必要とされるため、[ここ](https://www.oracle.com/technetwork/java/javase/downloads/index.html)からダウンロードしてください。 - -### GNU MCU Eclipse IDE - -最後に IDE をインストールする番です。[ここ](https://github.com/gnu-mcu-eclipse/org.eclipse.epp.packages/releases/)のリリースページから最新バージョンを取得します。 - -## Eclipse の設定 - -ダウンロードした Eclipse IDE を開きます。QMK ディレクトリをインポートするために、File -> Import -> C/C++ -> Existing Code as Makefile Project を選択します。Next を選択し、Browse を使用して QMK フォルダを選択します。tool-chain リストから ARM Cross GCC を選択し、Finish を選択します。 - -これで、左側に QMK フォルダが表示されます。右クリックして、Properties を選択します。左側で MCU を展開し、ARM Toolchains Paths を選択します。xPack を押して OK を押します。OpenOCD Path で同じことを繰り返し、Windows の場合は、Build Tools Path でも同じことを繰り返します。Apply and Close を選択します。 - -ここで、必要な MCU パッケージをインストールします。Window -> Perspective -> Open Perspective -> Other... -> Packs を選択して、Packs perspective に移動します。Packs タブの横にある黄色のリフレッシュ記号を選択します。これは様々な場所から MCU の定義を要求するため、時間が掛かります。一部のリンクが失敗した場合は、おそらく Ignore を選択できます。 - -これが終了すると、ビルドやデバッグする MCU を見つけることができるはずです。この例では、STM32F3 シリーズの MCU を使います。左側で、STMicroelectronics -> STM32F3 Series を選択します。中央のウィンドウに、pack が表示されます。右クリックし、Install を選択します。それが終了したら、Window -> Perspective -> Open Perspective -> Other... -> C/C++ を選択してデフォルトのパースペクティブに戻ることができます。 - -Eclipse に QMK をビルドしようとするデバイスを教える必要があります。QMK フォルダを右クリック -> Properties -> C/C++ Build -> Settings を選択します。Devices タブを選択し、Devices の下から MCU の適切な種類を選択します。私の例では、STM32F303CC です。 - -この間に、Build コマンドもセットアップしましょう。C/C++ Build を選択し、Behavior タブを選択します。Build コマンドのところで、`all` を必要な make コマンドに置き換えます。例えば、rev6 Planck の default キーマップの場合、これは `planck/rev6:default` になります。Apply and Close を選択します。 - -## ビルド - -全て正しくセットアップできていれば、ハンマーボタンを押すとファームウェアがビルドされ、.bin ファイルが出力されるはずです。 - -## デバッグ - -### デバッガの接続 - -ARM MCU は、クロック信号(SWCLK) とデータ信号(SWDIO) で構成される Single Wire Debug (SWD) プロトコルを使います。MCU を完全に操作するには、この2本のワイヤとグラウンドを接続するだけで十分です。ここでは、キーボードは USB を介して電力が供給されると想定しています。手動でリセットボタンを使えるため、RESET 信号は必要ありません。より高度なセットアップのために printf と scanf をホストに非同期にパイプする SWO 信号を使用できますが、私たちのセットアップでは無視します。 - -注意: SWCLK と SWDIO ピンがキーボードのマトリックスで使われていないことを確認してください。もし使われている場合は、一時的に他のピンに切り替えることができます。 - -### デバッガの設定 - -QMK フォルダを右クリックし、Debug As -> Debug Configurations... を選択します。ここで、GDB OpenOCD Debugging をダブルクリックします。Debugger タブを選択し、MCU に必要な設定を入力します。これを見つけるにはいじったりググったりする必要があるかもしれません。STM32F3 用のデフォルトスクリプトは `stm32f3discovery.cfg` と呼ばれます。OpenOCD に伝えるには、Config options で `-f board/stm32f3discovery.cfg` と入力します。 - -注意: 私の場合、この設定スクリプトはリセット操作を無効にするために編集が必要です。スクリプトの場所は、通常はパス `openocd/version/.content/scripts/board` の下の実際の実行可能フィールドの中で見つかります。ここで、私は `reset_config srst_only` を `reset_config none` に編集しました。 - -Apply and Close を選択します。 - -### デバッガの実行 - -キーボードをリセットしてください。 - -虫アイコンをクリックし、もし全てうまく行けば Debug パースペクティブに移動します。ここでは、main 関数の最初でプログラムカウンタが停止し、Play ボタンが押されるのを待ちます。全てのデバッガのほとんどの機能は Arm MCU で動作しますが、正確な詳細については Google があなたのお友達です! - - -ハッピーデバッギング! diff --git a/docs/ja/breaking_changes.md b/docs/ja/breaking_changes.md deleted file mode 100644 index 35f583789733..000000000000 --- a/docs/ja/breaking_changes.md +++ /dev/null @@ -1,120 +0,0 @@ -# Breaking changes/互換性を破る変更 - - - -このドキュメントは QMK の互換性を破る変更(Breaking change) のプロセスについて説明します。 -互換性を破る変更とは、互換性がなかったり潜在的な危険が生じるように QMK の動作を変える変更を指します。 -ユーザが QMK ツリーを更新しても自分のキーマップが壊れない事を確信できるように、これらの変更を制限します。(訳注:以後、原文のまま Breaking change を用語として使用します。) - -Breaking change ピリオドとは、危険な変更、または予想外の変更を QMK へ行なう PR をマージする時のことです。 -付随するテスト期間があるため、問題が起きることはまれか、有りえないと確信しています。 - -## 過去の Breaking change には何が含まれますか? - -* [2020年8月29日](ja/ChangeLog/20200829.md) -* [2020年5月30日](ja/ChangeLog/20200530.md) -* [2020年2月29日](ja/ChangeLog/20200229.md) -* [2019年8月30日](ja/ChangeLog/20190830.md) - -## 次の Breaking change はいつですか? - -次の Breaking change は2020年11月28日に予定されています。 - -### 重要な日付 - -* [x] 2020年 8月29日 - `develop` が作成されました。毎週リベースされます。 -* [ ] 2020年10月31日 - `develop` は新しいPRを取り込みません。 -* [ ] 2020年10月31日 - テスターの募集。 -* [ ] 2020年11月26日 - `master`がロックされ、PR はマージされません。 -* [ ] 2020年11月28日 - `develop` を `master` にマージします。 -* [ ] 2020年11月28日 - `master` のロックが解除されます。PR を再びマージすることができます。 - -## どのような変更が含まれますか? - -最新の Breaking change 候補を見るには、[`breaking_change` ラベル](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+label%3Abreaking_change+is%3Apr)を参照してください。 -現在から `develop` が閉じられるまでの間に新しい変更が追加される可能性があり、そのラベルが適用された PR はマージされることは保証されていません。 - -このラウンドに、あなたの Breaking change を含めたい場合は、`breaking_change` ラベルを持つ PR を作成し、`develop` が閉じる前に承認してもらう必要があります。 -`develop` が閉じた後は、新しい Breaking change は受け付けられません。 - -受け入れの基準: - -* PR が完了し、マージの準備ができている -* PR が ChangeLog を持つ - -# チェックリスト - -ここでは、Breaking change プロセスを実行する時に使用する様々なプロセスについて説明します。 - -## `master` から `develop` をリベースします - -これは `develop` が開いている間、毎週金曜日に実行されます。 - -プロセス: - -``` -cd qmk_firmware -git checkout master -git pull --ff-only -git checkout develop -git rebase master -git push --force -``` - -## `develop` ブランチの作成 - -以前の `develop` ブランチがマージされた直後に、これが発生します。 - -* `qmk_firmware` git commands - * [ ] `git checkout master` - * [ ] `git pull --ff-only` - * [ ] `git checkout -b develop` - * [ ] Edit `readme.md` - * [ ] これがテストブランチであることを上部に大きな通知で追加します。 - * [ ] このドキュメントへのリンクを含めます - * [ ] `git commit -m 'Branch point for Breaking Change'` - * [ ] `git tag breakpoint___
` - * [ ] `git tag ` # ブレーキング ポイント タグがバージョンの増分を混乱させないようにします - * [ ] `git push origin develop` - * [ ] `git push --tags` - -## マージの 4 週間前 - -* `develop` は新しい PR に対して閉じられ、現在の PR の修正のみがマージされる可能性があります。 -* テスターの呼び出しを投稿します - * [ ] Discord - * [ ] GitHub PR - * [ ] https://reddit.com/r/olkb - -## マージの 1 週間前 - -* master が < 2 日前> から <マージの日> まで閉じられることを発表します - * [ ] Discord - * [ ] GitHub PR - * [ ] https://reddit.com/r/olkb - -## マージの 2 日前 - -* master が 2 日間閉じられることを発表します - * [ ] Discord - * [ ] GitHub PR - * [ ] https://reddit.com/r/olkb - -## マージの日 - -* `qmk_firmware` git commands - * [ ] `git checkout develop` - * [ ] `git pull --ff-only` - * [ ] `git rebase origin/master` - * [ ] Edit `readme.md` - * [ ] `develop` についてのメモを削除 - * [ ] ChangeLog を 1 つのファイルにまとめます。 - * [ ] `git commit -m 'Merge point for Breaking Change'` - * [ ] `git push origin develop` -* GitHub Actions - * [ ] `develop`の PR を作成します - * [ ] `develop` PR をマージします diff --git a/docs/ja/breaking_changes_instructions.md b/docs/ja/breaking_changes_instructions.md deleted file mode 100644 index 69d17d73c5f5..000000000000 --- a/docs/ja/breaking_changes_instructions.md +++ /dev/null @@ -1,51 +0,0 @@ -# breaking changes/互換性を破る変更: プルリクエストにフラグが付けられた - - - -QMK のメンバーがあなたのプルリクエストに返信し、あなたの提出したものは Breaking change (互換性を破る変更) であると述べている場合があります。メンバーの判断では、あなたが提案した変更は QMK やその利用者にとってより大きな影響を持つと考えられます。 - -プルリクエストにフラグが立てられる原因となるものには、以下のようなものがあります: - -- **ユーザーのキーマップに対する編集** - ユーザーが自分のキーマップを QMK に提出した後、しばらくしてさらに更新してプルリクエストを開いたところ、それが `qmk/qmk_firmware` リポジトリで編集されていたためにマージできなかったことに気づくことがあるかもしれません。すべてのユーザーが Git や GitHub を使いこなせるわけではないので、ユーザー自身で問題を修正できないことに気づくかもしれません。 -- **期待される動作の変更** - QMK の動作を変更すると、既存の QMK 機能への変更を組み込んだ新しいファームウェアをフラッシュした場合、ユーザはハードウェアまたは QMK が壊れていると考え、希望する動作を復元する手段がないことに気付くことがあります。 -- **ユーザーのアクションを必要とする変更** - 変更には、ツールチェインを更新したり、Git で何らかのアクションを取るなど、ユーザーがアクションを行う必要がある場合もあります。 -- **精査が必要な変更** - 時には、投稿がプロジェクトとしての QMK に影響を与えることもあります。これは、著作権やライセンスの問題、コーディング規約、大規模な機能のオーバーホール、コミュニティによるより広範なテストを必要とする「リスクの高い」変更、あるいは全く別のものである可能性があります。 -- **エンドユーザーとのコミュニケーションを必要とする変更** - これには、将来の非推奨化への警告、時代遅れの慣習、その他伝えなければならないが上記のカテゴリのどれかに当てはまらないものが含まれます。 - -## 何をすればいいのか? - -提出したものが Breaking change だと判断された場合、手続きをスムーズに進めるためにできることがいくつかあります。 - -### PR を分割することを検討する - -あなたがコアコードを投稿していて、それが Breaking change プロセスを経る必要がある唯一の理由が、あなたの変更に合わせてキーマップを更新していることである場合、古いキーマップが機能し続けるような方法であなたの機能を投稿できるかどうかを検討してください。 -そののち、Breaking change プロセスを経て古いコードを削除する別の PR を提出してください。 - -### ChangeLog エントリの提供 - -Breaking change プロセスを経て提出する際には、変更ログのエントリを含めることを我々は要請します。 -エントリーは、あなたのプルリクエストが行う変更の短い要約としてください – [ここの各セクションは changelog として開始されました](ja/ChangeLog/20190830.md "n.b. This should link to the 2019 Aug 30 Breaking Changes doc - @noroadsleft")。 - -変更ログは `docs/ChangeLog/YYYYMMDD/PR####.md` に置いてください。 -ここで、`YYYYMMDD` は QMK の breaking change ブランチ – 通常は `develop` という名称 – が `master` ブランチにマージされる日付、`####` はプルリクエストの番号です。 - -ユーザー側でのアクションを必要とする場合、あなたの変更ログは、どのようなアクションを取らなければならないかをユーザーに指示するか、そのようなアクションを指示する場所にリンクする必要があります。 - -### 変更点を文書化する - -提出物の目的を理解し、それが必要とする可能性のある意味合いやアクションを理解することで、レビュープロセスをより簡単にすることができます。この目的のためには変更履歴で十分かもしれませんが、より広範囲の変更を行う場合には、変更履歴には不向きな詳細レベルが必要になるかもしれません。 - -あなたのプルリクエストにコメントしたり、質問やコメント、変更要求に対応したりすることは、非常にありがたいことです。 - -### 助けを求める - -あなたの提出物にフラグが立ったことで、あなたはびっくりしてしまったかもしれません。もし、あなた自身が脅されたり、圧倒されたりしていると感じたら、私たちに知らせてください。プルリクエストにコメントするか、[Discord で QMK チームに連絡を取ってください](https://discord.gg/Uq7gcHh)。 diff --git a/docs/ja/cli.md b/docs/ja/cli.md deleted file mode 100644 index 9e8169a84e07..000000000000 --- a/docs/ja/cli.md +++ /dev/null @@ -1,43 +0,0 @@ -# QMK CLI :id=qmk-cli - - - -## 概要 :id=overview - -QMK CLI を使用すると QMK キーボードの構築と作業が簡単になります。QMK ファームウェアの取得とコンパイル、キーマップの作成などのようなタスクを簡素化し合理化するためのコマンドを多く提供します。 - -### 必要事項 :id=requirements - -QMK は Python 3.6 以上を必要とします。我々は必要事項の数を少なくしようとしていますが、[`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt) に列挙されているパッケージもインストールする必要があります。これらは QMK CLI をインストールするときに自動的にインストールされます。 - -### Homebrew を使ったインストール (macOS、いくつかの Linux) :id=install-using-homebrew - -[Homebrew](https://brew.sh) をインストールしている場合は、タップして QMK をインストールすることができます: - -``` -brew install qmk/qmk/qmk -export QMK_HOME='~/qmk_firmware' # オプション、`qmk_firmware` の場所を設定します -qmk setup # これは `qmk/qmk_firmware` をクローンし、オプションでビルド環境をセットアップします -``` - -### pip を使ってインストール :id=install-using-easy_install-or-pip - -上で列挙した中にあなたのシステムがない場合は、QMK を手動でインストールすることができます。最初に、python 3.6 (以降)をインストールしていて、pip をインストールしていることを確認してください。次に以下のコマンドを使って QMK をインストールします: - -``` -python3 -m pip install qmk -export QMK_HOME='~/qmk_firmware' # オプション、`qmk_firmware` の場所を設定します -qmk setup # これは `qmk/qmk_firmware` をクローンし、オプションでビルド環境をセットアップします -``` - -### 他のオペレーティングシステムのためのパッケージ :id=packaging-for-other-operating-systems - -より多くのオペレーティングシステム用に `qmk` パッケージを作成および保守する人を探しています。OS 用のパッケージを作成する場合は、以下のガイドラインに従ってください: - -* これらのガイドラインと矛盾する場合は、OS のベストプラクティスに従ってください - * 逸脱する場合は、理由をコメントに文章化してください。 -* virtualenv を使ってインストールしてください -* 環境変数 `QMK_HOME` を設定して、ファームウェアソースを `~/qmk_firmware` 以外のどこかにチェックアウトするようにユーザに指示してください。 diff --git a/docs/ja/cli_commands.md b/docs/ja/cli_commands.md deleted file mode 100644 index b48de077cd38..000000000000 --- a/docs/ja/cli_commands.md +++ /dev/null @@ -1,296 +0,0 @@ -# QMK CLI コマンド - - - -# ユーザー用コマンド - -## `qmk compile` - -このコマンドにより、任意のディレクトリからファームウェアをコンパイルすることができます。 からエクスポートした JSON をコンパイルするか、リポジトリ内でキーマップをコンパイルするか、現在の作業ディレクトリでキーボードをコンパイルすることができます。 - -このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 - -**Configurator Exports での使い方**: - -``` -qmk compile -``` - -**キーマップでの使い方**: - -``` -qmk compile -kb -km -``` - -**キーボードディレクトリでの使い方**: - -default キーマップのあるキーボードディレクトリ、キーボードのキーマップディレクトリ、`--keymap ` で与えられるキーマップディレクトリにいなければなりません。 -``` -qmk compile -``` - -**指定したキーマップをサポートする全てのキーボードをビルドする場合の使い方**: - -``` -qmk compile -kb all -km -``` - -**例**: -``` -$ qmk config compile.keymap=default -$ cd ~/qmk_firmware/keyboards/planck/rev6 -$ qmk compile -Ψ Compiling keymap with make planck/rev6:default -... -``` -あるいはオプションのキーマップ引数を指定して - -``` -$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4 -$ qmk compile -km 66_iso -Ψ Compiling keymap with make clueboard/66/rev4:66_iso -... -``` -あるいはキーマップディレクトリで - -``` -$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak -$ qmk compile -Ψ Compiling keymap with make gh60/satan:colemak -... -``` - -**レイアウトディレクトリでの使い方**: - -`qmk_firmware/layouts/` 以下のキーマップディレクトリにいなければなりません。 -``` -qmk compile -kb -``` - -**例**: -``` -$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi -$ qmk compile -kb dz60 -Ψ Compiling keymap with make dz60:mechmerlin-ansi -... -``` - -## `qmk flash` - -このコマンドは `qmk compile` に似ていますが、ブートローダを対象にすることもできます。ブートローダはオプションで、デフォルトでは `:flash` に設定されています。 -違うブートローダを指定するには、`-bl ` を使ってください。利用可能なブートローダの詳細については、[ファームウェアを書き込む](ja/flashing.md)を見てください。 - -このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 - -**Configurator Exports での使い方**: - -``` -qmk flash -bl -``` - -**キーマップでの使い方**: - -``` -qmk flash -kb -km -bl -``` - -**ブートローダの列挙** - -``` -qmk flash -b -``` - -## `qmk config` - -このコマンドにより QMK の挙動を設定することができます。完全な `qmk config` のドキュメントについては、[CLI 設定](ja/cli_configuration.md)を見てください。 - -**使用法**: - -``` -qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] -``` - -## `qmk doctor` - -このコマンドは環境を調査し、潜在的なビルドあるいは書き込みの問題について警告します。必要に応じてそれらの多くを修正できます。 - -**使用法**: - -``` -qmk doctor [-y] [-n] -``` - -**例**: - -環境に問題がないか確認し、それらを修正するよう促します: - - qmk doctor - -環境を確認し、見つかった問題を自動的に修正します: - - qmk doctor -y - -環境を確認し、問題のみをレポートします: - - qmk doctor -n - -## `qmk info` - -QMK のキーボードやキーマップに関する情報を表示します。キーボードに関する情報を取得したり、レイアウトを表示したり、基礎となるキーマトリックスを表示したり、JSON キーマップをきれいに印刷したりするのに使用できます。 - -**使用法**: - -``` -qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD] -``` - -このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 - -**例**: - -キーボードの基本情報を表示する: - - qmk info -kb planck/rev5 - -キーボードのマトリクスを表示する: - - qmk info -kb ergodox_ez -m - -キーボードの JSON キーマップを表示する: - - qmk info -kb clueboard/california -km default - -## `qmk json2c` - -QMK Configurator からエクスポートしたものから keymap.c を生成します。 - -**使用法**: - -``` -qmk json2c [-o OUTPUT] filename -``` - -## `qmk list-keyboards` - -このコマンドは現在 `qmk_firmware` で定義されている全てのキーボードを列挙します。 - -**使用法**: - -``` -qmk list-keyboards -``` - -## `qmk list-keymaps` - -このコマンドは指定されたキーボード(とリビジョン)の全てのキーマップを列挙します。 - -このコマンドはディレクトリを認識します。キーボードのディレクトリにいる場合、自動的に KEYBOARD を入力します。 - -**使用法**: - -``` -qmk list-keymaps -kb planck/ez -``` - -## `qmk new-keymap` - -このコマンドは、キーボードの既存のデフォルトのキーマップに基づいて新しいキーマップを作成します。 - -このコマンドはディレクトリを認識します。キーボードやキーマップのディレクトリにいる場合、自動的に KEYBOARD や KEYMAP を入力します。 - -**使用法**: - -``` -qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] -``` - ---- - -# 開発者用コマンド - -## `qmk format-c` - -このコマンドは clang-format を使って C コードを整形します。 - -引数無しで実行すると、変更された全てのコアコードを整形します。デフォルトでは `git diff` で `origin/master` をチェックし、ブランチは `-b ` を使って変更できます。 - -`-a` で全てのコアコードを整形するか、コマンドラインでファイル名を渡して特定のファイルに対して実行します。 - -**指定したファイルに対する使い方**: - -``` -qmk format-c [file1] [file2] [...] [fileN] -``` - -**全てのコアファイルに対する使い方**: - -``` -qmk format-c -a -``` - -**origin/master で変更されたファイルのみに対する使い方**: - -``` -qmk format-c -``` - -**branch_name で変更されたファイルのみに対する使い方**: - -``` -qmk format-c -b branch_name -``` - -## `qmk docs` - -このコマンドは、ドキュメントを参照または改善するために使うことができるローカル HTTP サーバを起動します。デフォルトのポートは 8936 です。 - -**使用法**: - -``` -qmk docs [-p PORT] -``` - -## `qmk kle2json` - -このコマンドにより、生の KLE データから QMK Configurator の JSON へ変換することができます。絶対パスあるいは現在のディレクトリ内のファイル名のいずれかを受け取ります。デフォルトでは、`info.json` が既に存在している場合は上書きしません。上書きするには、`-f` あるいは `--force` フラグを使ってください。 - -**使用法**: - -``` -qmk kle2json [-f] -``` - -**例**: - -``` -$ qmk kle2json kle.txt -☒ File info.json already exists, use -f or --force to overwrite. -``` - -``` -$ qmk kle2json -f kle.txt -f -Ψ Wrote out to info.json -``` - -## `qmk format-python` - -このコマンドは `qmk_firmware` 内の python コードを整形します。 - -**使用法**: - -``` -qmk format-python -``` - -## `qmk pytest` - -このコマンドは python のテストスィートを実行します。python コードに変更を加えた場合、これの実行が成功することを確認する必要があります。 - -**使用法**: - -``` -qmk pytest -``` diff --git a/docs/ja/cli_configuration.md b/docs/ja/cli_configuration.md deleted file mode 100644 index 6ed791b47132..000000000000 --- a/docs/ja/cli_configuration.md +++ /dev/null @@ -1,126 +0,0 @@ -# QMK CLI 設定 - - - -このドキュメントは `qmk config` がどのように動作するかを説明します。 - -# はじめに - -QMK CLI の設定はキーバリューシステムです。各キーはピリオドで区切られたサブコマンドと引数名で構成されます。これにより、設定キーと設定された引数の間で簡単かつ直接的な変換が可能になります。 - -## 簡単な例 - -例として、`qmk compile --keyboard clueboard/66/rev4 --keymap default` コマンドを見てみましょう。 - -設定から読み取ることができる2つのコマンドライン引数があります: - -* `compile.keyboard` -* `compile.keymap` - -これらを設定してみましょう: - -``` -$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default -compile.keyboard: None -> clueboard/66/rev4 -compile.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -これで、毎回キーボードとキーマップを設定することなく、`qmk compile` を実行することができます。 - -## ユーザデフォルトの設定 - -複数のコマンド間で設定を共有したい場合があります。例えば、いくつかのコマンドは引数 `--keyboard` を受け取ります。全てのコマンドでこの値を設定する代わりに、その引数を受け取る全てのコマンドで使われるユーザ値を設定することができます。 - -例: - -``` -$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default -user.keyboard: None -> clueboard/66/rev4 -user.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# CLI ドキュメント (`qmk config`) - -`qmk config` コマンドは基礎となる設定とやり取りするために使われます。引数無しで実行すると、現在の設定を表示します。引数が指定された場合、それらは設定トークンと見なされます。設定トークンは以下の形式の空白を含まない文字列です: - - [.][=] - -## 設定値の設定 - -設定キーに等号 (=) を入れることで、設定値を設定することができます。キーは常に完全な `
.` 形式である必要があります。 - -例: - -``` -$ qmk config default.keymap=default -default.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## 設定値の読み込み - -設定全体、単一のキー、あるいはセクション全体の設定値を読み取ることができます。1つ以上の値を表示するために複数のキーを指定することができます。 - -### 全体の構成例 - - qmk config - -### セクション全体の例 - - qmk config compile - -### 単一キーの例 :id=single-key-example - - qmk config compile.keyboard - -### 複数キーの例 - - qmk config user compile.keyboard compile.keymap - -## 設定値の削除 - -設定値を特別な文字列 `None` に設定することで、設定値を削除することができます。 - -例: - -``` -$ qmk config default.keymap=None -default.keymap: default -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## 複数の操作 - -複数の読み込みおよび書き込み操作を1つのコマンドに組み合わせることができます。それらは順番に実行および表示されます: - -``` -$ qmk config compile default.keymap=default compile.keymap=None -compile.keymap=skully -compile.keyboard=clueboard/66_hotswap/gen1 -default.keymap: None -> default -compile.keymap: skully -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# ユーザ設定オプション - -| キー | デフォルト値 | 説明 | -|-----|---------------|-------------| -| user.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | -| user.keymap | None | キーマップ名 (例: `default`) | -| user.name | None | ユーザの GitHub のユーザ名。 | - -# 全ての設定オプション - -| キー | デフォルト値 | 説明 | -|-----|---------------|-------------| -| compile.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | -| compile.keymap | None | キーマップ名 (例: `default`) | -| hello.name | None | 実行時の挨拶の名前 | -| new_keyboard.keyboard | None | キーボードのパス (例: `clueboard/66/rev4`) | -| new_keyboard.keymap | None | キーマップ名 (例: `default`) | diff --git a/docs/ja/cli_development.md b/docs/ja/cli_development.md deleted file mode 100644 index 082bc5dafa19..000000000000 --- a/docs/ja/cli_development.md +++ /dev/null @@ -1,223 +0,0 @@ -# QMK CLI 開発 - - - -このドキュメントは、新しい `qmk` サブコマンドを書きたい開発者に役立つ情報が含まれています。 - -# 概要 - -QMK CLI は git で有名になったサブコマンドパターンを使って動作します。メインの `qmk` スクリプトは単に環境をセットアップし、実行する正しいエントリポイントを選択するためにあります。各サブコマンドは、何らかのアクションを実行しシェルのリターンコード、または None を返すエントリーポイント (`@cli.subcommand()` で修飾されます)を備えた自己完結型のモジュールです。 - -## 開発者モード: - -キーボードを保守、あるいは QMK に貢献したい場合は、CLI の「開発者」モードを有効にすることができます: - -`qmk config user.developer=True` - -これにより利用可能な全てのサブコマンドが表示されます。 -**注意:** 追加で必要なものをインストールする必要があります: -```bash -python3 -m pip install -r requirements-dev.txt -``` - -# サブコマンド - -[MILC](https://github.com/clueboard/milc) は、`qmk` が引数の解析、設定、ログ、およびほかの多くの機能を処理するために使用する CLI フレームワークです。グルーコードを書くために時間を無駄にすることなく、ツールの作成に集中できます。 - -ローカル CLI 内のサブコマンドは、常に `qmk_firmware/lib/python/qmk/cli` で見つかります。 - -サブコマンドの例を見てみましょう。これは `lib/python/qmk/cli/hello.py` です: - -```python -"""QMK Python Hello World - -This is an example QMK CLI script. -""" -from milc import cli - - -@cli.argument('-n', '--name', default='World', help='Name to greet.') -@cli.subcommand('QMK Hello World.') -def hello(cli): - """Log a friendly greeting. - """ - cli.log.info('Hello, %s!', cli.config.hello.name) -``` - -最初に `milc` から `cli` をインポートします。これが、ユーザとやり取りをし、スクリプトの挙動を制御する方法です。`@cli.argument()` を使って、コマンドラインフラグ `--name` を定義します。これは、ユーザが設定できる `hello.name` (そして対応する `user.name`) という名前の設定変数も作成し、引数を指定する必要が無くなります。`cli.subcommand()` デコレータは、この関数をサブコマンドとして指定します。サブコマンドの名前は関数の名前から取られます。 - -関数の中に入ると、典型的な "Hello, World!" プログラムが見つかります。`cli.log` を使って、基礎となる [ロガーオブジェクト](https://docs.python.org/3.6/library/logging.html#logger-objects) にアクセスし、その挙動はユーザが制御できます。またユーザが指定した名前の値に `cli.config.hello.name` でアクセスします。`cli.config.hello.name` の値は、ユーザが指定した `--name` 引数を調べることで決定されます。指定されていない場合、`qmk.ini` 設定ファイルの中の値が使われ、どちらも指定されていない場合は `cli.argument()` デコレータで指定されたデフォルトが代用されます。 - -# ユーザとの対話処理 - -MILC と QMK CLI にはユーザとやり取りするための幾つかの便利なツールがあります。これらの標準ツールを使うと、テキストに色を付けて対話し易くし、ユーザはその情報をいつどのように表示および保存するかを制御することができます。 - -## テキストの表示 - -サブコマンド内でテキストを出力するための2つの主な方法があります- `cli.log` と `cli.echo()`。それらは似た方法で動作しますが、ほとんどの一般的な目的の出力には `cli.log.info()` を使うことをお勧めします。 - -特別なトークンを使用してテキストを色付けし、プログラムの出力を理解しやすくすることができます。以下の[テキストの色付け](#colorizing-text)を見てください。 - -これらの両方の方法は python の [printf 形式の文字列書式化](https://docs.python.org/3.6/library/stdtypes.html#old-string-formatting) を使った組み込みの文字列書式化をサポートします。テキスト文字列内で`%s` と `%d` のようなトークンを使い、引数で値を渡すことができます。例として、上記の Hello、World プログラムを見てください。 - -書式演算子 (`%`) を直接使わないでください、常に引数で値を渡します。 - -### ログ (`cli.log`) - -`cli.log` オブジェクトは[ロガーオブジェクト](https://docs.python.org/3.6/library/logging.html#logger-objects)へのアクセスを与えます。ログ出力を設定し、ユーザに各ログレベルの素敵な絵文字(またはターミナルが unicode をサポートしない場合はログレベル名)を表示します。このようにして、ユーザは何か問題が発生した時に最も重要なメッセージを一目で確認することができます。 - -デフォルトのログレベルは `INFO` です。ユーザが `qmk -v ` を実行すると、デフォルトのログレベルは `DEBUG` に設定されます。 - -| 関数 | 絵文字 | -|----------|-------| -| cli.log.critical | `{bg_red}{fg_white}¬_¬{style_reset_all}` | -| cli.log.error | `{fg_red}☒{style_reset_all}` | -| cli.log.warning | `{fg_yellow}⚠{style_reset_all}` | -| cli.log.info | `{fg_blue}Ψ{style_reset_all}` | -| cli.log.debug | `{fg_cyan}☐{style_reset_all}` | -| cli.log.notset | `{style_reset_all}¯\\_(o_o)_/¯` | - -### 出力 (`cli.echo`) - -場合によっては単にログシステムの外部でテキストを出力する必要があります。これは、固定データを出力したり、ログに記録してはいけない何かを書きだす場合に適しています。ほとんどの場合、`cli.echo` よりも `cli.log.info()` を選ぶべきです。 - -### テキストの色付け - -テキスト内に色トークンを含めることで、テキストの出力を色付けすることができます。情報を伝えるためではなく、強調するために色を使います。ユーザは色を無効にできることを覚えておいてください。色を無効にした場合でもサブコマンドは引き続き使えるようにしてください。 - -背景色を設定するのは、あなたがやっていることに不可欠ではない限り、通常は避けるべきです。ユーザは、ターミナルの色に関しては多くの好みを持つため、あなたは黒と白のどちらの背景に対してもうまく機能する色を選択する必要があることを覚えておいてください。 - -'fg' という接頭辞の付いた色は、前景(テキスト)色に影響します。'bg' という接頭辞の付いた色は、背景色に影響します。 - -| 色 | 背景 | 拡張背景 | 前景 | 拡張前景 | -|-------|------------|---------------------|------------|--------------------| -| 黒 | {bg_black} | {bg_lightblack_ex} | {fg_black} | {fg_lightblack_ex} | -| 青 | {bg_blue} | {bg_lightblue_ex} | {fg_blue} | {fg_lightblue_ex} | -| シアン | {bg_cyan} | {bg_lightcyan_ex} | {fg_cyan} | {fg_lightcyan_ex} | -| 緑 | {bg_green} | {bg_lightgreen_ex} | {fg_green} | {fg_lightgreen_ex} | -| マゼンタ | {bg_magenta} | {bg_lightmagenta_ex} | {fg_magenta} | {fg_lightmagenta_ex} | -| 赤 | {bg_red} | {bg_lightred_ex} | {fg_red} | {fg_lightred_ex} | -| 白 | {bg_white} | {bg_lightwhite_ex} | {fg_white} | {fg_lightwhite_ex} | -| 黄 | {bg_yellow} | {bg_lightyellow_ex} | {fg_yellow} | {fg_lightyellow_ex} | - -ANSI 出力の挙動を変更するために使うことができる制御シーケンスもあります。 - -| 制御シーケンス | 説明 | -|-------------------|-------------| -| {style_bright} | テキストを明るくする | -| {style_dim} | テキストを暗くする | -| {style_normal} | テキストを通常にする (`{style_bright}` または `{style_dim}` のどちらでもない) | -| {style_reset_all} | 全てのテキストの属性をデフォルトに再設定する(これは自動的に全ての文字列の最後に自動的に追加されます。) | -| {bg_reset} | 背景色をユーザのデフォルトに再設定します。 | -| {fg_reset} | 背景色をユーザのデフォルトに再設定します。 | - -# 引数と設定 - -QMK は引数の解析と設定の詳細をあなたの代わりに処理します。新しい引数を追加すると、サブコマンドの名前と引数の長い名前に基づいて設定ツリーに自動的に組み込まれます。属性形式のアクセス (`cli.config..`) あるいは辞書形式のアクセス (`cli.config['']['']`) を使って、`cli.config` 内のこの設定にアクセスすることができます。 - -内部では、QMK は [設定ファイルのパーサ](https://docs.python.org/3/library/configparser.html) を使って設定を格納します。これにより、人間が編集可能な方法で設定を表す簡単で分かり易い方法を提供します。この設定へのアクセスをラップして、設定ファイルのパーサーが通常持たない幾つかの機能を提供しています。 - -## 設定値の読み込み - -通常期待される全ての方法で `cli.config` とやり取りすることができます。例えば、`qmk compile` コマンドは `cli.config.compile.keyboard` からキーボード名を取得します。値がコマンドライン、環境変数あるいは設定ファイルからきたものであるかどうかを知る必要はありません。 - -繰り返しもサポートされます: - -``` -for section in cli.config: - for key in cli.config[section]: - cli.log.info('%s.%s: %s', section, key, cli.config[section][key]) -``` - -## 設定値の設定 - -通常の方法で設定値を設定することができます。 - -辞書形式: - -``` -cli.config['
'][''] = -``` - -属性形式: - -``` -cli.config.
. = -``` - -## 設定値の削除 - -通常の方法で設定値を削除することができます。 - -辞書形式: - -``` -del(cli.config['
']['']) -``` - -属性形式: - -``` -del(cli.config.
.) -``` - -## 設定ファイルの書き方 - -設定は変更しても書き出されません。ほとんどのコマンドでこれをする必要はありません。ユーザに `qmk config` を使って設定を慎重に変更させることをお勧めします。 - -設定を書き出すために `cli.save_config()` を使うことができます。 - -## 設定からの引数の除外 - -一部の引数は設定ファイルに反映すべきではありません。これらは引数を作成する時に `arg_only=True` を追加することで除外することができます。 - -例: - -``` -@cli.argument('-o', '--output', arg_only=True, help='File to write to') -@cli.argument('filename', arg_only=True, help='Configurator JSON file') -@cli.subcommand('Create a keymap.c from a QMK Configurator export.') -def json_keymap(cli): - pass -``` - -`cli.args` を使ってのみこれらの引数にアクセスすることができます。例えば: - -``` -cli.log.info('Reading from %s and writing to %s', cli.args.filename, cli.args.output) -``` - -# テスト、リントおよびフォーマット - -nose2、flake8 および yapf を使ってコードをテスト、リントおよびフォーマットします。これらのテストを実行するために `pytest` と `format-python` サブコマンドを使うことができます。 - -### テストとリント - - qmk pytest - -### フォーマット - - qmk format-python - -## フォーマットの詳細 - -[yapf](https://github.com/google/yapf) を使ってコードを自動的にフォーマットします。フォーマットの設定は `setup.cfg` の `[yapf]` セクションにあります。 - -?> ヒント- 多くのエディタは yapf をプラグインとして使って、入力したコードを自動的にフォーマットすることができます。 - -## テストの詳細 - -テストは `lib/python/qmk/tests/` にあります。このディレクトリに単体テストと統合テストの両方があります。コードの単体テストと統合テストの両方を書いてほしいですが、一方のみ書く場合は統合テストを優先してください。 - -PR にテストの包括的なセットが含まれない場合は、次のようなコメントをコードに追加して、他の人が手助けできるようにしてください: - - # TODO(unassigned/): Write tests - -[nose2](https://nose2.readthedocs.io/en/latest/getting_started.html) を使ってテストを実行します。テスト関数でできることの詳細については、nose2 のドキュメントを参照してください。 - -## リントの詳細 - -flake8 を使ってコードをリントします。PR を開く前に、コードは flake8 をパスしなければなりません。これは `qmk pytest` を実行するときにチェックされ、PR を登録したときに CI によってチェックされます。 diff --git a/docs/ja/coding_conventions_c.md b/docs/ja/coding_conventions_c.md deleted file mode 100644 index c3d2de734e1f..000000000000 --- a/docs/ja/coding_conventions_c.md +++ /dev/null @@ -1,63 +0,0 @@ -# コーディング規約 (C) - - - -私たちのスタイルのほとんどはかなり理解しやすいですが、現時点では完全に一貫しているわけではありません。変更箇所周辺のコードのスタイルと一致させる必要がありますが、そのコードに一貫性が無い場合や不明瞭な場合は以下のガイドラインに従ってください: - -* 4つのスペース (ソフトタブ) を使ってインデントします。 -* 修正版 One True Brace Style を使います。 - * 開き括弧: ブロックを開始する文と同じ行の最後 - * 閉じ括弧: ブロックを開始した文と同じ字下げ - * Else If: 行の先頭に閉じ括弧を置き、次の開き括弧を同じ行の最後に置きます。 - * 省略可能な括弧: 常に括弧を付け加えます。 - * 良い: if (condition) { return false; } - * 悪い: if (condition) return false; -* C 形式のコメントの使用を推奨します: `/* */` - * コメントを機能を説明するストーリーと考えて下さい。 - * 特定の決定がなされた理由を充分なコメントで説明してください。 - * 分かり切ったコメントは書かないでください。 - * 分かり切ったコメントであるか確信できない場合は、コメントを含めてください。 -* 一般的に、行を折り返さないで、必要なだけ長くすることができます。行を折り返すことを選択した場合は、76列を超えて折り返さないでください。 -* 古い形式のインクルードガード (`#ifndef THIS_FILE_H`、`#define THIS_FILE_H`、...、`#endif`) ではなく、ヘッダファイルの先頭で `#pragma once` を使います。 -* プリプロセッサ if の両方の形式を受け付けます: `#ifdef DEFINED` と `#if defined(DEFINED)` - * どちらがいいかわからない場合は、`#if defined(DEFINED)` 形式を使ってください。 - * 複数の条件 `#if` に移行する場合を除き、既存のコードを別のスタイルに変更しないでください。 -* プリプロセッサディレクティブをインデントする方法(あるいはするかどうか)を決定する時は、以下の事に留意してください: - * 一貫性よりも読みやすさが重要です。 - * ファイルの既存のスタイルに従ってください。ファイルのスタイルが混在している場合は、修正しようとしているセクションに適したスタイルに従ってください。 - * インデントする時は、ハッシュを行の先頭に置き、`#` と `if` の間に空白を追加します。`#` の後ろに4つスペースを入れて開始します。 - * 周りの C コードのインデントレベルに従うか、プリプロセッサのディレクティブに独自のインデントレベルを設定することができます。コードの意図を最もよく伝えるスタイルを選択してください。 - -わかりやすいように例を示します: - -```c -/* Enums for foo */ -enum foo_state { - FOO_BAR, - FOO_BAZ, -}; - -/* Returns a value */ -int foo(void) { - if (some_condition) { - return FOO_BAR; - } else { - return -1; - } -} -``` - -# clang-format を使った自動整形 - -[Clang-format](https://clang.llvm.org/docs/ClangFormat.html) は LLVM の一部で、誰もが手動で整形するほど暇ではないため、コードを自動整形することができます。私たちは、上記のコーディング規約のほとんどを適用する設定ファイルを提供しています。空白と改行のみを変更するため、省略可能な括弧は自分で付け加えることを忘れないでください。 - -Windows で clang-format を入手するには [full LLVM インストーラ](https://llvm.org/builds/)を使い、Ubuntu では `sudo apt install clang-format` を使ってください。 - -コマンドラインから実行する場合、オプションとして `-style=file` を渡すと、QMK ルートディレクトリ内の .clang-format 設定ファイルを自動的に見つけます。 - -VSCode を使う場合は、標準の C/C++ プラグインが clang-format をサポートしますが、その他にも [独立した拡張機能](https://marketplace.visualstudio.com/items?itemName=LLVMExtensions.ClangFormat) があります。 - -幾つかのコード (LAYOUT マクロのような)が clang-format によって破壊されるため、これらのファイルで clang-format を実行しないか、整形したくないコードを `// clang-format off` と `// clang-format on` で囲みます。 diff --git a/docs/ja/coding_conventions_python.md b/docs/ja/coding_conventions_python.md deleted file mode 100644 index d8d4a31503a3..000000000000 --- a/docs/ja/coding_conventions_python.md +++ /dev/null @@ -1,331 +0,0 @@ -# コーディング規約 (Python) - - - -私たちのスタイルの大部分は PEP8 に従いますが、神経質にならないように幾つかのローカルな変更を加えています。 - -* サポートされる全てのプラットフォームとの互換性のために、Python 3.6 を対象にしています。 -* 4つのスペース (ソフトタブ) を使ってインデントします -* 充分なコメントを書くことを推奨します - * コメントを機能を説明するストーリーと考えて下さい - * 特定の決定がなされた理由を充分なコメントで説明してください。 - * 分かり切ったコメントは書かないでください - * 分かり切ったコメントであるか確信できない場合は、コメントを含めてください。 -* 全ての関数について、役に立つ docstring を必要とします。 -* 一般的に、行を折り返さないで、必要なだけ長くすることができます。行を折り返すことを選択した場合は、76列を超えて折り返さないでください。 -* 私たちの慣習の幾つかは、Python 使いでは無い人にコードベースをより身近にするために、python コミュニティに広まっているものとは競合しています。 - -# YAPF - -コードを整形するために [yapf](https://github.com/google/yapf) を使うことができます。[setup.cfg](setup.cfg) で設定を提供しています。 - -# インポート - -`import ...` や `from ... import ...` をいつ使うかについての厳密なルールはありません。理解しやすさと保守性が究極の目的です。 - -一般的に、コードを短く理解しやすくするためにモジュールから特定の関数とクラス名をインポートする方が望ましいです。これにより、名前が曖昧になることがあります。代わりにモジュールをインポートするようにします。互換性のあるモジュールをインポートする時を除いて、インポートする時は "as" キーワードを避けるべきです。 - -インポートは各モジュール1行にする必要があります。標準的な python ルールに従って、インポート文をシステム、サードパーティ、ローカルにグループ化します。 - -`from foo import *` を使わないでください。代わりにインポートしたいオブジェクトのリストを指定するか、モジュール全体をインポートします。 - -## インポートの例 - -良い: - -``` -from qmk import effects - -effects.echo() -``` - -悪い: - -``` -from qmk.effects import echo - -echo() # echoがどこから来たのかが不明瞭です -``` - -良い: - -``` -from qmk.keymap import compile_firmware - -compile_firmware() -``` - -良いですが、上の方がより良いです: - -``` -import qmk.keymap - -qmk.keymap.compile_firmware() -``` - -# 命令文 - -各行1文としてください。 - -可能な場合(例えば `if foo: bar`)でも、2つの文を1行にまとめないでください。 - -# 命名 - -`module_name`, `package_name`, `ClassName`, `method_name`, `ExceptionName`, `function_name`, `GLOBAL_CONSTANT_NAME`, `global_var_name`, `instance_var_name`, `function_parameter_name`, `local_var_name`. - -関数名、変数名 およびファイル名は説明的でなければなりません; 略語を避けます。特に、プロジェクト外の読み手に曖昧あるいは馴染みのない略語を使わず、単語内の文字を削除して略さないでください。 - -常に .py のファイル名の拡張子を使います。ダッシュを使わないでください。 - -## 避けるべき名前 - -* カウンタあるいはイテレータ以外の1文字の名前。try/except 文では例外の識別子として `e` を使うことができます。 -* パッケージ/モジュール名内のダッシュ (`-`) -* `__double_leading_and_trailing_underscore__` (2つのアンダースコアで始まる名前と終わる名前、Python で予約済み) - -# Docstring - -docstring の一貫性を維持するために、以下のガイドラインを設定しました。 - -* マークダウン(Markdown)形式の使用 -* 常に少なくとも1つの改行を含む3つのダブルクォートの docstring を使ってください: `"""\n"""` -* 最初の行は、関数が行うことの短い (70文字未満) 説明です。 -* docstring が更に必要な場合は、説明と残りの間に空白行を入れます。 -* 開始の3つのダブルクォートと同じインデントレベルでインデント行を始めます -* 以下で説明する形式を使って全ての関数の引数について記述します -* Args:、Returns: および Raises: が存在する場合、それらは docstring の最後の3つの要素で、それぞれ空白行で区切られなければなりません。 - -## 簡単な docstring の例 - -``` -def my_awesome_function(): - """1970 Jan 1 00:00 UTC からの秒数を返します。 - """ - return int(time.time()) -``` - -## 複雑な docstring の例 - -``` -def my_awesome_function(): - """1970 Jan 1 00:00 UTC からの秒数を返します。 - - この関数は常に整数の秒数を返します。 - """ - return int(time.time()) -``` - -## 関数の引数の docstring の例 - -``` -def my_awesome_function(start=None, offset=0): - """1970 Jan 1 00:00 UTC からの秒数を返します。 - - この関数は常に整数の秒数を返します。 - - - Args: - start - 1970 Jan 1 00:00 UTC の代わりの開始時間 - - offset - 最初の引数からこの秒数が引かれた答えを返します - - Returns: - 秒数を表す整数。 - - Raises: - ValueError - `start` あるいは `offset` が正の数ではない場合 - """ - if start < 0 or offset < 0: - raise ValueError('start and offset must be positive numbers.') - - if not start: - start = time.time() - - return int(start - offset) -``` - -# 例外 - -例外は例外的な状況を処理するために使われます。フローの制御のために使われるべきではありません。これは Python の「許しを請う」という規範からの逸脱です。例外をキャッチする場合、異常な状況を処理する必要があります。 - -何らかの理由で全ての例外のキャッチを使う場合は、cli.log を使って例外とスタックトレースを記録する必要があります。 - -try/except ブロックをできるだけ短くします。多数の try 文が必要な場合は、コードを再構成する必要があるかもしれません。 - -# タプル - -1項目のタプルを定義する場合、タプルを使用していることが明らかになるように、常に末尾のカンマを含めます。暗黙的な1項目のタプルのアンパックに頼らないでください。明確なリストを使う方が良いです。 - -これはよく使用される printf 形式の書式文字列を使う場合に、特に重要です。 - -# リストと辞書 - -シーケンス形式と末尾のカンマとを区別するように YAPF を設定しました。末尾のカンマが省略されると、YAPF はシーケンスを1つの行として整形します。末尾のカンマがある場合、YAPF はシーケンスを1行1項目で整形します。 - -一般的に1行が短い定義になるようにすべきです。読みやすさと保守性を向上させるために、後からではなく早めに複数の行を分割してください。 - -# 括弧 - -過度な括弧は避けますが、括弧を使ってコードを理解しやすくします。タプルを明示的に返すか、あるいは数式の一部である場合を除き、return 文で括弧を使わないでください。 - -# 書式文字列 - -一般的に printf 形式の書式文字列を用います。例: - -``` -name = 'World' -print('Hello, %s!' % (name,)) -``` - -このスタイルはログモジュールで使われており、私たちはそれを広範囲で利用しており、一貫性を保つために他の場所でも採用しています。これは、私たちの気まぐれな読者の大部分である C プログラマにもおなじみのスタイルです。 - -付属の CLI モジュールは、パーセント (%) 演算子を使わずにこれらを使うことをサポートしています。詳細は、`cli.echo()` と様々な `cli.log` 関数 (例えば、`cli.log.info()`) を見てください。 - -# 内包表記とジェネレータ表記 - -内包表記とジェネレータの自由な使用を推奨しますが、あまりに複雑にしないでください。複雑になる場合は、理解しやすい for ループで代替します。 - -# ラムダ - -使っても問題ありませんが、おそらく避けるべきです。内包表記とジェネレータを使えば、ラムダの必要性は以前ほど強くありません。 - -# 条件式 - -変数の割り当てでは問題ありませんが、そうでなければ避けるべきです。 - -条件式はコードに続く if 文です。例えば: - -``` -x = 1 if cond else 2 -``` - -一般にこれらを関数の引数、シーケンス項目などとして使用することはお勧めできません。見落としやすくなります。 - -# デフォルト引数 - -推奨されていますが、値は不変オブジェクトでなければなりません。 - -デフォルト値に引数リストを指定する場合は、その場で変更できないオブジェクトを指定するように常に注意してください。可変オブジェクトを使うと変更は呼び出しの間で持続しますが、これは通常あなたの望むものではありませんそれがあなたのやろうとしていることであっても、他の人にとっては混乱するもので理解を妨げます。 - -悪い: - -``` -def my_func(foo={}): - pass -``` - -良い: - -``` -def my_func(foo=None): - if not foo: - foo = {} -``` - -# プロパティ - -getter および setter 関数の代わりにプロパティを常に使います。 - -``` -class Foo(object): - def __init__(self): - self._bar = None - - @property - def bar(self): - return self._bar - - @bar.setter - def bar(self, bar): - self._bar = bar -``` - -# True/False の評価 - -一般的に、if 文で等価性を調べるのではなく、暗黙的な True/False 評価を行うべきです。 - -悪い: - -``` -if foo == True: - pass - -if bar == False: - pass -``` - -良い: - -``` -if foo: - pass - -if not bar: - pass -``` - -# デコレータ - -適切な時に使ってください。理解に役立つ時を除き、魔法の(ように見える技巧の)使いすぎは避けるようにしてください。 - -# スレッドとマルチプロセス - -避けるべきです。これが必要な場合は、私たちがコードをマージする前に十分な理由を述べる必要があります。 - -# 強力な機能 - -Python は非常に柔軟な言語で、独自のメタクラス、バイトコードへのアクセス、実行中コンパイル、動的な継承、オブジェクトの親の変更、インポートハック、リフレクション、システム内部の変更など、多くの素晴らしい機能を提供します。 - -これらを使わないでください。 - -パフォーマンスは私たちにとって重要な関心ごとではなく、コードのわかりやすさに関心があります。私たちは、コードベースを1日か2日しかいじっていない人が利用できるようにしたいです。これらの機能は一般的に理解のしやすさを犠牲にするため、より高速あるいはよりコンパクトなコードよりも、容易に理解できるコードの方が望ましいです。 - -一部の標準ライブラリモジュールはこれらの手法を使っており、これらのモジュールを利用しても問題ありません。ただし、それらを使う時には、読みやすさと理解のしやすさを忘れないでください。 - -# 型アノテーション付きコード - -今のところ型アノテーションシステムを使っていないため、コードにアノテーションをつけないようにしてください。将来的にはこれを再検討する可能性があります。 - -# 関数の長さ - -小さくて焦点のあった関数にしてください。 - -長い関数が時には適切であることを理解しているので、関数の長さには厳密な制限はありません。関数が約40行を超える場合は、プログラムの構造を損なわずに分割できるかどうかを検討してください。 - -今のところ長い関数が完全に機能するとしても、数か月でそれを変更する人が新しい挙動を追加するかもしれません。これにより見つけにくいバグが発生するかもしれません。関数を短くかつシンプルにすることで、他の人がコードを読んで修正しやすくします。 - -幾つかのコードで作業をすると、長く複雑な関数を見つけるかもしれません。既存コードを変更することを怖がらないでください: もし、難しいことが判明したり、エラーがデバッグしづらいとわかったり、いくつかの異なるコンテキストで一部を使いたいような関数を扱っている場合、関数を小さくてより扱いやすい単位に分割することを検討してください。 - -# FIXME - -FIXME をコードに残しても構いません。なぜでしょうか?このコードを文章化しないままにするよりも、少なくとも考え抜く必要がある(あるいは混乱している)コードの一部を文章化するように奨励する方が、このコードを文章化しないままにするよりも良いです。 - -全ての FIXME は以下のように書式化されるべきです: - -``` -FIXME(username): 何々機能が完了したらこのコードを再検討する。 -``` - -...username はあなたの GitHub のユーザ名です。 - -# テスト - -統合テストと単体テストの組み合わせを使ってコードが可能な限りバグが無いようにします。全てのテストは `lib/python/qmk/tests/` にあります。`qmk pytest` を使って全てのテストを実行することができます。 - -これを書いている時点では、テストは全く完全なものではありません。現在のテストを見て、テストされていない状況のための新しいテストケースを書くことは、コードベースに精通し、QMK に貢献するという両方の点で素晴らしい方法です。 - -## 統合テスト - -統合テストは `lib/python/qmk/tests/test_cli_commands.py` にあります。ここで実際に CLI コマンドが実行され、全体的な動作が検証されます。[`subprocess`](https://docs.python.org/3.6/library/subprocess.html#module-subprocess) を使って各 CLI コマンドを起動し、正しく動作するかを判断するために出力とリターンコードの組み合わせを使います。 - -## ユニットテスト - -`lib/python/qmk/tests/` 内の他の `test_*.py` ファイルはユニットテストを含みます。`lib/python/qmk/` 内の個々の関数のテストをここに書くことができます。一般的にこれらのファイルはモジュールに基づいて名前を付けられ、ドットはアンダースコアで置き換えられます。 - -これを書いている時点では、テストのためのモックを作っていません。これを変更する手伝いをしたい場合は、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=) か [Discord の #cli に参加](https://discord.gg/heQPAgy)し、そこで会話を開始してください。 diff --git a/docs/ja/compatible_microcontrollers.md b/docs/ja/compatible_microcontrollers.md deleted file mode 100644 index 23f32bbb60e8..000000000000 --- a/docs/ja/compatible_microcontrollers.md +++ /dev/null @@ -1,54 +0,0 @@ -# 互換性のあるマイクロコントローラ - - - -QMK は十分な容量のフラッシュメモリを備えた USB 対応 AVR または ARM マイクロコントローラで実行されます - 一般的に 32kB 以上ですが、ほとんどの機能を無効にすると*ほんの* 16kB に詰め込むことができます。 - -## Atmel AVR - -以下は、USB スタックとして [LUFA](https://www.fourwalledcubicle.com/LUFA.php) を使います: - -* [ATmega16U2](https://www.microchip.com/wwwproducts/en/ATmega16U2) / [ATmega32U2](https://www.microchip.com/wwwproducts/en/ATmega32U2) -* [ATmega16U4](https://www.microchip.com/wwwproducts/en/ATmega16U4) / [ATmega32U4](https://www.microchip.com/wwwproducts/en/ATmega32U4) -* [AT90USB64](https://www.microchip.com/wwwproducts/en/AT90USB646) / [AT90USB128](https://www.microchip.com/wwwproducts/en/AT90USB1286) -* [AT90USB162](https://www.microchip.com/wwwproducts/en/AT90USB162) - -組み込みの USB インターフェースを持たない、いくつかの MCU は代わりに [V-USB](https://www.obdev.at/products/vusb/index.html) を使います: - -* [ATmega32A](https://www.microchip.com/wwwproducts/en/ATmega32A) -* [ATmega328P](https://www.microchip.com/wwwproducts/en/ATmega328P) -* [ATmega328](https://www.microchip.com/wwwproducts/en/ATmega328) - -## ARM - -[ChibiOS](https://www.chibios.org) がサポートする USB 付きの ARM チップを使うこともできます。ほとんどのチップには十分な容量のフラッシュメモリがあります。動作するとわかっているのは: - -### STMicroelectronics (STM32) - -* [STM32F0x2](https://www.st.com/en/microcontrollers-microprocessors/stm32f0x2.html) -* [STM32F103](https://www.st.com/en/microcontrollers-microprocessors/stm32f103.html) -* [STM32F303](https://www.st.com/en/microcontrollers-microprocessors/stm32f303.html) -* [STM32F401](https://www.st.com/en/microcontrollers-microprocessors/stm32f401.html) -* [STM32F405](https://www.st.com/en/microcontrollers-microprocessors/stm32f405-415.html) -* [STM32F407](https://www.st.com/en/microcontrollers-microprocessors/stm32f407-417.html) -* [STM32F411](https://www.st.com/en/microcontrollers-microprocessors/stm32f411.html) -* [STM32F446](https://www.st.com/en/microcontrollers-microprocessors/stm32f446.html) -* [STM32G431](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x1.html) -* [STM32G474](https://www.st.com/en/microcontrollers-microprocessors/stm32g4x4.html) -* [STM32L412](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) -* [STM32L422](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x2.html) -* [STM32L433](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) -* [STM32L443](https://www.st.com/en/microcontrollers-microprocessors/stm32l4x3.html) - -### NXP (Kinetis) - -* [MKL26Z64](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/kl-series-cortex-m0-plus/kinetis-kl2x-72-96-mhz-usb-ultra-low-power-microcontrollers-mcus-based-on-arm-cortex-m0-plus-core:KL2x) -* [MK20DX128](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-50-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-based-on-arm-cortex-m4-core:K20_50) -* [MK20DX256](https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/k-series-cortex-m4/k2x-usb/kinetis-k20-72-mhz-full-speed-usb-mixed-signal-integration-microcontrollers-mcus-based-on-arm-cortex-m4-core:K20_72) - -## Atmel ATSAM - -Atmel の ATSAM マイクロコントローラの一つである、[Massdrop keyboards](https://github.com/qmk/qmk_firmware/tree/master/keyboards/massdrop) で使用されている [ATSAMD51J18A](https://www.microchip.com/wwwproducts/en/ATSAMD51J18A) には限定的なサポートがあります。 diff --git a/docs/ja/config_options.md b/docs/ja/config_options.md deleted file mode 100644 index 5e98da5eee69..000000000000 --- a/docs/ja/config_options.md +++ /dev/null @@ -1,410 +0,0 @@ -# QMK の設定 - - - -QMK はほぼ無制限に設定可能です。可能なところはいかなるところでも、やりすぎな程、ユーザーがコードサイズを犠牲にしてでも彼らのキーボードをカスタマイズをすることを許しています。ただし、このレベルの柔軟性により設定が困難になります。 - -QMK には主に2種類の設定ファイルがあります- `config.h` と `rules.mk`。これらのファイルは QMK の様々なレベルに存在し、同じ種類の全てのファイルは最終的な設定を構築するために組み合わされます。最低の優先度から最高の優先度までのレベルは以下の通りです: - -* QMK デフォルト -* キーボード -* フォルダ (最大5レべルの深さ) -* キーマップ - -## QMK デフォルト - -QMK での全ての利用可能な設定にはデフォルトがあります。その設定がキーボード、フォルダ、あるいはキーマップレべルで設定されない場合、これが使用される設定です。 - -## キーボード - -このレベルにはキーボード全体に適用される設定オプションが含まれています。一部の設定は、リビジョンあるいはほとんどのキーマップで変更されません。他の設定はこのキーボードのデフォルトに過ぎず、フォルダあるいはキーマップによって上書きされる可能性があります。 - -## フォルダ - -一部のキーボードには、異なるハードウェア構成のためのフォルダとサブフォルダがあります。ほとんどのキーボードは深さ1のフォルダのみですが、QMK は最大深さ5のフォルダの構造をサポートします。各フォルダは、最終的な設定に組み込まれる独自の `config.h` と `rules.mk` ファイルを持つことができます。 - -## キーマップ - -このレベルには特定のキーマップのための全てのオプションが含まれています。以前の定義を上書きしたい場合は、`#undef ` を使って定義を解除し、エラー無しで再定義することができます。 - -# `config.h` ファイル - -これは最初に include されるものの 1 つである C ヘッダファイルで、プロジェクト全体(もし含まれる場合)にわたって持続します。多くの変数をここで設定し、他の場所からアクセスすることができます。`config.h` ファイルでは、以下のもの以外の、他の `config.h` ファイルやその他のファイルの include をしないでください: - -```c -#include "config_common.h" -``` - - -## ハードウェアオプション -* `#define VENDOR_ID 0x1234` - * VID を定義します。ほとんどの DIY プロジェクトにおいて、任意のものを定義できます -* `#define PRODUCT_ID 0x5678` - * PID を定義します。ほとんどの DIY プロジェクトでは、任意のものを定義できます -* `#define DEVICE_VER 0` - * デバイスのバージョンを定義します (多くの場合リビジョンに使われます) -* `#define MANUFACTURER Me` - * 一般的に、誰もしくはどのブランドがボードを作成したか -* `#define PRODUCT Board` - * キーボードの名前 -* `#define MATRIX_ROWS 5` - * キーボードのマトリックスの行の数 -* `#define MATRIX_COLS 15` - * キーボードのマトリックスの列の数 -* `#define MATRIX_ROW_PINS { D0, D5, B5, B6 }` - * 行のピン、上から下へ -* `#define MATRIX_COL_PINS { F1, F0, B0, C7, F4, F5, F6, F7, D4, D6, B4, D7 }` - * 列のピン、左から右へ -* `#define MATRIX_IO_DELAY 30` - * マトリックスピン状態の変更と値の読み取り間のマイクロ秒単位の遅延 -* `#define UNUSED_PINS { D1, D2, D3, B1, B2, B3 }` - * 参考として、キーボードで使われていないピン -* `#define MATRIX_HAS_GHOST` - * マトリックスにゴーストがあるか(ありそうにないか)定義します -* `#define DIODE_DIRECTION COL2ROW` - * COL2ROW あるいは ROW2COL - マトリックスがどのように設定されているか。COL2ROW は、スイッチとロウ(行)ラインの間にダイオードが黒い印をロウ(行)ラインに向けて置いてあることを意味します。 -* `#define DIRECT_PINS { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` - * ロウ(行)ラインとカラム(列)ラインにマップされているピンを左から右に。各スイッチが個別のピンとグラウンドに接続されているマトリックスを定義します。 -* `#define AUDIO_VOICES` - * (循環させるために)代替音声を有効にします -* `#define C4_AUDIO` - * ピン C4 のオーディオを有効にします - * 非推奨。`#define AUDIO_PIN C4` を使ってください -* `#define C5_AUDIO` - * ピン C5 のオーディオを有効にします - * 非推奨。`#define AUDIO_PIN C5` を使ってください -* `#define C6_AUDIO` - * ピン C6 のオーディオを有効にします - * 非推奨。`#define AUDIO_PIN C6` を使ってください -* `#define B5_AUDIO` - * ピン B5 のオーディオを有効にします (C ピンの1つとともに B ピンの1つが有効にされている場合、疑似ステレオが有効にされます) - * 非推奨。もし `AUDIO_PIN` で `C` ピンを有効にしている場合は、`#define AUDIO_PIN_ALT B5` を使い、そうでなければ `#define AUDIO_PIN B5` を使います。 -* `#define B6_AUDIO` - * ピン B6 のオーディオを有効にします (C ピンの1つとともに B ピンの1つが有効にされている場合、疑似ステレオが有効にされます) - * 非推奨。もし `AUDIO_PIN` で `C` ピンを有効にしている場合は、`#define AUDIO_PIN_ALT B6` を使い、そうでなければ `#define AUDIO_PIN B6` を使います。 -* `#define B7_AUDIO` - * ピン B7 のオーディオを有効にします (C ピンの1つとともに B ピンの1つが有効にされている場合、疑似ステレオが有効にされます) - * 非推奨。もし `AUDIO_PIN` で `C` ピンを有効にしている場合は、`#define AUDIO_PIN_ALT B7` を使い、そうでなければ `#define AUDIO_PIN B7` を使います。 -* `#define BACKLIGHT_PIN B7` - * バックライトのピン -* `#define BACKLIGHT_LEVELS 3` - * バックライトのレベル数 (off を除いて最大31) -* `#define BACKLIGHT_BREATHING` - * バックライトのブレスを有効にします -* `#define BREATHING_PERIOD 6` - * 1つのバックライトの "ブレス" の長さの秒数 -* `#define DEBOUNCE 5` - * ピンの値を読み取る時の遅延 (5がデフォルト) -* `#define LOCKING_SUPPORT_ENABLE` - * メカニカルロックのサポート。キーマップで KC_LCAP、KC_LNUM そして KC_LSCR を使えるようにします -* `#define LOCKING_RESYNC_ENABLE` - * キーボードの LED の状態をスイッチの状態と一致させ続けようとします -* `#define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT)` - * マジックコマンドの使用を可能にするキーの組み合わせ (デバッグに便利です) -* `#define USB_MAX_POWER_CONSUMPTION 500` - * デバイスの USB 経由の最大電力(mA) を設定します (デフォルト: 500) -* `#define USB_POLLING_INTERVAL_MS 10` - * キーボード、マウス および 共有 (NKRO/メディアキー) インタフェースのための USB ポーリングレートをミリ秒で設定します -* `#define USB_SUSPEND_WAKEUP_DELAY 0` - * ウェイクアップパケットを送信した後で一時停止するミリ秒を設定します -* `#define F_SCL 100000L` - * I2C を使用するキーボードのための I2C クロックレート速度を設定します。デフォルトは `400000L` ですが、`split_common` を使っているキーボードは別でデフォルトは `100000L` です。 - -## 無効にできる機能 - -これらのオプションを定義すると、関連する機能が無効になり、コードサイズを節約できます。 - -* `#define NO_DEBUG` - * デバッグを無効にします -* `#define NO_PRINT` - * hid_listen を使った出力やデバッグを無効にします -* `#define NO_ACTION_LAYER` - * レイヤーを無効にします -* `#define NO_ACTION_TAPPING` - * タップダンスと他のタップ機能を無効にします -* `#define NO_ACTION_ONESHOT` - * ワンショットモディファイアを無効にします -* `#define NO_ACTION_MACRO` - * `MACRO()`、`action_get_macro()` _(非推奨)_ を使う古い形式のマクロ処理を無効にします -* `#define NO_ACTION_FUNCTION` - * `fn_actions`、`action_function()` _(非推奨)_ を使う古い形式の関数処理を無効にします - -## 有効にできる機能 - -これらのオプションを定義すると、関連する機能が有効になり、コードサイズが大きくなるかもしれません。 - -* `#define FORCE_NKRO` - * NKRO をデフォルトでオンにする必要があります。これにより EEPROM の設定に関係なく、キーボードの起動時に NKRO が強制的にオンになります。NKRO は引き続きオフにできますが、キーボードを再起動すると再びオンになります。 -* `#define STRICT_LAYER_RELEASE` - * キーリリースがどのレイヤーから来たのかを覚えるのではなく、現在のレイヤースタックを使って強制的に評価されるようにします (高度なケースに使われます) - -## 設定可能な挙動 :id=behaviors-that-can-be-configured - -* `#define TAPPING_TERM 200` - * タップがホールドになるまでの時間。 -* `#define TAPPING_TERM_PER_KEY` - * キーごとの `TAPPING_TERM` 設定の処理を有効にします -* `#define RETRO_TAPPING` - * 押下とリリースの間に他のキーによる中断がなければ、TAPPING_TERM の後であってもとにかくタップします - * 詳細は [Retro Tapping](ja/tap_hold.md#retro-tapping) を見てください -* `#define RETRO_TAPPING_PER_KEY` - * キーごとの `RETRO_TAPPING` 設定の処理を有効にします -* `#define TAPPING_TOGGLE 2` - * トグルを引き起こす前のタップ数 -* `#define PERMISSIVE_HOLD` - * `TAPPING_TERM` にヒットしていなくても、リリースする前に別のキーが押されると、タップとホールドキーがホールドを引き起こします - * 詳細は [Permissive Hold](ja/tap_hold.md#permissive-hold) を見てください -* `#define PERMISSIVE_HOLD_PER_KEY` - * キーごとの `PERMISSIVE_HOLD` 設定の処理を有効にします -* `#define TAPPING_FORCE_HOLD` - * タップされた直後に、デュアルロールキーを修飾子として使用できるようにします - * [Tapping Force Hold](ja/tap_hold.md#tapping-force-hold)を見てください - * タップトグル機能を無効にします (`TT` あるいは One Shot Tap Toggle) -* `#define TAPPING_FORCE_HOLD_PER_KEY` - * キーごとの `TAPPING_FORCE_HOLD` 設定処理を有効にします。 -* `#define LEADER_TIMEOUT 300` - * リーダーキーがタイムアウトするまでの時間 - * タイムアウトする前にシーケンスを終了できない場合は、タイムアウトの設定を増やす必要があるかもしれません。あるいは、`LEADER_PER_KEY_TIMING` オプションを有効にすると良いでしょう。これは各キーがタップされた後でタイムアウトを再設定します。 -* `#define LEADER_PER_KEY_TIMING` - * 全体では無く各キーを押すたびに実行されるリーダーキーコードのタイマーを設定します -* `#define LEADER_KEY_STRICT_KEY_PROCESSING` - * Mod-Tap および Layer-Tap キーコードのためのキーコードフィルタリングを無効にします。例えば、これを有効にすると、`KC_A` を使いたい場合は `MT(MOD_CTL, KC_A)` を指定する必要があります。 -* `#define ONESHOT_TIMEOUT 300` - * ワンショットがタイムアウトするまでの時間 -* `#define ONESHOT_TAP_TOGGLE 2` - * ワンショットトグルが引き起こされるまでのタップ数 -* `#define COMBO_TERM 200` - * コンボキーが検出されるまでの時間。定義されていない場合は、デフォルトは `TAPPING_TERM` です。 -* `#define TAP_CODE_DELAY 100` - * 適切な登録に問題がある場合(VUSB ボードで珍しくない)、`register_code` と `unregister_code` の間の遅延を設定します。値はミリ秒です。 -* `#define TAP_HOLD_CAPS_DELAY 80` - * MacOS で特別な処理が行われるため、`KC_CAPSLOCK` を使う時にタップホールドキー (`LT`, `MT`) に遅延を設定します。この値はミリ秒で、定義されていない場合はデフォルトは80msです。macOS については、これを200以上に設定すると良いでしょう。 - -## RGB ライト設定 :id=rgb-light-configuration - -* `#define RGB_DI_PIN D7` - * WS2812 の DI 端子につなぐピン -* `#define RGBLIGHT_LAYERS` - * オンとオフを切り替えることができる [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) を定義できます。現在のキーボードレイヤーまたは Caps Lock 状態を表示するのに最適です。 -* `#define RGBLIGHT_MAX_LAYERS` - * デフォルトは8です。もしさらに [ライトレイヤー](ja/feature_rgblight.md?id=lighting-layers) が必要であれば、32まで拡張できます。 - * メモ: 最大値を大きくするとファームウェアサイズが大きくなり、分割キーボードで同期が遅くなります。 -* `#define RGBLIGHT_LAYER_BLINK` - * 指定されたミリ秒の間、ライトレイヤーを [点滅](ja/feature_rgblight.md?id=lighting-layer-blink) する機能を追加します(例えば、アクションを確認するため)。 -* `#define RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF` - * 定義されている場合、RGB ライトがオフになっている場合でも [ライトレイヤー](ja/feature_rgblight?id=overriding-rgb-lighting-onoff-status) が表示されます。 -* `#define RGBLED_NUM 12` - * LED の数 -* `#define RGBLIGHT_SPLIT` - * 分割キーボードの左半分の RGB LED の出力を右半分の RGB LED の入力につなげるかわりに、それぞれの側で個別にコントローラの出力ピンが直接 RGB LED の入力に繋がっているときは、この定義が必要です。 -* `#define RGBLED_SPLIT { 6, 6 }` - * 分割キーボードの各半分の `RGB_DI_PIN` に直接配線されている接続されている LED の数 - * 最初の値は左半分の LED の数を示し、2番目の値は右半分です。 - * RGBLED_SPLIT が定義されている場合、RGBLIGHT_SPLIT は暗黙的に定義されます。 -* `#define RGBLIGHT_HUE_STEP 12` - * 色相の増減時のステップ単位 -* `#define RGBLIGHT_SAT_STEP 25` - * 彩度の増減時のステップ単位 -* `#define RGBLIGHT_VAL_STEP 12` - * 値(明度)の増減時のステップ単位 -* `#define RGBW` - * RGBW LED のサポートを有効にします - -## マウスキーオプション - -* `#define MOUSEKEY_INTERVAL 20` -* `#define MOUSEKEY_DELAY 0` -* `#define MOUSEKEY_TIME_TO_MAX 60` -* `#define MOUSEKEY_MAX_SPEED 7` -* `#define MOUSEKEY_WHEEL_DELAY 0` - -## 分割キーボードオプション - -分割キーボード固有のオプション。あなたの rules.mk に 'SPLIT_KEYBOARD = yes' が有ることを確認してください。 - -* `SPLIT_TRANSPORT = custom` - * 標準の分割通信ルーチンをカスタムのものに置き換えることができます。現在、ARM ベースの分割キーボードはこれを使わなければなりません。 - -### 左右の設定 - -1つ覚えておかなければならないことは、USB ポートが接続されている側が常にマスター側であるということです。USB に接続されていない側はスレーブです。 - -分割キーボードの左右を設定するには、幾つかの異なる方法があります (優先度の順にリストされています): - -1. `SPLIT_HAND_PIN` を設定します: 左右を決定するためにピンを読み込みます。ピンが high の場合、それが左側です。low であれば、その半分側が右側であると決定されます。 -2. `EE_HANDS` を設定し、各半分に `eeprom-lefthand.eep`/`eeprom-righthand.eep` を書き込みます - * DFU ブートローダを搭載したボードでは、これらの EEPROM ファイルを書き込むために `:dfu-split-left`/`:dfu-split-right` を使うことができます - * Caterina ブートローダを搭載したボード (標準的な Pro Micros など)では、`:avrdude-split-left`/`:avrdude-split-right` を使ってください - * ARM DFU ブートローダを搭載したボード (Proton C など)では、`:dfu-util-split-left`/`:dfu-util-split-right` を使ってください -3. `MASTER_RIGHT` を設定します: USB ポートに差し込まれた側はマスター側で右側であると決定されます(デフォルトの逆) -4. デフォルト: USB ポートに差し込まれている側がマスター側であり、左側であると見なされます。スレーブ側は右側です - -#### 左右を定義します - -* `#define SPLIT_HAND_PIN B7` - * high/low ピンを使って左右を決定します。low = 右手、high = 左手。`B7` を使っているピンに置き換えます。これはオプションで、`SPLIT_HAND_PIN` が未定義のままである場合、EE_HANDS メソッドまたは標準の Let's Splitが使っている MASTER_LEFT / MASTER_RIGHT 定義をまだ使うことができます。 - -* `#define SPLIT_HAND_MATRIX_GRID ,` - * 左右はキーマトリックスのキースイッチが存在しない交点を使って決定されます。通常、この交点が短絡している(ローレベル)のときに左側と見なされます。もし `#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT` が定義されている場合は、ローレベルの時に右側と決定されます。 - -* `#define EE_HANDS` (`SPLIT_HAND_PIN` と `SPLIT_HAND_MATRIX_GRID` が定義されていない場合のみ動作します) - * `eeprom-lefthand.eep`/`eeprom-righthand.eep` がそれぞれの半分に書き込まれた後で、EEPROM 内に格納されている左右の設定の値を読み込みます。 - -* `#define MASTER_RIGHT` - * マスター側が右側と定義されます。 - -### 他のオプション - -* `#define USE_I2C` - * Serial の代わりに I2C を使う場合 (デフォルトは serial) - -* `#define SOFT_SERIAL_PIN D0` - * serial を使う場合、これを定義します。`D0` あるいは `D1`,`D2`,`D3`,`E6`。 - -* `#define MATRIX_ROW_PINS_RIGHT { }` -* `#define MATRIX_COL_PINS_RIGHT { }` - * 右半分に左半分と異なるピン配置を指定したい場合は、`MATRIX_ROW_PINS_RIGHT`/`MATRIX_COL_PINS_RIGHT` を定義することができます。現在のところ、`MATRIX_ROW_PINS` のサイズは `MATRIX_ROW_PINS_RIGHT` と同じでなければならず、列の定義も同様です。 - -* `#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } }` - * 右半分に左半分と異なる直接ピン配置を指定したい場合は、`DIRECT_PINS_RIGHT` を定義することができます。現在のところ、`DIRECT_PINS` のサイズは `DIRECT_PINS_RIGHT` と同じでなければなりません。 - -* `#define RGBLED_SPLIT { 6, 6 }` - * [RGB ライト設定](#rgb-light-configuration)を見てください。 - -* `#define SELECT_SOFT_SERIAL_SPEED ` (デフォルトの速度は1です) - * serial 通信を使う時のプロトコルの速度を設定します。 - * 速度: - * 0: 約 189kbps (実験目的のみ) - * 1: 約 137kbps (デフォルト) - * 2: 約 75kbps - * 3: 約 39kbps - * 4: 約 26kbps - * 5: 約 20kbps - -* `#define SPLIT_USB_DETECT` - * マスタ/スレーブを委任する時に(タイムアウト付きで) USB 接続を検出します - * ARM についてはデフォルトの挙動 - * AVR Teensy については必須 - -* `#define SPLIT_USB_TIMEOUT 2000` - * `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合の最大タイムアウト - -* `#define SPLIT_USB_TIMEOUT_POLL 10` - * `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合のポーリング頻度 - -# `rules.mk` ファイル - -これは、トップレベルの `Makefile` から include される [make](https://www.gnu.org/software/make/manual/make.html) ファイルです。これは特定の機能を有効または無効にするだけでなく、コンパイルする MCU に関する情報を設定するために使われます。 - -## ビルドオプション - -* `DEFAULT_FOLDER` - * キーボードに1つ以上のサブフォルダがある場合にデフォルトのフォルダを指定するために使われます。 -* `FIRMWARE_FORMAT` - * ビルドの後でルート `qmk_firmware` フォルダにコピーされる形式 (bin, hex) を定義します。 -* `SRC` - * コンパイル・リンクリストにファイルを追加するために使われます。 -* `LIB_SRC` - * コンパイル・リンクリストにライブラリとしてファイルを追加するために使われます。 - `LIB_SRC` で指定されたファイルは、`SRC` で指定されたファイルの後にリンクされます。 - 例えば、次のように指定した場合: - ``` - SRC += a.c - LIB_SRC += lib_b.c - SRC += c.c - LIB_SRC += lib_d.c - ``` - リンク順は以下の通りです。 - ``` - ... a.o c.o ... lib_b.a lib_d.a ... - ``` -* `LAYOUTS` - * このキーボードがサポートする[レイアウト](ja/feature_layouts.md)のリスト -* `LTO_ENABLE` - * キーボードをコンパイルする時に、Link Time Optimization (LTO) を有効にします。これは処理に時間が掛かりますが、コンパイルされたサイズを大幅に減らします (そして、ファームウェアが小さいため、追加の時間は分からないくらいです)。 -ただし、LTO が有効な場合、古い TMK のマクロと関数の機能が壊れるため、自動的にこれらの機能を無効にします。これは `NO_ACTION_MACRO` と `NO_ACTION_FUNCTION` を自動的に定義することで行われます。(メモ: これは QMK の [マクロ](ja/feature_macros.md) と [レイヤー](ja/feature_layers.md) には影響を与えません。) - -## AVR MCU オプション -* `MCU = atmega32u4` -* `F_CPU = 16000000` -* `ARCH = AVR8` -* `F_USB = $(F_CPU)` -* `OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT` -* `BOOTLOADER = atmel-dfu` と以下のオプション: - * `atmel-dfu` - * `lufa-dfu` - * `qmk-dfu` - * `halfkay` - * `caterina` - * `bootloadHID` - * `USBasp` - -## 機能オプション :id=feature-options - -これらを使って特定の機能のビルドを有効または無効にします。有効にすればするほどファームウェアが大きくなり、MCU には大きすぎるファームウェアを構築するリスクがあります。 - -* `BOOTMAGIC_ENABLE` - * ブートマジックライトを有効にします -* `MOUSEKEY_ENABLE` - * マウスキー -* `EXTRAKEY_ENABLE` - * オーディオ制御とシステム制御 -* `CONSOLE_ENABLE` - * デバッグ用コンソール -* `COMMAND_ENABLE` - * デバッグ及び設定用のコマンド -* `COMBO_ENABLE` - * キーコンボ機能 -* `NKRO_ENABLE` - * USB N-キーロールオーバー - これが動作しない場合は、ここを見てください: https://github.com/tmk/tmk_keyboard/wiki/FAQ#nkro-doesnt-work -* `AUDIO_ENABLE` - * オーディオサブシステムを有効にします。 -* `RGBLIGHT_ENABLE` - * キーボードアンダーライト機能を有効にします -* `LEADER_ENABLE` - * リーダーキーコードを有効にします -* `MIDI_ENABLE` - * MIDI 制御 -* `UNICODE_ENABLE` - * Unicode -* `BLUETOOTH` - * 現在のオプションは、AdafruitBLE、RN42 -* `SPLIT_KEYBOARD` - * 分割キーボード (let's split や bakingpy のキーボードのようなデュアル MCU) のサポートを有効にし、quantum/split_common にある全ての必要なファイルをインクルードします -* `CUSTOM_MATRIX` - * 標準マトリックス走査ルーチンを独自のものに置き換えることができます。 -* `DEBOUNCE_TYPE` - * 標準キーデバウンスルーチンを代替または独自のものに置き換えることができます。 -* `WAIT_FOR_USB` - * キーボードが起動する前に、USB 接続が確立されるのをキーボードに待機させます -* `NO_USB_STARTUP_CHECK` - * キーボードの起動後の usb サスペンドチェックを無効にします。通常、キーボードはタスクが実行される前にホストがウェイク アップするのを待ちます。分割キーボードは半分はウェイクアップコールを取得できませんが、マスタにコマンドを送信する必要があるため、役に立ちます。 - -## USB エンドポイントの制限 - -USB 経由でサービスを提供するために、QMK は USB エンドポイントを使う必要があります。 -これらは有限なリソースです: 各マイクロコントローラは特定の数しか持ちません。 -これは一緒に有効にできる機能を制限します。 -利用可能なエンドポイントを超えると、ビルドエラーをひきおこします。 - -以下の機能は個別のエンドポイントを必要とするかもしれません: - -* `MOUSEKEY_ENABLE` -* `EXTRAKEY_ENABLE` -* `CONSOLE_ENABLE` -* `NKRO_ENABLE` -* `MIDI_ENABLE` -* `RAW_ENABLE` -* `VIRTSER_ENABLE` - -エンドポイントの使用率を向上させるために、HID 機能を組み合わせて1つのエンドポイントを使うようにすることができます。 -デフォルトでは、`MOUSEKEY`、`EXTRAKEY` および `NKRO` が単一のエンドポイントに結合されます。 - -基本キーボード機能も、`KEYBOARD_SHARED_EP = yes` を設定することで同じエンドポイントに結合することができます。 -これによりもう1つのエンドポイントが解放されますが、一部の BIOS ではブートキーボードプロトコルの切り替えを実装しないため、キーボードが動作しなくなるかもしれません。 - -マウスの結合も、ブートマウス互換性を破壊します。 -この機能が必要な場合は、`MOUSE_SHARED_EP = no` を設定することで、マウスを結合しないようにすることができます。 diff --git a/docs/ja/configurator_step_by_step.md b/docs/ja/configurator_step_by_step.md deleted file mode 100644 index 92be0f16a951..000000000000 --- a/docs/ja/configurator_step_by_step.md +++ /dev/null @@ -1,67 +0,0 @@ -# QMK Configurator: ステップ・バイ・ステップ - - - -このページでは、QMK Configurator でファームウェアを構築する手順を説明します。 - -## ステップ 1: キーボードを選ぶ - -ドロップダウンボックスをクリックして、キーマップを作成するキーボードを選択します。 - -?> **キーボードに複数のバージョンがある場合は、正しいバージョンを選択してください。** - -大事なことなのでもう一度言います。 - -!> **正しいバージョンを選択してください!** - -キーボードが QMK を搭載していると宣伝されていてもリストにない場合は、開発者がまだ作業中か、私たちがまだマージするきっかけがなかった可能性があります。 -アクティブな [プルリクエスト](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard) がない場合、[qmk_firmware](https://github.com/qmk/qmk_firmware/issues)で報告して、その特定のキーボードのサポートをリクエストします。 -製作者自身の GitHub アカウントにある QMK 搭載キーボードもあります。 -それも再確認してください。 - -## ステップ2: キーボードのレイアウトを選択する - -作成したいと思うキーマップに最も近いレイアウトを選択します。一部のキーボードには、まだ十分なレイアウトや正しいレイアウトが定義されていません。これらは将来サポートされる予定です。 - -## ステップ3: キーマップの名前を決める - -お好みの名前をキーマップにつけます。 - -?> コンパイル時に問題が発生した場合は、もしかすると QMK ファームウェアリポジトリに既に同じ名前が存在しているのかもしれません。名前を変更してみてください。 - -## ステップ4: キーマップを定義する - -キーコードの入力は、3つの方法のいずれかで行います。 - -1. ドラッグ・アンド・ドロップ -2. レイアウト上の空の場所をクリックして、希望するキーコードをクリックします -3. レイアウト上の空の場所をクリックして、キーボードの物理キーを押します - -?> マウスをキーの上に置くと、そのキーコードの機能の短い説明文が出ます。より詳細な説明については以下を見てください: - -* [基本的なキーコードリファレンス](ja/keycodes_basic.md) -* [高度なキーコードリファレンス](ja/feature_advanced_keycodes.md) - -!> 選択したレイアウトが物理的なビルドと一致しない場合は、使用していないキーは空白のままにしておきます。どのキーが使用されているかわからない場合、例えば、バックスペースキーは1つだが `LAYOUT_all` には2つのキーがある場合は、同じキーコードを両方の場所に配置してください。 - -## ステップ5: 後日のためにキーマップを保存する - -キーマップに満足するか、または後で作業したい場合は、`Export Keymap' ボタンを押します。 -これでキーマップがあなたのコンピュータに保存されます。 -その後、`Import Keymap` ボタンを押すことで、この .json ファイルを後で読み込むことができます。 - -!> **注意:** このファイルは、kbfirmware.com またはその他のツールに使用される .json ファイルと同じ形式ではありません。これらのツールにこの .json を使用したり、QMK Configurator でこれらのツールの .json を使用しようとすると、問題が発生します。 - -## ステップ6: ファームウェアをコンパイルする - -緑色の `Compile` ボタンを押します。 - -コンパイルが完了すると、緑色の `Download Firmware` ボタンを押すことができます。 - -## 次のステップ: キーボードに書き込む(フラッシュする) - -[ファームウェアを書きこむ](ja/newbs_flashing.md) を参照してください。 diff --git a/docs/ja/configurator_troubleshooting.md b/docs/ja/configurator_troubleshooting.md deleted file mode 100644 index 5979341c6e86..000000000000 --- a/docs/ja/configurator_troubleshooting.md +++ /dev/null @@ -1,32 +0,0 @@ -# Configurator トラブルシューティング - - - -## 私の .json ファイルが動きません - -.json ファイルが QMK Configurator で作ったものの場合、おめでとうございます。バグに遭遇しました。 [qmk_configurator](https://github.com/qmk/qmk_configurator/issues) で報告してください。 - -そうでない場合は、... 他の .json ファイルを使用しないようにという、上に書いた注意書きを見逃してませんか? - -#### レイアウトに余分なスペースがありますか?どうすればいいですか? - -もしスペースバーが3つに分かれている場合は、全てスペースバーで埋めるのが最善の方法です。バックスペースや Shift キーについても同じことができます。 - -#### キーコードってなに? - -以下を見てください。 - -* [基本的なキーコードリファレンス](ja/keycodes_basic.md) -* [高度なキーコードリファレンス](ja/feature_advanced_keycodes.md) - -#### コンパイルできません - -キーマップの他のレイヤーを再確認して、おかしなキーが存在しないことを確認してください。 - -## 問題とバグ - -私たちは利用者の依頼やバグレポートを常に受け入れています。[qmk_configurator](https://github.com/qmk/qmk_configurator/issues) で報告してください。 diff --git a/docs/ja/contributing.md b/docs/ja/contributing.md deleted file mode 100644 index 56cc4d312daa..000000000000 --- a/docs/ja/contributing.md +++ /dev/null @@ -1,173 +0,0 @@ -# 貢献方法 - - - -👍🎉 まず、これを読み貢献する時間を作ってくれてありがとうございます!🎉👍 - -サードパーティの貢献は、QMK の成長と改善に役立ちます。プルリクエストと貢献プロセスを貢献者とメンテナの両方にとって便利で簡単なものにしたいです。この目的のために、大きな変更をせずにプルリクエストが受け入れられるように貢献者向けのガイドラインをまとめました。 - -* [プロジェクトの概要](#project-overview) -* [コーディング規約](#coding-conventions) -* [一般的なガイドライン](#general-guidelines) -* [行動規範は私にとって何を意味しますか?](#what-does-the-code-of-conduct-mean-for-me) - -## この全てを読みたくはありません!単純に質問があります! - -QMK について質問したい場合は、[OLKB Subreddit](https://reddit.com/r/olkb) あるいは [Discord](https://discord.gg/Uq7gcHh) ですることができます。 - -以下の事を覚えておいてください: - -* 誰かがあなたの質問に答えるのに数時間掛かるかもしれません。しばらくお待ちください! -* QMK に関わる全ての人が彼らの時間とエネルギーを提供しています。QMK に関する作業や質問への回答に対する報酬はありません。 -* できるだけ簡単に答えられるように質問してみてください。その方法が分からない場合は、以下に幾つかの良いガイドがあります: - * https://opensource.com/life/16/10/how-ask-technical-questions - * http://www.catb.org/esr/faqs/smart-questions.html - -# プロジェクトの概要 :id=project-overview - -QMK は主に C で書かれており、特定の機能と部品は C++ で書かれています。QMK は、キーボードの中の組み込みプロセッサ、特に AVR ([LUFA](https://www.fourwalledcubicle.com/LUFA.php)) と ARM ([ChibiOS](https://www.chibios.org)) を対象にしています。すでに Arduino プログラミングに精通している場合は、多くの概念と制限がおなじみのものです。QMK に貢献するには Arduino を使用した経験は必要ありません。 - - - -# どこで助けを得られますか? - -助けが必要であれば、[issue を開く](https://github.com/qmk/qmk_firmware/issues) か [Discord で会話する](https://discord.gg/Uq7gcHh)ことができます。 - -# どうやって貢献することができますか? - -以前にオープンソースに貢献したことはありませんか? QMK で貢献がどのように機能するかが疑問ですか? ここに簡単な説明があります! - -0. [GitHub](https://github.com) アカウントにサインアップします。 -1. 貢献するためのキーマップをまとめるか、解決に興味がある[問題を見つける](https://github.com/qmk/qmk_firmware/issues)、あるいは追加したい[機能](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)を見つけます。 -2. 問題に関連付けられているリポジトリをあなたの GitHub アカウントにフォークします。これは、`GitHub上のあなたのユーザー名/qmk_firmware` の下にリポジトリのコピーを持つことを意味します。 -3. `git clone https://github.com/GitHub上のあなたのユーザー名/repository-name.git` を使ってローカルマシンにリポジトリをクローンします。 -4. 新しい機能に取り組んでいる場合は、issue を開きこれから行う作業について話し合うことを検討してください。 -5. `git checkout -b branch-name-here` を使って修正用の新しいブランチを作成します。 -6. 解決しようとしている問題、あるいは追加したい機能について適切な変更を加えます。 -7. `git add insert-paths-of-changed-files-here` を使って変更されたファイルの内容を git がプロジェクトの状態を管理するために使用する "snapshot"、インデックスとしても知られている、に追加します。 -8. `git commit -m "Insert a short message of the changes made here"` を使って、説明的なメッセージとともにインデックスの内容を保存します。 -9. `git push origin branch-name-here` を使って GitHub 上のリポジトリに変更をプッシュします。 -10. プルリクエストを [QMK Firmware](https://github.com/qmk/qmk_firmware/pull/new/master) にサブミットします。 -11. 行われた変更の簡単な説明と、変更に関する問題またはバグ番号を使って、プルリクエストにタイトルを付けます。例えば、issue に "Added more log outputting to resolve #4352" のようなタイトルをつけることができます。 -12. プルリクエストの説明では、行った変更、行ったプルリクエストに存在すると思われる問題、およびメンテナに対する質問を説明します。プルリクエストが完ぺきではない場合(プルリクエストが無い場合)でも問題ありません。レビュワーが問題の修正と改善を手伝います。 -13. プルリクエストがメンテナによってレビューされるのを待ちます。 -14. レビューをしているメンテナが変更を推奨する場合は、プルリクエストに変更を加えます。 -15. プルリクエストがマージされた後で成功を祝います! - -# コーディング規約 :id=coding-conventions - -私たちのスタイルのほとんどは簡単に理解できます。C あるいは Python のいずれかに精通している場合は、ローカルスタイルにそれほど問題はないはずです。 - -* [コーディング規約 - C](ja/coding_conventions_c.md) -* [コーディング規約 - Python](ja/coding_conventions_python.md) - -# 一般的なガイドライン :id=general-guidelines - -QMK には幾つかの異なるタイプの変更があり、それぞれ異なるレベルの厳密さが必要です。どのような種類の変更を行っても、次のガイドラインに留意してください。 - -* PR を論理単位に分割します。例えば、2つの個別の機能をカバーする1つの PR を送信するのではなく、代わりに機能ごとに個別の PR をサブミットします。 -* コミットする前に、`git diff --check` を使って不要な空白を確認します。 -* コードの変更が実際にコンパイルされることを確認してください。 - * キーマップ: `make keyboard:your_new_keymap` がエラーを返さないことを確認してください。 - * キーボード: `make keyboard:all` がエラーを返さないことを確認してください。 - * コア: `make all` がエラーを返さないことを確認してください。 -* コミットメッセージがそれ自体で理解できることを確認してください。最初の行に短い説明(70文字以内)を入れ、2行目は空にし、3行目以降では必要に応じてコミットを詳細に説明する必要があります。例: - -``` -kerpleplork の fronzlebop を調整します - -kerpleplork はエラーコード 23 で連続的に失敗していました。根本的な原因は fronzlebop 設定で、これにより kerpleplork は N 回の繰り返しごとにアクティブになります。 - -私が使用できるデバイスの限られた実験では、kerpleplork の混乱を避けるために 7 は十分高い値であることを示していますが、念のため ARM デバイスを持つ人たちからフィードバックを得たいです。 -``` - -!> **重要:** デフォルト以外のキーマップ、ユーザスペースおよびレイアウトのようなユーザコードへのバグ修正あるいは改善に貢献したい場合は、PR にコードの元の提出者にタグをつけてください。Git と GitHub のスキルレベルに関係なく、多くのユーザは知らないうちにコードが変更されることに混乱したりイライラしたりするかもしれません。 - -## ドキュメント - -ドキュメントは QMK への貢献を始める最も簡単な方法の1つです。ドキュメントが間違っているか不完全な場所を見つけ、これらを修正するのは簡単です!私たちもドキュメントを編集する人を非常に必要としています。編集するスキルがあるが、どこにどのように飛び乗ればいいのか分からない場合は、[助けをもとめて](#where-can-i-go-for-help)ください! - -全てのドキュメントは `qmk_firmware/docs` ディレクトリの中にあります。あるいは web ベースのワークフローを使いたい場合は、https://docs.qmk.fm/ の各ページの下部にある "Edit this page" リンクをクリックすることができます。 - -ドキュメントの中にコードの例を提供する場合は、ドキュメント内の他の場所で使用されている命名規則を順守してください。例えば、一貫性を保つために、`my_layers` あるいは `my_keycodes` として列挙型を標準化します: - -```c -enum my_layers { - _FIRST_LAYER, - _SECOND_LAYER -}; - -enum my_keycodes { - FIRST_LAYER = SAFE_RANGE, - SECOND_LAYER -}; -``` - -### ドキュメントのプレビュー :id=previewing-the-documentation - -開発環境をセットアップした場合は、プルリクエストを開く前に以下のコマンドを `qmk_firmware/` フォルダから実行することで、あなたの変更をプレビューすることができます: - - ./bin/qmk docs - -または、Python 3 のみがインストールされている場合: - - python3 -m http.server 8936 - -その後、ウェブブラウザで、`http://localhost:8936/` を表示します。 - -## キーマップ - -ほとんどの初めての QMK 貢献者は、個人のキーマップから始めます。キーマップの標準はかなりカジュアルなものにしようとしています(キーマップは結局のところ作成者の性格を反映しています)が、他の人があなたのキーマップを簡単に見つけて学ぶことができるように、これらのガイドラインに従うようにお願いします。 - -* [テンプレート](ja/documentation_templates.md) を使って `readme.md` を書きます。 -* 全てのキーマップの PR は squash されるため、コミットがどのように squash されるかを気にする場合は、自分で行う必要があります。 -* キーマップの PR に機能をまとめないでください。最初に機能をサブミットし、次にキーマップのための2つ目の PR をサブミットします。 -* `Makefile` をキーマップフォルダに含めないでください(もう使われていません)。 -* ファイルヘッダの著作権を更新します (`%YOUR_NAME%` を探します) - -## キーボード - -キーボードは QMK の存在理由です。一部のキーボードはコミュニティによって管理されていますが、他のキーボードはそれぞれのキーボードを作成する責任者によって管理されています。`readme.md` を見るとそのキーボードを管理しているのが誰かが分かります。特定のキーボードに関する質問がある場合、[Issue を開いて](https://github.com/qmk/qmk_firmware/issues)質問にメンテナをタグ付けしてください。(訳注: タグ付け は [メンションする](https://help.github.com/ja/github/writing-on-github/basic-writing-and-formatting-syntax#mentioning-people-and-teams) という意味です。) - -また以下のガイドラインに従うことをお願いします: - -* [テンプレート](ja/documentation_templates.md) を使って `readme.md` を書きます。 -* コミットの数を適切に保ってください。そうでなければあなたの PR を squash します。 -* コア機能を新しいキーボードにまとめないでください。最初に機能をサブミットし、次にキーボード用に別の PR をサブミットしてください。 -* `.c`/`.h` ファイルにすぐ上の親フォルダに従って名前を付けます。例えば、`/keyboards///.[ch]` -* `Makefile` をキーボードフォルダに含めないでください(もう使われていません) -* ファイルヘッダの著作権を更新します (`%YOUR_NAME%` を探します) - -## Quantum/TMK コア - -新しい機能をビルドするために多くの作業を行う前に、最適な方法で実装していることを確認する必要があります。[QMK の理解](ja/understanding_qmk.md)を読むことで、QMK の基本的な理解を得ることができます。これはあなたを QMK のプログラムフローのツアーに連れて行きます。ここから、あなたのアイデアを実装するための最良の方法の感覚をつかむために、私たちと話す必要があります。これを行うには主に2つの方法があります: - -* [Discord でのチャット](https://discord.gg/Uq7gcHh) -* [Issue を開く](https://github.com/qmk/qmk_firmware/issues/new) - -機能とバグ修正の PR は全てのキーボードに影響します。また、私たちは QMK の再編も進めています。このため、実装が行われる前に特に重要な変更について議論することが特に重要です。最初に私たちと話をせずに PR を開いた場合、あなたの選択が私たちの計画した方向とうまく合わない場合は幾つかの大きな再作業を行う覚悟をしてください。 - -機能やバグの修正に取り組む時に留意すべき幾つかの事があります。 - -* **デフォルトで無効** - QMK がサポートするほとんどのチップでメモリがかなり制限されており、現在のキーマップが壊れていないことが重要です。ですので、あなたの機能をオフにするのではなく**オン**にするようにしてください。デフォルトでオンにすべき場合、あるいはコードのサイズを小さくする必要がある場合は、相談してください。 -* **サブミットする前にローカルでコンパイル** - これが明白であることを願っていますが、コンパイルする必要があります。プルリクエストを作成する前に、変更した内容がコンパイルできるかどうかを常に確認する必要があります。 -* **リビジョンと異なるチップベースを考慮** - 僅かに異なる設定、さらには異なるチップベースを可能にするリビジョンを持つキーボードが幾つかあります。ARM および AVR でサポートされる機能を作成する、あるいは動作しないプラットフォームでは自動的に無効化するようにしてください。 -* **機能の説明** - 新しいファイルあるいは既存のファイルの一部として、`docs/` の中に文章化します。文章化しないと、他の人はあなたの苦労から利益を得ることができません。 - -また以下のガイドラインに従うことをお願いします: - -* コミットの数を適切に保ってください。そうでなければあなたの PR を squash します。 -* キーボードあるいはキーマップをコアの変更にまとめないでください。コアの変更を最初にサブミットしてください。 -* 機能のための[ユニット テスト](ja/unit_testing.md)を書いてください。 -* 編集しているファイルのスタイルに従ってください。スタイルが明確でないか、スタイルが混在している場合は、上記の[コーディング規約](#coding-conventions)に準拠する必要があります。 - -## リファクタリング - -QMK で物事がどのようにレイアウトされるかについて明確なビジョンを維持するために、私たちはリファクタリングを詳細に計画し、変更をする協力者がいます。リファクタリングのアイデアあるいは提案がある場合は、[issue を開いてください](https://github.com/qmk/qmk_firmware/issues)。QMK を改善する方法についてお話ししたいと思います。 - -# 行動規範は私にとって何を意味しますか? :id=what-does-the-code-of-conduct-mean-for-me - -私たちの[行動規範](https://github.com/qmk/qmk_firmware/blob/master/CODE_OF_CONDUCT.md)は、身元に関係なくあなたがプロジェクトの全員を敬意と礼儀を持って扱う責任があることを意味します。あなたが行動規範に記載されている不適切な行動やコメントの被害者である場合は、私たちはあなたのためにここにおり、私たちのコードに従って虐待者が適切に懲戒されるように最善を尽くします。 diff --git a/docs/ja/custom_matrix.md b/docs/ja/custom_matrix.md deleted file mode 100644 index 194960d77c90..000000000000 --- a/docs/ja/custom_matrix.md +++ /dev/null @@ -1,114 +0,0 @@ -# カスタムマトリックス - - - -QMKは、デフォルトのマトリックススキャンルーチンを独自のコードで部分的に入れ替えたり全部入れ替えたりしたりするメカニズムを提供します。 - -この機能を使用する理由は次のとおりです: - -* キーボードのスイッチと MCU ピンの間に追加のハードウェアがある場合 - * I/O マルチプレクサ - * ラインデコーダー -* 一般的ではないキースイッチマトリックス - * `COL2ROW` と `ROW2COL` の同時使用 - -## 前提条件 - -カスタムマトリックスの実装には、通常、追加のソースファイルのコンパイルが含まれます。 -一貫性を保つために、このソースファイルのファイル名は `matrix.c` とすることをお勧めします。 - -あなたのキーボードディレクトリに新しいファイルを追加します: -```text -keyboards//matrix.c -``` - -そして、新しいファイルのコンパイルを指定するため、以下を `rules.mk` に追加します -```make -SRC += matrix.c -``` - -## マトリックスコードの部分置き換え :id=lite - -カスタムマトリックスを実装する際、定型コードを書かなくてすむように、さまざまなスキャン関数のデフォルト実装を提供しています。 - -設定するには、以下を `rules.mk` に追加します: -```make -CUSTOM_MATRIX = lite -``` - -そして、キーボードディレクトリの `matrix.c` ファイルに次の関数を実装します。 - -```c -void matrix_init_custom(void) { - // TODO: ここでハードウェアの初期化をする -} - -bool matrix_scan_custom(matrix_row_t current_matrix[]) { - bool matrix_has_changed = false; - - // TODO: ここで、マトリックススキャンを行なう - - return matrix_has_changed; -} -``` - -## マトリックスコードの全面置き換え - -スキャンルーチンをさらに変更する必要がある場合は、完全なスキャンルーチンを実装することを選択できます。 - -設定するには、以下を `rules.mk` に追加します: -```make -CUSTOM_MATRIX = yes -``` - -そして、キーボードディレクトリの `matrix.c` ファイルに次の関数を実装します。 - -```c -matrix_row_t matrix_get_row(uint8_t row) { - // TODO: 要求された行データを返します -} - -void matrix_print(void) { - // TODO: printf() を使って現在のマトリックスの状態をコンソールにダンプします -} - -void matrix_init(void) { - // TODO: ここでハードウェアとグローバルマトリックスの状態を初期化します - - // ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを初期化します - debounce_init(MATRIX_ROWS); - - // 正しいキーボード動作のためにこれを呼び出す*必要があります* - matrix_init_kb(); -} - -uint8_t matrix_scan(void) { - bool changed = false; - - // TODO: ここにマトリックススキャンルーチンを追加します - - // ハードウェアによるデバウンスがない場合 - 設定されているデバウンスルーチンを使用します - changed = debounce(raw_matrix, matrix, MATRIX_ROWS, changed); - - // 正しいキーボード動作のためにこれを呼び出す*必要があります* - matrix_scan_kb(); - - return changed; -} -``` - -また、次のコールバックのデフォルトも提供します。 - -```c -__attribute__((weak)) void matrix_init_kb(void) { matrix_init_user(); } - -__attribute__((weak)) void matrix_scan_kb(void) { matrix_scan_user(); } - -__attribute__((weak)) void matrix_init_user(void) {} - -__attribute__((weak)) void matrix_scan_user(void) {} -``` diff --git a/docs/ja/custom_quantum_functions.md b/docs/ja/custom_quantum_functions.md deleted file mode 100644 index bd3f15a5fd2c..000000000000 --- a/docs/ja/custom_quantum_functions.md +++ /dev/null @@ -1,403 +0,0 @@ -# キーボードの挙動をカスタマイズする方法 - - - -多くの人にとって、カスタムキーボードはボタンの押下をコンピュータに送信するだけではありません。単純なボタンの押下やマクロよりも複雑なことを実行できるようにしたいでしょう。QMK にはコードを挿入したり、機能を上書きしたり、様々な状況でキーボードの挙動をカスタマイズできるフックがあります。 - -このページでは、QMK に関する特別な知識は想定していませんが、[QMK の理解](ja/understanding_qmk.md)を読むとより根本的なレベルで何が起きているかを理解するのに役立ちます。 - -## コア、キーボード、キーマップ階層 :id=a-word-on-core-vs-keyboards-vs-keymap - -私たちは QMK を階層として構造化しました: - -* コア (`_quantum`) - * キーボード/リビジョン (`_kb`) - * キーマップ (`_user`) - -以下で説明される各関数は `_kb()` サフィックスあるいは `_user()` サフィックスを使って定義することができます。`_kb()` サフィックスはキーボード/リビジョンレベルで使うことを意図しており、一方で `_user()` サフィックスはキーマップレベルで使われるべきです。 - -キーボード/リビジョンレベルで関数を定義する場合、`_kb()` は他の何かを実行する前に `_user()` を呼び出すよう実装することが重要です。そうでなければ、キーマップレベル関数は呼ばれないでしょう。 - -# カスタムキーコード - -最も一般的なタスクは、既存のキーコードの挙動を変更するか、新しいキーコードを作成することです。コードの観点からは、それぞれの仕組みは非常に似ています。 - -## 新しいキーコードの定義 - -独自のカスタムキーコードを作成する最初のステップは、それらを列挙することです。これは、カスタムキーコードに名前を付け、そのキーコードにユニークな番号を割り当てることの両方を意味します。QMK は、カスタムキーコードを固定範囲の番号に制限するのではなく、`SAFE_RANGE` マクロを提供します。カスタムキーコードを列挙する時に `SAFE_RANGE` を使うと、ユニークな番号を取得することが保証されます。 - - -これは2つのキーコードを列挙する例です。このブロックを `keymap.c` に追加した後で、キーマップの中で `FOO` と `BAR` を使うことができます。 - -```c -enum my_keycodes { - FOO = SAFE_RANGE, - BAR -}; -``` - -## 任意のキーコードの挙動のプログラミング :id=programming-the-behavior-of-any-keycode - -既存のキーの挙動を上書きしたい場合、あるいは新しいキーについて挙動を定義する場合、`process_record_kb()` および `process_record_user()` 関数を使うべきです。これらは実際のキーイベントが処理される前のキー処理中に QMK によって呼び出されます。これらの関数が `true` を返す場合、QMK はキーコードを通常通りに処理します。これは、キーを置き換えるのではなく、キーの機能を拡張するのに便利です。これらの関数が `false` を返す場合、QMK は通常のキー処理をスキップし、必要なキーのアップまたはダウンイベントを送信するのかはユーザ次第です。 - -これらの関数はキーが押されるか放されるたびに呼び出されます。 - -### `process_record_user()` の実装例 - -この例は2つの事を行います。`FOO` と呼ばれるカスタムキーコードの挙動を定義し、Enter キーが押されるたびに音を再生します。 - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // 押された時に何かをします - } else { - // 放された時に何かをします - } - return false; // このキーの以降の処理をスキップします - case KC_ENTER: - // enter が押された時に音を再生します - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // QMK に enter のプレスまたはリリースイベントを送信させます - default: - return true; // 他の全てのキーコードを通常通りに処理します - } -} -``` - -### `process_record_*` 関数のドキュメント - -* キーボード/リビジョン: `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` -* キーマップ: `bool process_record_user(uint16_t keycode, keyrecord_t *record)` - -`keycode` 引数はキーマップで定義されているものです。例えば `MO(1)`、`KC_L` など。これらのイベントを処理するには `switch...case` ブロックを使うべきです。 - -`record` 引数は実際のプレスに関する情報を含みます: - -```c -keyrecord_t record { - keyevent_t event { - keypos_t key { - uint8_t col - uint8_t row - } - bool pressed - uint16_t time - } -} -``` - -# キーボードの初期化コード - -キーボードの初期化プロセスには幾つかのステップがあります。何をしたいかによって、どの関数を使うべきかに影響します。 - -3つの主な初期化関数があり、呼び出される順番にリストされています。 - -* `keyboard_pre_init_*` - ほとんどのものが開始される前に起こります。非常に早くに実行したいハードウェアのセットアップに適しています。 -* `matrix_init_*` - ファームウェアのスタートアッププロセスの途中で起こります。ハードウェアは初期化されますが、機能はまだ初期化されていない場合があります。 -* `keyboard_post_init_*` - ファームウェアのスタートアッププロセスの最後に起こります。これはほとんどの場合、 "カスタマイズ"コードを配置する場所です。 - -!> ほとんどの人にとって、`keyboard_post_init_user` が呼び出したいものです。例えば、ここで RGB アンダーグローのセットアップを行います。 - -## キーボードの事前初期化コード - -これは USB さえ起動する前の、起動中の非常に早い段階で実行されます。 - -この直後にマトリックスが初期化されます。 - -これは主にハードウェア向きの初期化のためであるため、ほとんどのユーザは使うべきではありません。 - -ただし、初期化が必要なハードウェアがある場合には、これが最適な場所です (LED ピンの初期化など)。 - -### `keyboard_pre_init_user()` の実装例 - -この例は、キーボードレベルで、LED ピンとして B0、B1、B2、B3 および B4 をセットアップします。 - -```c -void keyboard_pre_init_user(void) { - // キーボードの事前初期コードを呼び出します。 - - // LED ピンを出力として設定します - setPinOutput(B0); - setPinOutput(B1); - setPinOutput(B2); - setPinOutput(B3); - setPinOutput(B4); -} -``` - -### `keyboard_pre_init_*` 関数のドキュメント :id=keyboard_pre_init_-function-documentation - -* キーボード/リビジョン: `void keyboard_pre_init_kb(void)` -* キーマップ: `void keyboard_pre_init_user(void)` - -## マトリックスの初期化コード - -これは、マトリックスが初期化され、ハードウェアの一部がセットアップされた後で、ただし機能の多くが初期化される前に、呼び出されます。 - -他の場所で必要になるかもしれないものをセットアップするのに役立ちますが、ハードウェアに関連するものではなく、開始場所に依存するものでもありません。 - - -### `matrix_init_*` 関数のドキュメント - -* キーボード/リビジョン: `void matrix_init_kb(void)` -* キーマップ: `void matrix_init_user(void)` - - -## キーボードの事後初期化コード - -キーボードの初期化プロセスの極めて最後のタスクとして実行されます。この時点で初期化される必要があるような、特定の機能を変更したい場合に便利です。 - - -### `keyboard_post_init_user()` の実装例 - -この例は、他の全てのものが初期化された後で実行され、rgb アンダーグローの設定をセットアップします。 - -```c -void keyboard_post_init_user(void) { - // post init コードを呼びます - rgblight_enable_noeeprom(); // 設定を保存せずに Rgb を有効にします - rgblight_sethsv_noeeprom(180, 255, 255); // 保存せずに色を青緑/シアンに設定します - rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // 保存せずにモードを高速なブリージングに設定します -} -``` - -### `keyboard_post_init_*` 関数のドキュメント - -* キーボード/リビジョン: `void keyboard_post_init_kb(void)` -* キーマップ: `void keyboard_post_init_user(void)` - -# マトリックススキャンコード :id=matrix-scanning-code - -可能であれば常に `process_record_*()` を使ってキーボードをカスタマイズし、その方法でイベントをフックし、コードがキーボードのパフォーマンスに悪影響を与えないようにします。ただし、まれにマトリックススキャンにフックする必要があります。これらの関数は1秒あたり少なくとも10回は呼び出されるため、これらの関数のコードのパフォーマンスに非常に注意してください。 - -### `matrix_scan_*` の実装例 - -この例は意図的に省略されています。このようなパフォーマンスに敏感な領域にフックする前に、例を使わずにこれを書くために、QMK 内部について十分理解する必要があります。助けが必要であれば、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new) か [Discord で会話](https://discord.gg/Uq7gcHh)してください。 - -### `matrix_scan_*` 関数のドキュメント - -* キーボード/リビジョン: `void matrix_scan_kb(void)` -* キーマップ: `void matrix_scan_user(void)` - -この関数はマトリックススキャンのたびに呼び出されます。これは基本的に MCU が処理できる頻度です。大量に実行されるため、ここに何を置くかについては注意してください。 - -カスタムマトリックススキャンコードが必要な場合は、この関数を使う必要があります。また、カスタムステータス出力 (LED あるいはディスプレイなど)や、ユーザが入力していない場合でも定期的にトリガーするその他の機能のために使うことができます。 - -# キーボードハウスキーピング :id=keyboard-housekeeping - -* キーボード/リビジョン: `void housekeeping_task_kb(void)` -* キーマップ: `void housekeeping_task_user(void)` - -この関数は、全ての QMK 処理の最後に、次の繰り返しを開始する前に呼び出されます。`housekeeping_task_*` の関数が呼び出された時点で、QMK が最後のマトリックススキャンを処理したと、安全に見なすことができます -- レイヤーの状態が更新され、USB レポートが送信され、LED が更新され、表示が描画されています。 - -`matrix_scan_*` と同様に、これらは MCU が処理できる頻度で呼び出されます。キーボードの応答性を維持するために、これらの関数の呼び出し中にできるだけ何もしないことをお勧めします。実際に何か特別なものを実装する必要がある場合に動作を停止させる可能性があります。 - -# キーボードアイドリング/ウェイクコード - -キーボードがサポートしている場合、多くの機能を停止することで"アイドル"にすることができます。これの良い例は、RGB ライトあるいはバックライトです。これにより、電力消費を節約できるか、キーボードの動作が改善されるかもしれません。 - -これは2つの関数によって制御されます: `suspend_power_down_*` および `suspend_wakeup_init_*`。これらはシステムキーボードがアイドルになった時と、起動した時のそれぞれで呼ばれます。 - - -### suspend_power_down_user() と suspend_wakeup_init_user() の実装例 - - -```c -void suspend_power_down_user(void) { - // code will run multiple times while keyboard is suspended -} - -void suspend_wakeup_init_user(void) { - // code will run on keyboard wakeup -} -``` - -### キーボードサスペンド/ウェイク関数のドキュメント - -* キーボード/リビジョン : `void suspend_power_down_kb(void)` および `void suspend_wakeup_init_user(void)` -* キーマップ: `void suspend_power_down_kb(void)` および `void suspend_wakeup_init_user(void)` - -# レイヤー切り替えコード :id=layer-change-code - -これはレイヤーが切り替えられるたびにコードを実行します。レイヤー表示あるいはカスタムレイヤー処理に役立ちます。 - -### `layer_state_set_*` の実装例 - -この例は、レイヤーに基づいて [RGB アンダーグロー](ja/feature_rgblight.md)を設定する方法を示していて、Planck を例として使っています。 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - rgblight_setrgb (0x00, 0x00, 0xFF); - break; - case _LOWER: - rgblight_setrgb (0xFF, 0x00, 0x00); - break; - case _PLOVER: - rgblight_setrgb (0x00, 0xFF, 0x00); - break; - case _ADJUST: - rgblight_setrgb (0x7A, 0x00, 0xFF); - break; - default: // 他の全てのレイヤーあるいはデフォルトのレイヤー - rgblight_setrgb (0x00, 0xFF, 0xFF); - break; - } - return state; -} -``` - -特定のレイヤーの状態を確認するには、`IS_LAYER_ON_STATE(state, layer)` と `IS_LAYER_OFF_STATE(state, layer)` マクロを使います。 - -`layer_state_set_*` 関数の外では、グローバルなレイヤー状態を確認するために `IS_LAYER_ON(layer)` と `IS_LAYER_OFF(layer)` マクロを使えます。 - -### `layer_state_set_*` 関数のドキュメント - -* キーボード/リビジョン: `layer_state_t layer_state_set_kb(layer_state_t state)` -* キーマップ: `layer_state_t layer_state_set_user(layer_state_t state)` - - -[キーマップの概要](ja/keymap.md#keymap-layer-status)で説明されるように、`state` はアクティブなレイヤーのビットマスクです。 - - -# 永続的な設定 (EEPROM) - -これによりキーボードのための永続的な設定を設定することができます。これらの設定はコントローラの EEPROM に保存され、電源が落ちた後であっても保持されます。設定は `eeconfig_read_kb` および `eeconfig_read_user` を使って読み取ることができ、`eeconfig_update_kb` および `eeconfig_update_user` を使って書きこむことができます。これは切り替え可能な機能 (rgb レイヤーの表示の切り替えなど)に役立ちます。さらに、`eeconfig_init_kb` および `eeconfig_init_user` を使って EEPROM のデフォルト値を設定できます。 - -ここでの複雑な部分は、EEPROM を介してデータを保存およびアクセスできる方法がたくさんあり、これを行うための"正しい"方法が無いということです。ただし、各関数には DWORD (4 バイト)しかありません。 - -EEPROM の書き込み回数には制限があることに注意してください。これは非常に高い値ですが、EEPROM に書き込むのはこれだけではなく、もし頻繁に書き込むと、MCU の寿命を大幅に短くする可能性があります。 - -* この例を理解していない場合は、この機能はかなり複雑なため、この機能を使うことを避けても構いません。 - -### 実装例 - -これは、設定を追加し、読み書きする例です。この例では、ユーザキーマップを使っています。これは複雑な機能で、多くのことが行われています。実際、動作のために上記の多くの関数を使います! - - -keymap.c ファイルの中で、先頭にこれを追加します: -```c -typedef union { - uint32_t raw; - struct { - bool rgb_layer_change :1; - }; -} user_config_t; - -user_config_t user_config; -``` - -これは、設定をメモリ内に保存し、EEPROM に書き込むことができる32ビット構造体をセットアップします。これを使うと、この構造体に変数が定義されるため、変数を定義する必要が無くなります。`bool` (boolean) の値は1ビットを使い、`uint8_t` は8ビットを使い、`uint16_t` は16ビットを使うことに注意してください。組み合わせて使うことができますが、順番の変更は読み書きされる値が変更されるため、問題が発生するかもしれません。 - -`layer_state_set_*` 関数のために `rgb_layer_change` を使い、全てを設定するために `keyboard_post_init_user` および `process_record_user` を使います。 - -ここで、上の `keyboard_post_init_user` コードを使って、作成したばかりの構造体を設定するために `eeconfig_read_user()` を追加します。そして、この構造体をすぐに使ってキーマップの機能を制御することができます。それは以下のようになります: -```c -void keyboard_post_init_user(void) { - // キーマップレベルのマトリックスの初期化処理を呼びます - - // EEPROM からユーザ設定を読み込みます - user_config.raw = eeconfig_read_user(); - - // 有効な場合はデフォルトレイヤーを設定します - if (user_config.rgb_layer_change) { - rgblight_enable_noeeprom(); - rgblight_sethsv_noeeprom_cyan(); - rgblight_mode_noeeprom(1); - } -} -``` -上記の関数は読み取ったばかりの EEPROM 設定を使い、デフォルトのレイヤーの RGB 色を設定します。その「生の」値は、上で作成した「共用体」に基づいて使用可能な構造に変換されます。 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } - break; - case _LOWER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } - break; - case _PLOVER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } - break; - case _ADJUST: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } - break; - default: // 他の全てのレイヤーあるいはデフォルトのレイヤー - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } - break; - } - return state; -} -``` -これにより、値が有効になっていた場合のみ、RGB アンダーグローが変更されます。この値を設定するために、`RGB_LYR` と呼ばれる `process_record_user` 用の新しいキーコードを作成します。さらに、通常の RGB コードを使う場合、上記の例を使ってオフになることを確認します。以下のようになります: -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // 押された時に何かをします - } else { - // 放された時に何かをします - } - return false; // このキーの以降の処理をスキップします - case KC_ENTER: - // enter が押された時に音を再生します - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // QMK に enter のプレスまたはリリースイベントを送信させます - case RGB_LYR: // これにより、アンダーグローをレイヤー表示として、あるいは通常通りに使うことができます。 - if (record->event.pressed) { - user_config.rgb_layer_change ^= 1; // 状態を切り替えます - eeconfig_update_user(user_config.raw); // 新しい状態を EEPROM に書き込みます - if (user_config.rgb_layer_change) { // レイヤーの状態表示が有効な場合 - layer_state_set(layer_state); // すぐにレイヤーの色を更新します - } - } - return false; - case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // 任意の RGB コード に対して(quantum_keycodes.h を見てください。400行目参照) - if (record->event.pressed) { // これはレイヤー表示を無効にします。これを変更する場合は、無効にしたいだろうため。 - if (user_config.rgb_layer_change) { // 有効な場合のみ - user_config.rgb_layer_change = false; // 無効にします - eeconfig_update_user(user_config.raw); // 設定を EEPROM に書き込みます - } - } - return true; break; - default: - return true; // 他の全てのキーコードを通常通りに処理します - } -} -``` -最後に、`eeconfig_init_user` 関数を追加して、EEPROM がリセットされた時にデフォルト値、さらにはカスタムアクションを指定できるようにします。EEPROM を強制的にリセットするには、`EEP_RST` キーコードあるいは[ブートマジック](ja/feature_bootmagic.md)機能を使います。例えば、デフォルトで rgb レイヤー表示を設定し、デフォルト値を保存したい場合。 - -```c -void eeconfig_init_user(void) { // EEPROM がリセットされます! - user_config.raw = 0; - user_config.rgb_layer_change = true; // デフォルトでこれを有効にします - eeconfig_update_user(user_config.raw); // デフォルト値を EEPROM に書き込みます - - // これらの値も EEPROM に書き込むためには、noeeprom 以外のバージョンを使います - rgblight_enable(); // デフォルトで RGB を有効にします - rgblight_sethsv_cyan(); // デフォルトでシアンに設定します - rgblight_mode(1); // デフォルトでソリッドに設定します -} -``` - -これで完了です。RGB レイヤー表示は必要な場合にのみ機能します。キーボードを取り外した後でも保存されます。RGB コードのいずれかを使うと、レイヤー表示が無効になり、設定したモードと色がそのままになります。 - -### 'EECONFIG' 関数のドキュメント - -* キーボード/リビジョン: `void eeconfig_init_kb(void)`、`uint32_t eeconfig_read_kb(void)` および `void eeconfig_update_kb(uint32_t val)` -* キーマップ: `void eeconfig_init_user(void)`、`uint32_t eeconfig_read_user(void)` および `void eeconfig_update_user(uint32_t val)` - -`val` は EEPROM に書き込みたいデータの値です。`eeconfig_read_*` 関数は EEPROM から32ビット(DWORD) 値を返します。 diff --git a/docs/ja/data_driven_config.md b/docs/ja/data_driven_config.md deleted file mode 100644 index bc8f4d24a542..000000000000 --- a/docs/ja/data_driven_config.md +++ /dev/null @@ -1,123 +0,0 @@ -# データ駆動型コンフィギュレーション - - - -このページでは、QMK のデータ駆動型 JSON コンフィギュレーションシステムがどのように動作するかを説明します。これは、QMK 自体に取り組みたい開発者を対象としています。 - -## ヒストリー - -これまで、QMK は、`rules.mk` と `config.h` の2つのメカニズムを組み合わせてコンフィギュレーションされてきました。 -この方法は、QMK がほんの一握りのキーボードをサポートしていたときは上手く機能していましたが、今では、サポートするキーボードは1500近くまで成長しました。 -`keyboards` の下だけで6000個の設定ファイルがあることが推定されます。 -これらのファイルの自由形式の性質と、重複を避けるために人々が使用してきたユニークなパターンが継続的なメンテナンスを困難にしており、また、多くのキーボードが時代遅れで時には理解が難しいパターンに従っています。 - -また、CLI に慣れていない人に QMK のパワーを提供することにも取り組んでおり、VIA などの他のプロジェクトでは、プログラムをインストールするのと同じくらい簡単に QMK を使用できるように取り組んでいます。 -これらのツールには、ユーザーが QMK を最大限に活用できるように、キーボードのレイアウト方法や使用可能なピンと機能に関する情報が必要です。 -その第一歩として `info.json` を導入しました。 -QMK API は、これら3つの情報源(`config.h`、` rules.mk`、および `info.json`)を、エンドユーザーツールが使用できる信頼できる単一の情報源に結合するための取り組みです。 - -これで、`info.json`から `rules.mk` と `config.h` の値を生成することがサポートされ、信頼できる単一の情報源を持つことができます。 -これにより、自動化されたツールを使用してキーボードを保守できるため、時間と保守作業を大幅に節約できます。 - -## 概要 - -C 側では何も変わりません。 -新しいルールを作成したり、定義したりする必要がある場合は、同じプロセスに従います。 - -1. `docs/config_options.md` に追加します。 -1. 適切なコアファイルにデフォルトを設定します。 -1. 必要に応じて ifdef 文を追加します。 - -次に、新しい構成のサポートを `info.json` に追加する必要があります。 -基本的なプロセスは次のとおりです。 - -1. `data/schemas/keyboards.jsonschema` のスキーマに追加します -1. `data/maps` にマッピングを追加します -1. (オプションおよび非推奨)構成を抽出/生成するコードを追加します。 - * `lib/python/qmk/info.py` - * `lib/python/qmk/cli/generate/config_h.py` - * `lib/python/qmk/cli/generate/rules_mk.py` - -## info.json にオプションを追加する - -このセクションでは、info.json に `config.h`/`rules.mk` の値のサポートを追加することについて説明します。 - -### スキーマに追加する - -QMK では、[jsonschema](https:json-schema.org) のファイルを `data/schemas` に保持しています。 -キーボード固有の `info.json` ファイルに入る値は `keyboard.jsonschema` に保持されています。 -エンドユーザーが編集できるようにしたい値はすべてここに入れなければなりません。 - -場合によっては、新しいトップレベルキーを追加するだけで済みます。 -従うべきいくつかの例は、 `keyboard_name`、`maintainer`、 `processor`、および `url` です。 -これは、オプションが自己完結型で、他のオプションと直接関係がない場合に適しています。 - -その他の場合、1つの `object` の中に、似ているオプションを集める必要があります。 -これは、機能のサポートを追加する場合に特に当てはまります。 -このために従うべきいくつかの例は、`indicators`、`matrix_pins`、および `rgblight` です。 -新しいオプションを統合する方法がわからない場合は、[問題を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=)か、[Discord で #cli に参加](https://discord.gg/heQPAgy)して、そこで会話を始めてください。 - -### マッピングを追加する - -ほとんどの場合、単純なマッピングを追加することができます。 -これらは `data/mappings/info_config.json` と `data/mappings/info_rules.json` に JSON ファイルとして保持され、それぞれ `config.h` と `rules.mk` のマッピングを制御します。 -各マッピングは `config.h` または `rules.mk` 変数名をキーとし、値は以下のキーを持つハッシュです。 - -* `info_key`: (必須)この値の `info.json` 内の場所。 下記参照。 -* `value_type`: (オプション)デフォルトは `str`。 この変数の値の形式。 下記参照。 -* `to_json`: (オプション)デフォルトは `true`。 このマッピングを info.json から除外するには、`false` に設定します -* `to_c`: (オプション)デフォルトは `true`。 このマッピングを config.h から除外するには、`false` に設定します -* `warn_duplicate`: (オプション)デフォルトは `true`。 値が両方の場所に存在する場合に警告をオフにするには、`false` に設定します - -#### Info Key - -info.json 内の変数をアドレス指定するために JSON ドット表記を使用します。 -たとえば、`info_json["rgblight"]["split_count"]` にアクセスするには、`rgblight.split_count` を指定します。 -これにより、深くネストされたキーを単純な文字列でアドレス指定できます。 - -内部では [Dotty Dict](https://dotty-dict.readthedocs.io/en/latest/) を使用しています。これらの文字列がオブジェクトアクセスに変換される方法についてはそのドキュメントを参照してください。 - -#### Value Types - -デフォルトでは、すべての値を単純な文字列として扱います。 -値がより複雑な場合は、次のいずれかのタイプを使用してデータをインテリジェントに解析できます。 - -* `array`: 文字列のコンマ区切りの配列 -* `array.int`: 整数のコンマ区切り配列 -* `int`: 整数 -* `hex`: 16進数としてフォーマットされた数値 -* `list`: 文字列のスペース区切りの配列 -* `mapping`: キーと値のペアのハッシュ - -### 抽出するコードを追加する - -ほとんどのユースケースは、上記のマッピングファイルによって解決できます。 -できない場合は、代わりに設定値を抽出するコードを書くことができます。 - -QMK が完全な `info.json` を生成するときはいつでも、`config.h` と `rules.mk` から情報を抽出します。 -あなたの新しい設定値のためのコードを `lib/python/qmk/info.py` に追加する必要があります。 -通常、これは、新しい `_extract_()` 関数を追加してから、 `_extract_config_h()` または `_extract_rules_mk()` のいずれかで関数を呼び出すことを意味します。 - -このファイルの編集方法がわからない場合、または Python に慣れていない場合は、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new?assignees=&labels=cli%2C+python&template=other_issues.md&title=)か [Discord で #cli に参加](https://discord.gg/heQPAgy)すると、この部分を誰かが手伝ってくれるでしょう。 - -### 生成するコードを追加する - -パズルの最後のピースは、ビルドシステムに新しいオプションを提供することです。 -これは、2つのファイルを生成することによって行われます。 - -* `.build/obj_/src/info_config.h` -* `.build/obj_/src/rules.mk` - -この2つのファイルは、次のコードによって生成されます。 - -* `lib/python/qmk/cli/generate/config_h.py` -* `lib/python/qmk/cli/generate/rules_mk.py` - -`config.h`値の場合、ルール用の関数を記述し、その関数を `generate_config_h()` で呼び出す必要があります。 - -`rules.mk` の新しいトップレベルの `info.json` キーがある場合は、`lib/python/qmk/cli/generate/rules_mk.py` の上部にある `info_to_rules` にキーを追加するだけです。 -それ以外の場合は、`generate_rules_mk()` で機能の新しい if ブロックを作成する必要があります。 diff --git a/docs/ja/documentation_best_practices.md b/docs/ja/documentation_best_practices.md deleted file mode 100644 index c866d3959933..000000000000 --- a/docs/ja/documentation_best_practices.md +++ /dev/null @@ -1,69 +0,0 @@ -# ドキュメントベストプラクティス - - - -このページは QMK のためのドキュメントを作成する時のベストプラクティスを文章化するためのものです。これらのガイドラインに従うことで、一貫したトーンとスタイルを維持することでき、他の人が QMK をより理解しやすくすることができます。 - -# ページの開始 - -ドキュメントページは通常 H1 ヘッダで始まり、最初の段落を使ってこのページの内容を説明します。この見出しと段落は目次の次にあるため、見出しは短くして空白の無い長い文字列を避けるように気を付けてください。 - -例: - -``` -# My Page Title - -This page covers my super cool feature. You can use this feature to make coffee, squeeze fresh oj, and have an egg mcmuffin and hashbrowns delivered from your local macca's by drone. -``` - -# 見出し - -通常、ページには複数の "H1" 見出しが有るべきです。H1 と H2 見出しのみが目次に含まれるので、適切に計画してください。目次が広くなりすぎないように、H1 と H2 の見出しでは幅を広げないようにしてください。 - -# スタイル付きのヒントブロック - -注意を引くためにテキストの周りにスタイル付きのヒントブロックを描くことができます。 - -### 重要なもの - -``` -!> This is important -``` - -以下のように表示されます: - -!> This is important - -### 一般的なヒント - -``` -?> This is a helpful tip. -``` - -以下のように表示されます: - -?> This is a helpful tip. - - -# 機能を文章化する - -QMK のために新しい機能を作成した場合、そのドキュメントページを作成してください。長い必要は無く、機能を説明する幾つかの文と、関連するキーコードを列挙した表で十分です。以下は基本的なテンプレートです: - -```markdown -# My Cool Feature - -This page describes my cool feature. You can use my cool feature to make coffee and order cream and sugar to be delivered via drone. - -## My Cool Feature Keycodes - -|Long Name|Short Name|Description| -|---------|----------|-----------| -|KC_COFFEE||Make Coffee| -|KC_CREAM||Order Cream| -|KC_SUGAR||Order Sugar| -``` - -ドキュメントを `docs/feature_.md` に配置し、そのファイルを `docs/_summary.md` の適切な場所に追加します。キーコードを追加した場合は、機能ページに戻るリンクとともに `docs/keycodes.md` に追加するようにしてください。 diff --git a/docs/ja/documentation_templates.md b/docs/ja/documentation_templates.md deleted file mode 100644 index 0ba3caf5ec1e..000000000000 --- a/docs/ja/documentation_templates.md +++ /dev/null @@ -1,45 +0,0 @@ -# ドキュメントテンプレート - - - -このページでは、新しいキーマップやキーボードを QMK に提出する際に使うべきテンプレートをまとめています。 - -## キーマップ `readme.md` テンプレート :id=keyboard-readmemd-template - -ほとんどのキーマップには、レイアウトを表す画像があります。画像を作成するには、[Keyboard Layout Editor](https://keyboard-layout-editor.com) を使うことができます。画像は [Imgur](https://imgur.com) や別のホスティングサービスにアップロードし、プルリクエストに画像を含めないでください。 - -画像の下には、キーマップを理解してもらうための簡単な説明文を書いてください。 - -``` -![Clueboard Layout Image](https://i.imgur.com/7Capi8W.png) - -# Default Clueboard Layout - -This is the default layout that comes flashed on every Clueboard. For the most -part it's a straightforward and easy to follow layout. The only unusual key is -the key in the upper left, which sends Escape normally, but Grave when any of -the Ctrl, Alt, or GUI modifiers are held down. -``` - -## キーボード `readme.md` テンプレート - -``` -# Planck - -![Planck](https://i.imgur.com/q2M3uEU.jpg) - -A compact 40% (12x4) ortholinear keyboard kit made and sold by OLKB and Massdrop. [More info on qmk.fm](https://qmk.fm/planck/) - -* Keyboard Maintainer: [Jack Humbert](https://github.com/jackhumbert) -* Hardware Supported: Planck PCB rev1, rev2, rev3, rev4, Teensy 2.0 -* Hardware Availability: [OLKB.com](https://olkb.com), [Massdrop](https://www.massdrop.com/buy/planck-mechanical-keyboard?mode=guest_open) - -Make example for this keyboard (after setting up your build environment): - - make planck/rev4:default - -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). -``` diff --git a/docs/ja/driver_installation_zadig.md b/docs/ja/driver_installation_zadig.md deleted file mode 100644 index bd794b40763a..000000000000 --- a/docs/ja/driver_installation_zadig.md +++ /dev/null @@ -1,53 +0,0 @@ -# Zadig を使ったブートローダドライバのインストール - - - -QMK はホストにたいして通常の HID キーボードデバイスとして振る舞うため特別なドライバは必要ありません。しかし、Windows でのキーボードへの書き込みは、多くの場合、キーボードをリセットした時に現れるブートローダデバイスで*行います*。 - -2つの注目すべき例外があります: 通常 Pro Micro で見られる Caterina ブートローダや、PJRC Teensy に書き込まれている HalfKay ブートローダは、それぞれシリアルポートと汎用 HID デバイスとして振る舞うため、ドライバは必要ありません。 - -[Zadig](https://zadig.akeo.ie/) ユーティリティを使うことをお勧めします。MSYS2 あるいは WSL を使って開発環境をセットアップした場合、`qmk_install.sh` スクリプトはドライバをインストールするかどうかをたずねます。 - -## インストール - -`RESET` キーコード (別のレイヤにあるかもしれません)を押すか、通常はキーボードの下面にあるリセットスイッチを押して、キーボードをブートローダモードにします。どちらもキーボードに無い場合は、Escape または Space+`B` を押しながら接続してみてください (詳細は、[ブートマジック](ja/feature_bootmagic.md) ドキュメントを見てください)。一部のキーボードはブートマジックの代わりに[コマンド](ja/feature_command.md)を使います。この場合、キーボードが接続されている状態で「左Shift + 右Shift + `B`」あるいは「左Shift + 右Shift + Escape」を押すと、ブートローダモードに入ることができます。 -一部のキーボードはブートローダに入るために特定の操作をする必要があります。例えば、[ブートマジック Lite](ja/feature_bootmagic.md#bootmagic-lite) キー (デフォルト: Escape) は別のキー(例えば、左Control)かもしれません。また、コマンドを有効にするキーの組み合わせ (デフォルト: 左Shift + 右Shift) は何か他のキー(例えば 左Control + 右Control)を押し続ける必要がある場合があります。不明な場合は、キーボードの README ファイルを参照してください。 - -USBaspLoader を使ってデバイスをブートローダモードにするには、`BOOT` ボタンを押しながら `RESET` ボタンをタップしてください。 -あるいは `BOOT` を押し続けながら USB ケーブルを挿入します。 - -Zadig は自動的にブートローダデバイスを検知します。**Options → List All Devices** を確認する必要がある場合があります。 - -- Atmel AVR MCU を搭載したキーボードの場合、ブートローダは `ATm32U4DFU` に似た名前が付けられ、ベンダー ID は `03EB` です。 -- USBasp ブートローダは `USBasp` として表示され、VID/PID は`16C0:05DC` です。 -- QMK-DFU ブートローダを使って書き込まれた AVR キーボードは ` Bootloader` という名前が付けられ、VID は `03EB` です。 -- ほとんどの ARM キーボードでは、`STM32 BOOTLOADER` と呼ばれ、VID/PID は `0483:DF11` です。 - -!> Zadig が `HidUsb` ドライバを使用する1つ以上のデバイスを表示する場合、キーボードはおそらくブートローダモードではありません。矢印はオレンジ色になり、システムドライバの変更を確認するように求められます。この場合、続行**しないでください**! - -矢印が緑色で表示されたら、ドライバを選択し、**Install Driver** をクリックします。`libusb-win32` ドライバは通常 AVR で動作し、`WinUSB`は ARM で動作しますが、それでもキーボードに書き込みできない場合は、リストから異なるドライバをインストールしてみてください。USBAspLoader デバイスは `libusbK` ドライバを使わなければなりません。 - -![ブートローダドライバが正常にインストールされた Zadig](https://i.imgur.com/b8VgXzx.png) - -最後に、新しいドライバがロードされたことを確認するためにキーボードのプラグを抜いて再接続します。書き込みに QMK Toolbox を使う場合は、ドライバの変更を認識しない場合があるため、QMK Toolkit を終了して再起動します。 - -## 間違ったデバイスのインストールからの回復 - -キーボードが入力できなくなった場合は、ブートローダではなくキーボード自体のドライバを間違って入れ替えた可能性があります。これはキーボードがブートローダモードでない場合に起こりえます。これは Zadig で簡単に確認することができます - 健全なキーボードには、全てのインタフェースに `HidUsb` ドライバがインストールされています: - -![Zadig から見た健全なキーボード](https://i.imgur.com/Hx0E5kC.png) - -デバイスマネージャーを開き、キーボードと思われるデバイスを探します。 - -![デバイスマネージャーにおける、間違ったドライバがインストールされたキーボード](https://i.imgur.com/L3wvX8f.png) - -右クリックし、**デバイスのアンインストール** をクリックします。最初に **このデバイスのドライバーソフトウェアを削除します** にチェックが付いていることを確認してください。 - -!["ドライバの削除"にチェックボックスにチェックが付いた、デバイスのアンインストールダイアログ](https://i.imgur.com/aEs2RuA.png) - -**Action → Scan for hardware changes** をクリックします。この時点で、再び入力できるようになっているはずです。Zadig でキーボードデバイスが `HidUsb` ドライバを使っていることを再確認します。そうであれば完了です。キーボードは再び機能するはずです! - -?> Windows が新しいドライバを使えるようにするために、この時点でコンピュータを完全に再起動する必要があるかもしれません。 diff --git a/docs/ja/faq_build.md b/docs/ja/faq_build.md deleted file mode 100644 index a1c55407ee41..000000000000 --- a/docs/ja/faq_build.md +++ /dev/null @@ -1,73 +0,0 @@ -# よくあるビルドの質問 - - - -このページは QMK のビルドに関する質問を説明します。まだビルドをしていない場合は、[ビルド環境のセットアップ](ja/getting_started_build_tools.md) および [Make 手順](ja/getting_started_make_guide.md)ガイドを読むべきです。 - -## Linux でプログラムできません -デバイスを操作するには適切な権限が必要です。Linux ユーザの場合は、以下の `udev` ルールに関する指示を見てください。`udev` に問題がある場合は、回避策は `sudo` コマンドを使うことです。このコマンドに慣れていない場合は、`man sudo` コマンドでマニュアルを確認するか、[この web ページを見てください](https://linux.die.net/man/8/sudo)。 - -コントローラが ATMega32u4 の場合の `sudo` の使い方の例: - - $ sudo dfu-programmer atmega32u4 erase --force - $ sudo dfu-programmer atmega32u4 flash your.hex - $ sudo dfu-programmer atmega32u4 reset - -あるいは、単純に: - - $ sudo make ::flash - -`make` を `sudo` で実行することは一般的には良い考えでは***なく***、可能であれば前者の方法のいずれかを使うべきです。 - -### Linux の `udev` ルール :id=linux-udev-rules - -Linux では、ブートローダデバイスと通信するには適切な権限が必要です。ファームウェアを書き込む時に `sudo` を使うか(非推奨)、`/etc/udev/rules.d/` に[このファイル](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules)を配置することで、通信することができます。 - -追加が完了したら、以下を実行します: - -``` -sudo udevadm control --reload-rules -sudo udevadm trigger -``` - -**注意:** 古い(1.12以前の) ModemManager では、フィルタリングは厳密なモードではない場合にのみ動作し、以下のコマンドはその設定を更新することができます。 - -``` -printf '[Service]\nExecStart=\nExecStart=/usr/sbin/ModemManager --filter-policy=default' | sudo tee /etc/systemd/system/ModemManager.service.d/policy.conf -sudo systemctl daemon-reload -sudo systemctl restart ModemManager -``` - -### Linux のブートローダモードで Serial デバイスが検知されない -カーネルがデバイスを適切にサポートしていることを確認してください。デバイスが、Pro Micro (Atmega32u4) のように USB ACM を使う場合、`CONFIG_USB_ACM=y` を含めるようにしてください。他のデバイスは `USB_SERIAL` およびそのサブオプションを必要とするかもしれません。 - -## DFU ブートローダの不明なデバイス - -Windows 上でキーボードを書き込む時に発生する問題は、ブートローダ用に間違ったドライバがインストールされているか、全くインストールされていないかによるものがほとんどです。 - -QMK インストールスクリプト (MSYS2 あるいは WSL 内の `qmk_firmware` ディレクトリから `./util/qmk_install.sh`) を再実行するか、QMK Toolbox の再インストールでこの問題が解決するかもしれません。別のやり方として、手動で [`qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer) パッケージをダウンロードして実行することができます。 - -それでもうまく行かない場合は、Zadig をダウンロードして実行する必要があります。詳細な情報は [Zadig を使ったブートローダドライバのインストール](ja/driver_installation_zadig.md)を見てください。 - -## USB VID と PID -`config.h` を編集することで任意の ID を使うことができます。おそらく未使用の ID を使っても、他の製品と衝突するとても低い可能性があることを除いて、実際には問題はありません。 - -QMK のほとんどのキーボードは、vendor ID として、`0xFEED` を使います。他のキーボードを調べて、ユニークな ID を選択してください。 - -またこれも見てください。 -https://github.com/tmk/tmk_keyboard/issues/150 - -ここで本当にユニークな VID:PID を買うことができます。個人的な使用にはこれは必要ないと思います。 -- https://www.obdev.at/products/vusb/license.html -- https://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 - -### キーボードに書き込んだが何も起こらない、あるいはキーの押下が登録されない - ARM (rev6 planck、clueboard 60、hs60v2 など) でも同じ (Feb 2019) -ARM ベースのチップ上での EEPROM の動作によって、保存された設定が無効になる場合があります。これはデフォルトレイヤに影響し、まだ調査中の特定の環境下でキーボードが使えなくなるかも*しれません*。EEPROM のリセットでこれが修正されます。 - -[Planck rev6 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) を使って eeprom のリセットを強制することができます。このイメージを書き込んだ後で、通常のファームウェアを書き込むと、キーボードが _通常_ の動作順序に復元されます。 -[Preonic rev3 reset EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) - -いずれかの形式でブートマジックが有効になっている場合は、これも実行できるはずです (実行方法の詳細については、[ブートマジックドキュメント](ja/feature_bootmagic.md)とキーボード情報を見てください)。 diff --git a/docs/ja/faq_debug.md b/docs/ja/faq_debug.md deleted file mode 100644 index 236f43a6ef50..000000000000 --- a/docs/ja/faq_debug.md +++ /dev/null @@ -1,131 +0,0 @@ -# デバッグの FAQ - - - -このページは、キーボードのトラブルシューティングについての様々な一般的な質問を説明します。 - -## デバッグ :id=debugging - -`rules.mk` へ `CONSOLE_ENABLE = yes` の設定をするとキーボードはデバッグ情報を出力します。デフォルトの出力は非常に限られたものですが、デバッグモードをオンにすることでデバッグ情報の量を増やすことが出来ます。キーマップの `DEBUG` キーコードを使用するか、デバッグモードを有効にする[コマンド](ja/feature_command.md)機能を使用するか、以下のコードをキーマップに追加します。 - -```c -void keyboard_post_init_user(void) { - // 希望する動作に合わせて値をカスタマイズします - debug_enable=true; - debug_matrix=true; - //debug_keyboard=true; - //debug_mouse=true; -} -``` - -## デバッグツール - -キーボードのデバッグに使えるツールは2つあります。 - -### QMK Toolbox を使ったデバッグ - -互換性のある環境では、[QMK Toolbox](https://github.com/qmk/qmk_toolbox) を使うことでキーボードからのデバッグメッセージを表示できます。 - -### hid_listen を使ったデバッグ - -ターミナルベースの方法がお好みですか?PJRC が提供する [hid_listen](https://www.pjrc.com/teensy/hid_listen.html) もデバッグメッセージの表示に使用できます。ビルド済みの実行ファイルは Windows、Linux、MacOS 用が用意されています。 - -## 独自のデバッグメッセージを送信する - -[カスタムコード](ja/custom_quantum_functions.md)内からデバッグメッセージを出力すると便利な場合があります。それはとても簡単です。ファイルの先頭に `print.h` のインクルードを追加します: - -```c -#include "print.h" -``` - -その後は、いくつかの異なった print 関数を使用することが出来ます: - -* `print("string")`: シンプルな文字列を出力します -* `uprintf("%s string", var)`: フォーマットされた文字列を出力します -* `dprint("string")` デバッグモードが有効な場合のみ、シンプルな文字列を出力します -* `dprintf("%s string", var)`: デバッグモードが有効な場合のみ、フォーマットされた文字列を出力します - -## デバッグの例 - -以下は現実世界での実際のデバッグ手法の例を集めたものです。 - -### マトリックス上のどの場所でキー押下が起こったか? - -移植する場合や、PCB の問題を診断する場合、キー入力が正しくスキャンされているかどうかを確認することが役立つ場合があります。この手法でのロギングを有効化するには、`keymap.c` へ以下のコードを追加します。 - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - // コンソールが有効化されている場合、マトリックス上の位置とキー押下状態を出力します -#ifdef CONSOLE_ENABLE - uprintf("KL: kc: 0x%04X, col: %u, row: %u, pressed: %b, time: %u, interrupt: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count); -#endif - return true; -} -``` - -出力例 -```text -Waiting for device:....... -Listening: -KL: kc: 169, col: 0, row: 0, pressed: 1 -KL: kc: 169, col: 0, row: 0, pressed: 0 -KL: kc: 174, col: 1, row: 0, pressed: 1 -KL: kc: 174, col: 1, row: 0, pressed: 0 -KL: kc: 172, col: 2, row: 0, pressed: 1 -KL: kc: 172, col: 2, row: 0, pressed: 0 -``` - -### キースキャンにかかる時間の測定 - -パフォーマンスの問題をテストする場合、スイッチマトリックスをスキャンする頻度を知ることが役立ちます。この手法でのロギングを有効化するには `config.h` へ以下のコードを追加します。 - -```c -#define DEBUG_MATRIX_SCAN_RATE -``` - -出力例 -```text - > matrix scan frequency: 315 - > matrix scan frequency: 313 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 -``` - -## `hid_listen` がデバイスを認識できない -デバイスのデバッグコンソールの準備ができていない場合、以下のように表示されます: - -``` -Waiting for device:......... -``` - -デバイスが接続されると、*hid_listen* がデバイスを見つけ、以下のメッセージが表示されます: - -``` -Waiting for new device:......................... -Listening: -``` - -この 'Listening:' のメッセージが表示されない場合は、[Makefile] を `CONSOLE_ENABLE=yes` に設定してビルドしてみてください - -Linux のような OS でデバイスにアクセスするには、特権が必要かもしれません。`sudo hid_listen` を試してください。 - -多くの Linux ディストリビューションでは、次の内容で `/etc/udev/rules.d/70-hid-listen.rules` というファイルを作成することで、root として hid_listen を実行する必要がなくなります: - -``` -SUBSYSTEM=="hidraw", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="def1", TAG+="uaccess", RUN{builtin}+="uaccess" -``` - -abcd と def1 をキーボードのベンダーとプロダクト IDに置き換えてください。文字は小文字でなければなりません。`RUN{builtin}+="uaccess"` の部分は、古いディストリビューションでのみ必要です。 - -## コンソールにメッセージが表示されない -以下を調べてください: -- *hid_listen* がデバイスを検出する。上記を見てください。 -- **Magic**+d を使ってデバッグを有効にする。[マジックコマンド](https://github.com/tmk/tmk_keyboard#magic-commands)を見てください。 -- `debug_enable=true` を設定します。[デバッグ](#debugging)を見てください。 -- デバッグプリントの代わりに `print` 関数を使ってみてください。**common/print.h** を見てください。 -- コンソール機能を持つ他のデバイスを切断します。[Issue #97](https://github.com/tmk/tmk_keyboard/issues/97) を見てください。 diff --git a/docs/ja/faq_general.md b/docs/ja/faq_general.md deleted file mode 100644 index 407846b7883e..000000000000 --- a/docs/ja/faq_general.md +++ /dev/null @@ -1,58 +0,0 @@ -# よくある質問 - - - -## QMK とは何か? - -Quantum Mechanical Keyboard の略である [QMK](https://github.com/qmk) は、カスタムキーボードのためのツールをビルドしている人々のグループです。[TMK](https://github.com/tmk/tmk_keyboard) の大幅に修正されたフォークである [QMK ファームウェア](https://github.com/qmk/qmk_firmware)から始まりました。 - -## どこから始めればいいかわかりません! - -この場合は、[初心者ガイド](ja/newbs.md) から始めるべきです。ここには多くの素晴らしい情報があり、それらはあなたが始めるのに必要な全てをカバーするはずです。 - -問題がある場合は、[QMK Configurator](https://config.qmk.fm)にアクセスしてください。あなたが必要なものの大部分が処理されます。 - -## ビルドしたファームウェアを書き込むにはどうすればいいですか? - -まず、[コンパイル/書き込み FAQ ページ](ja/faq-build.md) に進みます。そこにはたくさんの情報があり、そこには一般的な問題に対する多くの解決策があります。 - -## ここで取り上げていない問題がある場合はどうしますか? - -OK、問題ありません。[GitHub で issue を開く](https://github.com/qmk/qmk_firmware/issues) をチェックして、誰かが同じこと(似ているかだけでなく実際に同じであることを確認してください)を経験しているかどうかを確認してください。 - -もし何も見つからない場合は、[新しい issue](https://github.com/qmk/qmk_firmware/issues/new) を開いてください! - -## バグを見つけたらどうしますか? - -[issue](https://github.com/qmk/qmk_firmware/issues/new) を開いてください。そしてもし修正方法を知っている場合は、GitHub で修正のプルリクエストを開いてください。 - -## しかし、`git` と `GitHub` は怖いです! - -心配しないでください。開発を容易にするために `git` と GitHub を使い始めるための、かなり良い [ガイドライン](ja/newbs_git_best_practices.md) があります。 - -さらに、追加の `git` と GitHub の関連リンクを [ここ](ja/newbs_learn_more_resources.md) に見つけることができます。 - -## サポートを追加したいキーボードがあります - -素晴らしい!プルリクエストを開いてください。私たちはコードをレビューし、マージします! - -### `QMK` でブランドしたい場合はどうればいいですか? - -素晴らしい!私たちはあなたを支援したいと思います! - -実際、私たちにはあなたのページとキーボードに QMK ブランドを追加するための [完全なページ](https://qmk.fm/powered/) があります。これは QMK を公式にサポートするために必要なほぼ全て(知識と画像)をカバーしています。 - -これについて質問がある場合は、issue を開くか、[Discord](https://discord.gg/Uq7gcHh) に進んでください。 - -## QMK と TMK の違いは何か? - -TMK は [Jun Wako](https://github.com/tmk) によって設計され実装されました。QMK は [Jack Humbert](https://github.com/jackhumbert) の Planck 用 TMK のフォークとして始まりました。しばらくして、Jack のフォークは TMK からかなり分岐し、2015年に Jack はフォークを QMK に名前を変えることにしました。 - -技術的な観点から、QMK は幾つかの新しい機能を追加した TMK に基づいています。最も注目すべきことは、QMK は利用可能なキーコードの数を増やし、`S()`、`LCTL()` および `MO()` などの高度な機能を実装するためにこれらを使っています。[キーコード](ja/keycodes.md)でこれらのキーコードの完全なリストを見ることができます。 - -プロジェクトとコミュニティの管理の観点から、TMK は公式にサポートされている全てのキーボードを自分で管理しており、コミュニティのサポートも少し受けています。他のキーボード用に別個のコミュニティが維持するフォークが存在するか、作成できます。デフォルトでは少数のキーマップのみが提供されるため、ユーザは一般的にお互いにキーマップを共有しません。QMK は集中管理されたリポジトリを介して、キーボードとキーマップの両方を共有することを奨励しており、品質基準に準拠する全てのプルリクエストを受け付けます。これらはほとんどコミュニティで管理されますが、必要な場合は QMK チームも支援します。 - -どちらのアプローチもメリットとデメリットがあり、理に適う場合は TMK と QMK の間でコードは自由にやり取りされます。 diff --git a/docs/ja/faq_keymap.md b/docs/ja/faq_keymap.md deleted file mode 100644 index 9c6cf6232de9..000000000000 --- a/docs/ja/faq_keymap.md +++ /dev/null @@ -1,160 +0,0 @@ -# キーマップの FAQ - - - -このページは人々がキーマップについてしばしば持つ疑問について説明します。まだ読んだことが無い場合には、[キーマップの概要](ja/keymap.md)を最初に読むべきです。 - -## どのキーコードを使えますか? -あなたが利用可能なキーコードのインデックスについては、[キーコード](ja/keycodes.md)を見てください。より広範なドキュメントがある場合は、そこからリンクしてあります。 - -キーコードは実際には [common/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h) で定義されています。 - -## デフォルトのキーコードとは何か? - -世界中で使用されている ANSI、ISO および JIS の3つの標準キーボードがあります。北米では主に ANSI が使われ、ヨーロッパおよびアフリカでは主に ISO が使われ、日本では JIS が使われます。言及されていない地域では、ANSI あるいは ISO が使われています。これらのレイアウトに対応するキーコードは以下の通りです: - - -![キーボードのレイアウトイメージ](https://i.imgur.com/5wsh5wM.png) - -## 複雑なキーコードのカスタム名を作成する方法はありますか? - -時には、読みやすくするために、一部のキーコードにカスタム名を定義すると役に立ちます。人々は、しばしば `#define` を使ってカスタム名を定義します。例えば: - -```c -#define FN_CAPS LT(_FL, KC_CAPSLOCK) -#define ALT_TAB LALT(KC_TAB) -``` - -これにより、キーマップで `FN_CAPS` と `ALT_TAB` を使えるようになり、読みやすくなります。 - -## 一部のキーが入れ替わっているか、または動作しない - -QMK には2つの機能、ブートマジックとコマンドがあり、これによりその場でキーボードの動作を変更することができます。これには Ctrl/Caps の交換、Gui の無効化、Alt/Gui の交換、Backspace/Backslash の交換、全てのキーの無効化およびその他の動作の変更が含まれますが、これらに限定されません。 - -迅速な解決策として、キーボードを接続している時に `Space`+`Backspace` を押してみてください。これはキーボードに保存されている設定をリセットし、これらのキーを通常の操作に戻します。うまく行かない場合は、以下を見てください: - -* [ブートマジック](ja/feature_bootmagic.md) -* [コマンド](ja/feature_command.md) - -## メニューキーが動作しない - -ほとんどの最近のキーボードにある、`KC_RGUI` と `KC_RCTL` の間にあるキーは、実際には `KC_APP` と呼ばれます。これは、そのキーが発明された時に、関連する標準にすでに `MENU` という名前のキーが存在していたため、MS はそれを `APP` キーと呼ぶことを選択したためです。 - -## `KC_SYSREQ` が動作しません -`KC_SYSREQ` の代わりに、Print Screen(`KC_PSCREEN` あるいは `KC_PSCR`) のキーコードを使ってください。'Alt + Print Screen' のキーの組み合わせは、'システムリクエスト' と認識されます。 - -[issue #168](https://github.com/tmk/tmk_keyboard/issues/168) と以下を見てください -* https://en.wikipedia.org/wiki/Magic_SysRq_key -* https://en.wikipedia.org/wiki/System_request - -## 電源キーが動作しません - -やや紛らわしいことに、QMK には2つの "Power" キーコードがあります: キーボード/キーパッド HID usage page では `KC_POWER`、Consumer page では `KC_SYSTEM_POWER` (あるいは `KC_PWR`)。 - -前者は macOS でのみ認識されますが、後者 `KC_SLEP` および `KC_WAKE` は3つの主要なオペレーティングシステム全てでサポートされるため、これらを使うことをお勧めします。Windows ではこれらのキーはすぐに機能しますが、macOS ではそれらはダイアログが表示されるまで押し続ける必要があります。 - -## ワンショットモディファイア -私の個人的な 'the' の問題を解決します。'The' ではなく 'the' あるいは 'THe' を間違って入力することがありました。ワンショットシフトはこれを軽減します。 -https://github.com/tmk/tmk_keyboard/issues/67 - -## モディファイヤ/レイヤスタック -修飾キーあるいはレイヤは、レイヤの切り替えが適切に設定されていない場合、スタックするかもしれません。 -修飾キーおよびレイヤ切り替えの場合、リリースイベント時に修飾キーの登録を解除する、もしくは前のレイヤに戻るために、目的のレイヤの同じ位置に `KC_TRANS` を配置する必要があります。 - -* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching -* https://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 -* https://github.com/tmk/tmk_keyboard/issues/248 - - -## メカニカルロックスイッチのサポート - -この機能は [Alps](https://deskthority.net/wiki/Alps_SKCL_Lock) のような*メカニカルロックスイッチ*用です。以下を `config.h` に追加することで有効にすることができます: - -``` -#define LOCKING_SUPPORT_ENABLE -#define LOCKING_RESYNC_ENABLE -``` - -この機能を有効にした後で、キーマップでキーコード `KC_LCAP`、`KC_LNUM` および `KC_LSCR` を使います。 - -古いビンテージメカニカルキーボードにはロックスイッチが付いている場合がありますが、最新のものにはありません。***ほとんどの場合この機能は必要なく、単にキーコード `KC_CAPS`、`KC_NUM` および `KC_SCRL`*** を使います。 - -## セディーユ 'Ç' のような ASCII 以外の特別文字の入力 - -[ユニコード](ja/feature_unicode.md) 機能を見てください。 - -## macOS での `Fn` キー - -ほとんどの Fn キーと異なり、Apple のキーボードの Fn キーには実際には独自のキーコードのようなものがあります。基本的な 6KRO HID レポートの6番目のキーコードの代わりになります -- つまり、Apple キーボードは実際には 5KRO のみです。 - -QMK にこのキーを送信させることは技術的に可能です。ただし、そうするには Fn キーの状態を追加するためにレポート形式の修正を必要とします。 -さらに悪いことに、キーボードの VID と PID が実際の Apple のキーボードのものと一致しない限り、認識されません。公式の QMK がこの機能をサポートすることで法的な問題が起きるため、サポートされることはないでしょう。 - -詳細については、[この issue](https://github.com/qmk/qmk_firmware/issues/2179) を見てください。 - -## Mac OSX でサポートされるキーは? -このソースコードから、どのキーコードが OSX でサポートされるかを知ることができます。 - -`usb_2_adb_keymap` 配列は、キーボード/キーパッドページの Page usages を ADB スキャンコード(OSX 内部キーコード)にマップします。 - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c - -`IOHIDConsumer::dispatchConsumerEvent` は Consumer page usages を処理します。 - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp - - -## Mac OSX での JIS キー -`無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` のような日本語 JIS キーボード固有のキーは OSX では認識されません。**Seil** を使ってこれらのキーを使うことができます。以下のオプションを試してください。 - -* PC キーボードで NFER キーを有効にする -* PC キーボードで XFER キーを有効にする -* PC キーボードで KATAKANA キーを有効にする - -https://pqrs.org/osx/karabiner/seil.html - - -## RN-42 Bluetooth が Karabiner で動作しない -Karabiner - Mac OSX 上のキーマッピングツール - は、デフォルトでは RN-42 モジュールからの入力を無視します。Karabiner をキーボードで動作させるにはこのオプションを有効にする必要があります。 -https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559237 - -この問題の詳細についてはこれらを見てください。 -https://github.com/tmk/tmk_keyboard/issues/213 -https://github.com/tekezo/Karabiner/issues/403 - - -## 単一のキーでの Esc と` - -[Grave Escape](ja/feature_grave_esc.md) 機能を見てください。 - -## Mac OSX での Eject -`KC_EJCT` キーコードは OSX で動作します。https://github.com/tmk/tmk_keyboard/issues/250 -Windows 10 はコードを無視し、Linux/Xorg は認識しますが、デフォルトではマッピングがありません。 - -実際の Apple キーボードにある Eject キーコードは実際には分かりません。HHKB は Mac モードでは Eject キー (`Fn+f`) に `F20` を使いますが、これはおそらく Apple の Eject キーコードと同じではありません。 - - -## `action_util.c` の `weak_mods` と `real_mods` は何か -___改善されるべきです___ - -real_mods は実際の物理的な修飾キーの状態を保持することを目的にしていますが、weak_mods は実際の修飾キーの状態に影響しない仮想あるいは一時的なモディファイアの状態を保持します。 - -物理的な左シフトキーを押しながら ACTION_MODS_KEY(LSHIFT, KC_A) を入力するとします - -weak_mods では、 -* (1) 左シフトキーを押し続ける: real_mods |= MOD_BIT(LSHIFT) -* (2) ACTION_MODS_KEY(LSHIFT, KC_A) を押す: weak_mods |= MOD_BIT(LSHIFT) -* (3) ACTION_MODS_KEY(LSHIFT, KC_A) を放す: weak_mods &= ~MOD_BIT(LSHIFT) -real_mods はモディファイアの状態を維持します。 - -weak mods 無しでは、 -* (1) 左シフトキーを押し続ける: real_mods |= MOD_BIT(LSHIFT) -* (2) ACTION_MODS_KEY(LSHIFT, KC_A) を押す: real_mods |= MOD_BIT(LSHIFT) -* (3) ACTION_MODS_KEY(LSHIFT, KC_A) を放す: real_mods &= ~MOD_BIT(LSHIFT) -ここで、real_mods は 'physical left shift' '物理的な左シフト' の状態を見失います。 - -キーボードレポートが送信される時、weak_mods は real_mods と論理和がとられます。 -https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/docs/ja/faq_misc.md b/docs/ja/faq_misc.md deleted file mode 100644 index 24a0e18235d0..000000000000 --- a/docs/ja/faq_misc.md +++ /dev/null @@ -1,103 +0,0 @@ -# その他の FAQ - - - -## どうやってキーボードをテストすればいいですか? :id=testing - -通常、キーボードのテストは非常に簡単です。全てのキーをひとつずつ押して、期待するキーが送信されることを確認します。例え QMK で動作していない場合でも、[QMK Configurator](https://config.qmk.fm/#/test/) のテストモードを使用すると、キーボードをチェックできます。 - -## 安全性の考慮 - -あなたはおそらくキーボードを「文鎮化」したくないでしょう。文鎮化するとファームウェアを書き換えられないようになります。リスクがあまりに高い(そしてそうでないかもしれない)ものの一部のリストを示します。 - -- キーボードマップに QK_BOOT が含まれない場合、DFU モードに入るには、PCB のリセットボタンを押す必要があります。底部のネジを外す必要があります。 -- tmk_core / common にあるファイルを触るとキーボードが操作不能になるかもしれません。 -- .hex ファイルが大きすぎると問題を引き起こします; `make dfu` コマンドはブロックを削除し、サイズを検査し(おっと、間違った順序です!)、エラーを出力し、 -キーボードへの書き込みに失敗し、DFU モードのままになります。 - - この目的のためには、Planck の最大の .hex ファイルサイズは 7000h (10進数で28672)であることに注意してください。 - -``` -Linking: .build/planck_rev4_cbbrowne.elf [OK] -Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] - -Size after: - text data bss dec hex filename - 0 22396 0 22396 577c planck_rev4_cbbrowne.hex -``` - - - 上のファイルのサイズは 22396/577ch で、28672/7000h より小さいです。 - - 適切な代わりの .hex ファイルがある限り、それをロードして再試行することができます。 - - あなたがキーボードの Makefile で指定したかもしれない一部のオプションは、余分なメモリを消費します; BOOTMAGIC_ENABLE、MOUSEKEY_ENABLE、EXTRAKEY_ENABLE、CONSOLE_ENABLE、API_SYSEX_ENABLE に注意してください。 -- DFU ツールは(オプションの余計なフルーツサラダを投げ込まない限り)ブートローダに書き込むことを許可しないので、ここにはリスクはほとんどありません。 -- EEPROM の書き込みサイクルは、約100000(10万)です。ファームウェアを繰り返し継続的に書き換えるべきではありません。それは最終的に EEPROM を焼き焦がします。 - -## NKRO が動作しません -最初に、**Makefile** 内でビルドオプション `NKRO_ENABLE` を使ってファームウェアをコンパイルする必要があります。 - -**NKRO** がまだ動作しない場合は、`Magic` **N** コマンド(デフォルトでは `LShift+RShift+N`)を試してみてください。**NKRO** モードと **6KRO** モード間を一時的に切り替えるためにこのコマンドを使うことができます。**NKRO** が機能しない状況、特に BIOS の場合は **6KRO** モードに切り替える必要があります。 - - -## トラックポイントははリセット回路が必要です (PS/2 マウスサポート) -リセット回路が無いとハードウェアの不適切な初期化のために一貫性の無い結果になります。TPM754 の回路図を見てください: - -- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 -- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf - - -## 16 を超えるマトリックの列を読み込めない -列が 16 を超える場合、[matrix.h] の `read_cols()` 内の `1<<16` の代わりに `1UL<<16` を使ってください。 - -C では、AVR の場合 `1` は [16 bit] である [int] 型の1を意味し、15を超えて左にシフトすることはできません。従って、`1<<16` を計算すると予期せずゼロになります。これを回避するには `1UL` として [unsigned long] 型を使う必要があります。 - -https://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 - -## 特別なエクストラキーが動作しない(システム、オーディオコントロールキー) -QMK でそれらを使うには、`rules.mk` 内で `EXTRAKEY_ENABLE` を定義する必要があります。 - -``` -EXTRAKEY_ENABLE = yes # オーディオ制御とシステム制御 -``` - -## スリープから復帰しない - -**デバイスマネージャ**の**電源の管理**タブ内の `このデバイスで、コンピュータのスタンバイ状態を解除できるようにする` 設定を調べてください。また BIOS 設定も調べてください。スリープ中に任意のキーを押すとホストが起動するはずです。 - -## Arduino を使っていますか? - -**Arduino のピンの命名は実際のチップと異なることに注意してください。** 例えば、Arduino のピン `D0` は `PD0` ではありません。回路図を自身で確認してください。 - -- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf -- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf - -Arduino の Leonardo と micro には **ATMega32U4** が載っていて、TMK 用に使うことができますが、Arduino のブートローダが問題になることがあります。 - -## JTAG を有効にする - -デフォルトでは、キーボードが起動するとすぐに JTAG デバッグインタフェースが無効になります。JTAG 対応 MCU は `JTAGEN` ヒューズが設定された状態で出荷されており、キーボードがスイッチマトリックス、LED などに使用している可能性のある MCU の特定のピンを乗っ取ります。 - -JTAG を有効にしたままにしたい場合は、単に以下のものを `config.h` に追加します: - -```c -#define NO_JTAG_DISABLE -``` - -## USB 3 の互換性 -一部の問題は、USB 3.x ポートから USB 2.0 ポートに切り替えることで修正できます。 - - -## Mac の互換性 -### OS X 10.11 と Hub -こちらを見てください: https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 - - -## BIOS (UEFI) 設定/リジューム (スリープとウェークアップ)/電源サイクルの問題 -一部の人がキーボードが BIOS で動作しなくなった、またはリジューム(電源サイクル)の後で動作しなくなったと報告しました。 - -今のところ、この問題の根本は明確ではないですが、幾つかのビルドオプションが関係しているようです。Makefile で、`CONSOLE_ENABLE`、`NKRO_ENABLE`、`SLEEP_LED_ENABLE` あるいは他のオプションを無効にしてみてください。 - -より詳しい情報: -- https://github.com/tmk/tmk_keyboard/issues/266 -- https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/docs/ja/feature_advanced_keycodes.md b/docs/ja/feature_advanced_keycodes.md deleted file mode 100644 index 2416c742a0e8..000000000000 --- a/docs/ja/feature_advanced_keycodes.md +++ /dev/null @@ -1,185 +0,0 @@ -# 修飾キー :id=modifier-keys - - - -以下のようにキーコードとモディファイアを組み合わせることができます。押すと、モディファイアのキーダウンイベントが送信され、次に `kc` のキーダウンイベントが送信されます。放すと、`kc` のキーアップイベントが送信され、次にモディファイアのキーアップイベントが送信されます。 - -| キー | エイリアス | 説明 | -| ---------- | ---------------------------------- | ------------------------------------------------------------------- | -| `LCTL(kc)` | `C(kc)` | 左 Control を押しながら `kc` を押します。 | -| `LSFT(kc)` | `S(kc)` | 左 Shift を押しながら `kc` を押します。 | -| `LALT(kc)` | `A(kc)`, `LOPT(kc)` | 左 Alt を押しながら `kc`を押します。 | -| `LGUI(kc)` | `G(kc)`, `LCMD(kc)`, `LWIN(kc)` | 左 GUI を押しながら `kc` を押します。 | -| `RCTL(kc)` | | 右 Control を押しながら `kc` を押します。 | -| `RSFT(kc)` | | 右 Shift を押しながら `kc` を押します。 | -| `RALT(kc)` | `ROPT(kc)`, `ALGR(kc)` | 右 Alt を押しながら `kc` を押します。 | -| `RGUI(kc)` | `RCMD(kc)`, `LWIN(kc)` | 右 GUI を押しながら `kc` を押します。 | -| `LSG(kc)` | `SGUI(kc)`, `SCMD(kc)`, `SWIN(kc)` | 左 Shift と左 GUI を押しながら `kc` を押します。 | -| `LAG(kc)` | | 左 Alt と左 GUI を押しながら `kc` を押します。 | -| `RSG(kc)` | | 右 Shift と右 GUI を押しながら `kc` を押します。 | -| `RAG(kc)` | | 右 Alt と右 GUI を押しながら `kc` を押します。 | -| `LCA(kc)` | | 左 Control と左 Alt を押しながら `kc` を押します。 | -| `LSA(kc)` | | 左 Shift と左 Alt を押しながら `kc` を押します。 | -| `RSA(kc)` | `SAGR(kc)` | 右 Shift と右 Alt (AltGr) を押しながら `kc` を押します。 | -| `RCS(kc)` | | 右 Control と右 Shift を押しながら `kc` を押します。 | -| `LCAG(kc)` | | 左 Control、左 Alt、左 GUI を押しながら `kc` を押します。 | -| `MEH(kc)` | | 左 Control、左 Shift、左 Alt を押しながら `kc` を押します。 | -| `HYPR(kc)` | | 左 Control、左 Shift、左 Alt、左 GUI を押しながら `kc` を押します。 | - -また、それらを繋げることができます。例えば、`LCTL(LALT(KC_DEL))` または `C(A(KC_DEL))` は1回のキー押下で Control+Alt+Delete を送信するキーを作成します。 - -# モディファイアの状態を確認 :id=checking-modifier-state - - -現在のモディファイアの状態は、2つの関数によって主にアクセスされます。: `get_mods()` 関数は通常のモディファイアとモッドタップの状態を、`get_oneshot_mods()` 関数はワンショットモディファイアの状態を確認する関数です。(ワンショットモディファイアはキーが押されていない限り、通常のモディファイアキーのように動作します。) - -1つ以上の特定のモディファイアが現在のモディファイアの状態に含まれているかどうかは、モディファイアの状態と、照合したいモディファイアの組み合わせに相当するモッドマスクとを AND 演算することで検出できます。 -ビット演算が使われる理由は、モディファイアの状態が (GASC)R(GASC)L の形式で1バイトとして格納されるためです。 - -従って、例を挙げると、`01000010` は LShift+RALT の内部表現です。 -C 言語におけるビット演算のより詳しい情報は、[ここ](https://en.wikipedia.org/wiki/Bitwise_operations_in_C) をクリックして、Wikipedia のページのトピックを開いてください。 - -実際には、`get_mods() & MOD_BIT(KC_)`([モディファイアキーコードのリスト](ja/keycodes_basic.md#modifiers) 参照) で、あるモディファイアが有効かどうかをチェックできるということです、また左右のモディファイアの違いが重要ではなく、両方にマッチさせたい場合は、`get_mods() & MOD_MASK_`とします。ワンショットモディファイアについても、`get_mods()` を `get_oneshot_mods()` に置き換えれば同じことができます。 - -モディファイアの特定の組み合わせが同時にアクティブなのか確認する*だけ*なら、上で説明したモディファイアの状態とモッドマスクの論理積と、モッドマスク自身の結果を比較します。: `get_mods() & == ` - -例えば、左 Control キーと 左 Shift キーのワンショットモディファイアがオンで、その他のワンショットモディファイアがオフの場合にカスタムコードを起動したいとしましょう。そうするには、`(MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))` で左 Control キーと Shift キーのモッドビットを組み合わせて目的のモッドマスクを構成し、それらを差し込みます: `get_oneshot_mods & (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT)) == (MOD_BIT(KC_LCTL) | MOD_BIT(KC_LSFT))`。モッドビットマスクの代わりに `MOD_MASK_CS` 使うと、条件を満たすために4つのモディファイアキー (左右両方の Control キーと Shift キー) を押す必要があります。 - -モッドマスクの完全なリストは、以下のとおりです。 - -| モッドマスク名 | マッチするモディファイア | -|--------------------|-------------------------------------------------------------| -| `MOD_MASK_CTRL` | 左 Control , 右 Control | -| `MOD_MASK_SHIFT` | 左 Shift , 右 Shift | -| `MOD_MASK_ALT` | 左 Alt , 右 Alt | -| `MOD_MASK_GUI` | 左 GUI , 右 GUI | -| `MOD_MASK_CS` | Control , Shift | -| `MOD_MASK_CA` | (左/右) Control , (左/右) Alt | -| `MOD_MASK_CG` | (左/右) Control , (左/右) GUI | -| `MOD_MASK_SA` | (左/右) Shift , (左/右) Alt | -| `MOD_MASK_SG` | (左/右) Shift , (左/右) GUI | -| `MOD_MASK_AG` | (左/右) Alt , (左/右) GUI | -| `MOD_MASK_CSA` | (左/右) Control , (左/右) Shift , (左/右) Alt | -| `MOD_MASK_CSG` | (左/右) Control , (左/右) Shift , (左/右) GUI | -| `MOD_MASK_CAG` | (左/右) Control , (左/右) Alt , (左/右) GUI | -| `MOD_MASK_SAG` | (左/右) Shift , (左/右) Alt , (左/右) GUI | -| `MOD_MASK_CSAG` | (左/右) Control , (左/右) Shift , (左/右) Alt , (左/右) GUI | - -`get_mods()` 関数を使って現在アクティブなモディファイアにアクセスする以外に、モディファイアの状態を変更するために使えるいくつかの関数があります。ここでは、`mods` 引数はモディファイアビットマスクを表します。 - -* `add_mods(mods)`: その他のモディファイアに影響を与えずに `mods` を有効にします。 -* `register_mods(mods)`: `add_mods` に似ていますが、キーボードにすぐにレポートを送信します。 -* `del_mods(mods)`: その他のモディファイアに影響を与えずに `mods` を無効にします。 -* `unregister_mods(mods)`: `del_mods` に似ていますが、キーボードにすぐにレポートを送信します。 -* `set_mods(mods)`: `mods` で現在のモディファイアの状態を上書きします -* `clear_mods()`: 全てのモディファイアを無効にすることによって、モディファイアの状態をリセットします。 - -同様に、`get_oneshot_mods()` 関数に加えて、ワンショットモディファイアのための関数もあります。 - -* `add_oneshot_mods(mods)`: その他のワンショットモディファイアに影響を与えずに `mods` を有効にします -* `del_oneshot_mods(mods)`: その他のワンショットモディファイアに影響を与えずに `mods` を無効にします -* `set_oneshot_mods(mods)`: `mods` で現在のワンショットモディファイアの状態を上書きします -* `clear_oneshot_mods()`: 全てのワンショットモディファイアを無効にすることによって、ワンショットモディファイアの状態をリセットします。 - -## 例 :id=examples - -次の例は、[マクロについてのページ](ja/feature_macros.md) で読める [高度なマクロ](ja/feature_macros.md?id=advanced-macro-functions) を使っています。 -### Alt + Tab の代わりの Alt + Escape :id=alt-escape-for-alt-tab - -左 Alt と `KC_ESC` が押されたときに、アプリ切り替えの(左 Alt と) `KC_TAB` のように振る舞うことを実現する単純な例です。この例は、左 Alt だけがアクティブになっているかを厳格に確認します。つまり、Alt+Shift+Esc によるアプリの逆順での切り替えはできません。また、この例は、実際の Alt+Escape キーボードショートカットを起動することはできなくなりますが、AltGr+Escape キーボードショートカットを起動することはできることに留意してください。 - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - - case KC_ESC: - // 左 Alt だけがアクティブか検知します - if ((get_mods() & MOD_BIT(KC_LALT)) == MOD_BIT(KC_LALT)) { - if (record->event.pressed) { - // KC_LALT を登録する必要はありません。既にアクティブだからです。 - // Alt モディファイアはこの KC_TAB に適用されます。 - register_code(KC_TAB); - } else { - unregister_code(KC_TAB); - } - // QMK にこれ以上キーコードの処理をさせません。 - return false; - } - // それ以外の場合は、QMK に通常通り KC_ESC の処理をさせます。 - return true; - - } - return true; -}; -``` - -### Delete の代わりの Shift + Backspace :id=shift-backspace-for-delete - -`KC_BSPC` と組み合わせることで Shift の本来の動作が取り消され、そして、`KC_DEL` に完全に置き換えられる高度な例です。この例を適切に動作させるために2つのメイン変数が作られます。: `mod_state` と `delkey_registered` です。最初の1つ目の変数は、モディファイアの状態を記憶し、`KC_DEL` を登録した後に元に戻すために使われます。2つ目の変数はブール型変数 (true または false) で、`KC_DEL` の状態を追跡して Backspace/Delete キー全体のリリースを正確に管理します。 - -前の例と対照的に、この例は厳格なモディファイアの確認を行いません。このカスタムコードを起動するには、1つまたは2つの Shift キーがアクティブな間に `KC_BSPC` を押せば十分で、他のモディファイアの状態は関係ありません。この方法は、いくつかの特典を提供します。: Ctrl+Shift+Backspace は次の単語を削除 (Control+Delete) し、Ctrl+Alt+Shift+Backspace は Ctrl+Alt+Del キーボードショートカットを実行します。 - -```c -// アクティブなモディファイアを表すバイナリデータを保持する変数を初期化します -uint8_t mod_state; -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - // 後々の参照のために現在のモディファイアの状態を変数に格納します - mod_state = get_mods(); - switch (keycode) { - - case KC_BSPC: - { - // Delete キーの状態(登録されているかどうか)を追跡するブール型変数を初期化します。 - static bool delkey_registered; - if (record->event.pressed) { - // いずれかの Shift がアクティブか検知します - if (mod_state & MOD_MASK_SHIFT) { - // 最初に、 Shift キーを KC_DEL に適用しないため、 - // 一時的に左右両方の Shift キーをキャンセルします - del_mods(MOD_MASK_SHIFT); - register_code(KC_DEL); - // KC_DEL の状態を反映させるためにブール型変数を更新します - delkey_registered = true; - // Backspace/Delete キーをタップした後でも押し続けている Shift キーが機能するように、 - // モディファイアの状態を再適用します。 - set_mods(mod_state); - return false; - } - } else { // KC_BSPC キーを離した場合 - // KC_BSPC を離しても KC_DEL が送信されている場合 - if (delkey_registered) { - unregister_code(KC_DEL); - delkey_registered = false; - return false; - } - } - // QMK に Shift キーを除いて KC_BSPC を通常通り処理させます - return true; - } - - } - return true; -}; -``` -# 過去の内容 :id=legacy-content - -このページには多くの機能が含まれていました。このページを構成していた多くのセクションをそれぞれのページに移動しました。これより下は全て単なるリダイレクトであるため、web上で古いリンクをたどっている人は探しているものを見つけることができます。 - -## レイヤー :id=switching-and-toggling-layers - -* [レイヤー](ja/feature_layers.md) - -## モッドタップ :id=mod-tap - -* [モッドタップ](ja/mod_tap.md) - -## ワンショットキー :id=one-shot-keys - -* [ワンショットキー](ja/one_shot_keys.md) - -## タップホールド設定オプション :id=tap-hold-configuration-options - -* [タップホールド設定オプション](ja/tap_hold.md) diff --git a/docs/ja/feature_audio.md b/docs/ja/feature_audio.md deleted file mode 100644 index 2d1fd8f78a49..000000000000 --- a/docs/ja/feature_audio.md +++ /dev/null @@ -1,322 +0,0 @@ -# オーディオ - - - -キーボードは音を出すことができます!Planck、Preonic あるいは特定の PWM 対応ピンにアクセスできる AVR キーボードがある場合は、単純なスピーカーを接続してビープ音を鳴らすことができます。これらのビープ音を使ってレイヤーの変化、モディファイア、特殊キーを示したり、あるいは単にイカした8ビットの曲を鳴らすことができます。 - -最大2つの同時オーディオ音声がサポートされ、1つはタイマー1によってもう一つはタイマー3によって駆動されます。以下のピンは config.h の中でオーディオ出力として定義することができます: - -Timer 1: -`#define B5_AUDIO` -`#define B6_AUDIO` -`#define B7_AUDIO` - -Timer 3: -`#define C4_AUDIO` -`#define C5_AUDIO` -`#define C6_AUDIO` - -`rules.mk` に `AUDIO_ENABLE = yes` を追加すると、他の設定無しで自動的に有効になる幾つかの異なるサウンドがあります: - -``` -STARTUP_SONG // キーボードの起動時に再生 (audio.c) -GOODBYE_SONG // QK_BOOT キーを押すと再生 (quantum.c) -AG_NORM_SONG // AG_NORM キーを押すと再生 (quantum.c) -AG_SWAP_SONG // AG_SWAP キーを押すと再生 (quantum.c) -CG_NORM_SONG // CG_NORM キーを押すと再生 (quantum.c) -CG_SWAP_SONG // CG_SWAP キーを押すと再生 (quantum.c) -MUSIC_ON_SONG // 音楽モードがアクティブになると再生 (process_music.c) -MUSIC_OFF_SONG // 音楽モードが非アクティブになると再生 (process_music.c) -CHROMATIC_SONG // 半音階音楽モードが選択された時に再生 (process_music.c) -GUITAR_SONG // ギター音楽モードが選択された時に再生 (process_music.c) -VIOLIN_SONG // バイオリン音楽モードが選択された時に再生 (process_music.c) -MAJOR_SONG // メジャー音楽モードが選択された時に再生 (process_music.c) -``` - -`config.h` の中で以下のような操作を行うことで、デフォルトの曲を上書きすることができます: - -```c -#ifdef AUDIO_ENABLE - #define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -``` - -サウンドの完全なリストは、[quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) で見つかります - このリストに自由に追加してください!利用可能な音は [quantum/audio/musical_notes.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/musical_notes.h) で見つかります。 - -特定の時にカスタムサウンドを再生するために、以下のように曲を定義することができます(ファイルの上部付近に): - -```c -float my_song[][2] = SONG(QWERTY_SOUND); -``` - -以下のように曲を再生します: - -```c -PLAY_SONG(my_song); -``` - -または、以下のようにループで再生することができます: - -```c -PLAY_LOOP(my_song); -``` - -オーディオがキーボードに組み込まれていない時に問題が起きる事を避けるために、`#ifdef AUDIO_ENABLE` / `#endif` で全てのオーディオ機能をくるむことをお勧めします。 - -オーディオで利用可能なキーコードは以下の通りです: - -* `AU_ON` - オーディオ機能をオン -* `AU_OFF` - オーディオ機能をオフ -* `AU_TOG` - オーディオ機能を切り替え - -!> これらのキーコードは全てのオーディオ機能をオンおよびオフにします。オフにするとオーディオフィードバック、オーディオクリック、音楽モードなどが完全に無効になります。 - -## ARM オーディオボリューム - -ARM デバイスの場合、DAC サンプル値を調整できます。キーボードがあなたやあなたの同僚にとって騒々しい場合、`config.h` 内の `DAC_SAMPLE_MAX` を使って最大量を設定することができます: - -```c -#define DAC_SAMPLE_MAX 65535U -``` - -## 音楽モード - -音楽モードは列を半音階に、行をオクターブにマップします。これは格子配列キーボードで最適に動作しますが、他のものでも動作させることができます。`0xFF` 未満の全てのキーコードはブロックされるため、音の演奏中は入力できません - 特別なキー/mod があればそれらは引き続き動作します。これを回避するには、音楽モードを有効にする前(あるいは後)で、KC_NO を使って別のレイヤーにジャンプします。 - -メモリの問題により、録音は実験的です - 奇妙な動作が発生した場合は、キーボードの取り外しと再接続で問題が解決するでしょう。 - -利用可能なキーコード: - -* `MU_ON` - 音楽モードをオン -* `MU_OFF` - 音楽モードをオフ -* `MU_TOG` - 音楽モードの切り替え -* `MU_MOD` - 音楽モードの循環 - * `CHROMATIC_MODE` - 半音階。行はオクターブを変更します - * `GUITAR_MODE` - 半音階、ただし行は弦を変更します (+5 階) - * `VIOLIN_MODE` - 半音階。ただし行は弦を変換します (+7 階) - * `MAJOR_MODE` - メージャースケール - -音楽モードでは、以下のキーコードは動作が異なり、通過しません: - -* `LCTL` - 録音を開始 -* `LALT` - 録音を停止/演奏を停止 -* `LGUI` - 録音を再生 -* `KC_UP` - 再生をスピードアップ -* `KC_DOWN` - 再生をスローダウン - -ピッチ標準 (`PITCH_STANDARD_A`) はデフォルトで 440.0f です - これを変更するには、`config.h` に以下のようなものを追加します: - - #define PITCH_STANDARD_A 432.0f - -音楽モードも完全に無効にすることができます。コントローラの容量が足りなくて困っている場合に役に立ちます。無効にするには、これを `config.h` に追加します: - - #define NO_MUSIC_MODE - -### 音楽マスク - -デフォルトで、`MUSIC_MASK` は `keycode < 0xFF` に設定されます。これは、`0xFF` 未満のキーコードが音に変換され、何も出力しないことを意味します。`config.h` の中で以下のものを定義することで、これを変更することができます: - - #define MUSIC_MASK keycode != KC_NO - -これは全てのキーコードを捕捉します - これは、キーボードを再起動するまで、音楽モードで動けなくなることに注意してください! - -どのキーコードを引き続き処理するかを制御する、より高度な方法については、`.c` の中の `music_mask_kb(keycode)` および `keymap.c` の中の `music_mask_user(keycode)` を使うことができます: - - bool music_mask_user(uint16_t keycode) { - switch (keycode) { - case RAISE: - case LOWER: - return false; - default: - return true; - } - } - -false を返すものはマスクの一部では無く、常に処理されます。 - -### 音楽マップ - -デフォルトでは、音楽モードはキーのスケールを決定するために列と行を使います。キーボードレイアウトに一致する長方形のマトリックスを使うキーボードの場合、これで十分です。しかし、(Planck Rev6 あるいは多くの分割キーボードなどのように)より複雑なマトリックスを使うキーボードの場合、非常に歪んだ感じを受けることになります。 - -しかしながら、音楽マップオプションにより、音楽モードのためにスケーリングを再マップすることができるため、レイアウトに一致し、より自然になります。 - -この機能を使うには、`#define MUSIC_MAP` を `config.h` ファイルに追加します。そして、`キーボードの名前.c` または `keymap.c` に `uint8_t music_map` を追加します。 - -```c -const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS] = LAYOUT_ortho_4x12( - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 -); -``` - -キーボードが使用する `LAYOUT` マクロも使用したいでしょう。これは正しいキーの位置にマップします。キーボードレイアウトの左下から開始し、右に移動してさらに上に移動します。完全なマトリックスができるまで、全てのエントリを入力します。 - -これを実装する方法の例として、[Planck Keyboard](https://github.com/qmk/qmk_firmware/blob/e9ace1487887c1f8b4a7e8e6d87c322988bec9ce/keyboards/planck/planck.c#L24-L29) を見ることができます。 - -## オーディオクリック - -これは、ボタンを押すたびにクリック音を追加し、キーボードからのクリック音をシミュレートします。キーを押すたびにわずかに音が異なるため、すばやく入力しても長い単一の音のようには聞こえません。 - -* `CK_TOGG` - ステータスを切り替えます (有効にされた場合、音を再生します) -* `CK_ON` - オーディオクリックをオンにします (音を再生します) -* `CK_OFF` - オーディオクリックをオフにします (音を再生しません) -* `CK_RST` - 周波数をデフォルトの状態に再設定します (デフォルトの周波数で音を再生します) -* `CK_UP` - クリック音の周波数を増やします (新しい周波数で音を再生します) -* `CK_DOWN` - クリック音の周波数を減らします (新しい周波数で音を再生します) - - -容量を節約するためにデフォルトではこの機能は無効です。有効にするには、`config.h` に以下を追加します: - - #define AUDIO_CLICKY - - -これらの値を定義することで、デフォルト、最小および最大周波数、ステッピングおよび組み込みのランダム性を設定することができます: - -| オプション | デフォルト値 | 説明 | -|--------|---------------|-------------| -| `AUDIO_CLICKY_FREQ_DEFAULT` | 440.0f | クリック音のデフォルト/開始音の周波数を設定します。 | -| `AUDIO_CLICKY_FREQ_MIN` | 65.0f | 最小周波数を設定します (60f 未満は少しバグがあります)。 | -| `AUDIO_CLICKY_FREQ_MAX` | 1500.0f | 最大周波数を設定します。高すぎると同僚があなたを攻撃する可能性があります。 | -| `AUDIO_CLICKY_FREQ_FACTOR` | 1.18921f | UP/DOWN キーコードのステップを設定します。これは掛け算の係数です。デフォルトでは、音楽のマイナーの1/3ずつ、周波数を上げ/下げします。 | -| `AUDIO_CLICKY_FREQ_RANDOMNESS` | 0.05f | クリックのランダム性の係数を設定します。これを `0f` に設定すると各クリックが同一になり、`1.0f` に設定するとこの音は90年代のコンピュータ画面のスクロール/タイピングの効果があります。 | -| `AUDIO_CLICKY_DELAY_DURATION` | 1 | 1がテンポの 1/16、または64分音符である整数音符の長さ (実装の詳細については、`quantum/audio/musical_notes.h` を見てください)。メインのクリック効果は、この時間だけ遅れます。これらを6-12前後の値に調整すると、うるさいスイッチの補正に役立ちます。 | - - - - -## MIDI 機能 - -これはまだ WIP ですが、何が起きているかを見るために、`quantum/process_keycode/process_midi.c` を調べてください。Makefile から有効にします。 - - -## オーディオキーコード - -| キー | エイリアス | 説明 | -|----------------|---------|----------------------------------| -| `AU_ON` | | オーディオモードオン | -| `AU_OFF` | | オーディオモードオフ | -| `AU_TOG` | | オーディオモードを切り替えます | -| `CLICKY_TOGGLE` | `CK_TOGG` | オーディオクリックモードを切り替えます | -| `CLICKY_UP` | `CK_UP` | クリック音の周波数を増やします | -| `CLICKY_DOWN` | `CK_DOWN` | クリック音の周波数を減らします | -| `CLICKY_RESET` | `CK_RST` | 周波数をデフォルトに再設定します | -| `MU_ON` | | 音楽モードをオンにします | -| `MU_OFF` | | 音楽モードをオフにします | -| `MU_TOG` | | 音楽モードを切り替えます | -| `MU_MOD` | | 音楽モードを循環します | - - diff --git a/docs/ja/feature_auto_shift.md b/docs/ja/feature_auto_shift.md deleted file mode 100644 index cf67b3397711..000000000000 --- a/docs/ja/feature_auto_shift.md +++ /dev/null @@ -1,135 +0,0 @@ -# 自動シフト: なぜシフトキーが必要ですか? - - - -キーをタップすると、その文字を取得します。キーをタップするが、*わずかに*長く押し続けると、シフト状態になります。ほら!シフトキーは必要ありません! - -## なぜ自動シフトなのですか? - -多くの人が腱鞘炎などの症状に苦しんでいます。一般的な原因は、指を繰り返し長い距離を伸ばすことです。私たちはキーボード上でシフトキーに手を伸ばすためにあまりにも頻繁に小指を伸ばします。自動シフトキーはそれを軽減しようとしています。 - -## どのように動作しますか? - -キーをタップする時に、キーを放す前にほんの短い間押したままにします。この押したままにする時間は全ての人にとって異なる長さです。自動シフトは、定数 `AUTO_SHIFT_TIMEOUT` を定義し、これは普段の押された状態の時間の2倍に通常は設定されます。タイマーは、キーを押す時に開始され、キーを放す時に止まります。押された時間が `AUTO_SHIFT_TIMEOUT` 以上の場合に、キーのシフトバージョンが発行されます。時間が `AUTO_SHIFT_TIMEOUT` 時間よりも短い場合は、通常の状態が発行されます。 - -## 自動シフトには制限がありますか? - -残念ながらあります。 - -1. キーリピートが動作しなくなります。例えば、20個の 'a' 文字が必要な場合、'a' キーを1、2秒押し続けるかもしれません。オペレーティングシステムに押されたキーの状態を発行する代わりに押された時間を計るので、自動シフトでは動作しません。 -2. シフトをするつもりがない時にシフトされた文字を取得し、シフトしたい時にそうではない他の文字を取得するでしょう。これは結局は練習になります。急いでいる時は、シフトされたバージョンのために十分長くキーを押したと思うかもしれませんが、そうではありませんでした。一方、キーをタップしていると思うかもしれませんが、実際には予想よりも少し長い間押していました。 - -## どうやって自動シフトを有効にしますか? - -キーマップフォルダの `rules.mk` に追加します: - - AUTO_SHIFT_ENABLE = yes - -`rules.mk` が存在しない場合、それを作成することができます。 - -そして自動シフトキーを有効にした新しいファームウェアをコンパイルしてインストールします!以上です! - -## モディファイア - -デフォルトで、1つ以上のモディファイアと一緒にキーが押されると自動シフトは無効になります。従って、本当に長い間 Ctrl+A を保持しても、Ctrl+Shift+A と同じではありません。 - -`config.h` に定義を追加することで、モディファイアの自動シフトを再度有効にすることができます - -```c -#define AUTO_SHIFT_MODIFIERS -``` - -この場合、`AUTO_SHIFT_TIMEOUT` を超えて押された Ctrl+A は Ctrl+Shift+A として送信されます - - -## 自動シフトの設定 - -必要に応じて、自動シフトの挙動を変更することができる幾つかの設定があります。キーマップフォルダにある `config.h` に様々な変数を設定することで行われます。`config.h` ファイルが存在しない場合、それを作成することができます。 - -例 - -```c -#pragma once - -#define AUTO_SHIFT_TIMEOUT 150 -#define NO_AUTO_SHIFT_SPECIAL -``` - -### AUTO_SHIFT_TIMEOUT (単位: ミリ秒) - -これは、シフトされた状態を取得するためにどれだけ長くキーを押し続けなければならないかを制御します。 -明らかにこれは人によって異なります。一般的な人にとって、135 から 150 の設定がうまく機能します。ただし、少なくとも 175 の値から開始する必要があります。これはデフォルト値です。その後、ここから下げていきます。間違って検出することなくシフトされた状態を取得するのに必要な、最も短い時間を得るという考え方です。 - -完璧に動作するまで、いろいろな値を試してみます。多くの人は、全てが所定の値で適切に動作するものの、時々、1つあるいは2つのキーがシフト状態を発行することが分かるでしょう。これは単に習慣と、幾つかのキーを他のキーよりも少し長く押し続けることによるものです。この値を見つけたら、問題のキーを通常よりも少し早くタップするとともに、その値を設定します。 - -?> 自動シフトには、この値を素早く取得するのに役立つ3つの特別なキーがあります。詳細は「自動シフトのセットアップ」を見てください! - -### NO_AUTO_SHIFT_SPECIAL (単純にこのように定義します) - --\_, =+, [{, ]}, ;:, '", ,<, .> および /? を含む特殊キーを自動シフトしません - -### NO_AUTO_SHIFT_NUMERIC (単純にこのように定義します) - -0から9までの数字キーを自動シフトしません。 - -### NO_AUTO_SHIFT_ALPHA (単純にこのように定義します) - -AからZを含むアルファベット文字を自動シフトしません。 - -## 自動シフトセットアップの使用 - -これにより、`AUTO_SHIFT_TIMEOUT` で設定している時間を一時的に増減させたり報告するために、3つのキーを定義することができます。 - -### セットアップ - -3つのキーを一時的にキーマップにマップします: - -| キー名 | 説明 | -|----------|-----------------------------------------------------| -| KC_ASDN | 自動シフトタイムアウト変数を下げる | -| KC_ASUP | 自動シフトタイムアウト変数を上げる | -| KC_ASRP | 現在の自動シフトタイムアウト値を報告する | -| KC_ASON | 自動シフト機能をオンにする | -| KC_ASOFF | 自動シフト機能をオフにする | -| KC_ASTG | 自動シフト機能の状態を切り替える | - -新しいファームウェアをコンパイルしてアップロードします。 - -### 使い方 - -これらのテスト中は、完全に普段通り入力する必要があり、意図的にシフトされたキーを使わずに入力するように注意する必要があります。 - -1. アルファベットの複数の文を入力します。 -2. 大文字に注意してください。 -3. 大文字が存在しない場合は、自動シフトタイムアウト値を減らすために `KC_ASDN` にマップしたキーを押し、ステップ1に戻ります。 -4. 大文字が幾つかある場合は、押す時間を短くしてこれらのキーをタップする必要があるか、あるいはタイムアウトを増やす必要があるかを決定します。 -5. タイムアウトを増やすことに決めた場合は、`KC_ASUP` にマップしたキーを押し、ステップ1に戻ります。 -6. 結果に満足したら、`KC_ASRP` にマップしたキーを押します。キーボードは `AUTO_SHIFT_TIMEOUT` の値を自動的に入力します。 -7. 報告された値で `config.h` の `AUTO_SHIFT_TIMEOUT` を更新します。 -8. `config.h` に `AUTO_SHIFT_NO_SETUP` を追加します。 -9. `KC_ASDN`、`KC_ASUP` および `KC_ASRP` のキーバインディングを削除します。 -10. 新しいファームウェアをコンパイルしてアップロードします。 - -#### 実行例 - - hello world. my name is john doe. i am a computer programmer playing with - keyboards right now. - - [KC_ASDN を何度か押します] - - heLLo woRLd. mY nAMe is JOHn dOE. i AM A compUTeR proGRaMMER PlAYiNG witH - KEYboArDS RiGHT NOw. - - [KC_ASUP を数回押します] - - hello world. my name is john Doe. i am a computer programmer playing with - keyboarDs right now. - - [KC_ASRPを押します] - - 115 - -キーボードは現在の `AUTO_SHIFT_TIMEOUT` 値を表す `115` を入力しました。これで設定が完了しました!テスト中に現れる *D* キーを少し練習してください。それで完璧です。 diff --git a/docs/ja/feature_backlight.md b/docs/ja/feature_backlight.md deleted file mode 100644 index 150069607c20..000000000000 --- a/docs/ja/feature_backlight.md +++ /dev/null @@ -1,225 +0,0 @@ -# バックライト :id=backlighting - - - -多くのキーボードは、キースイッチを貫通して配置されたり、キースイッチの下に配置された個々の LED によって、バックライトキーをサポートします。この機能は通常スイッチごとに単一の色しか使用できないため、[RGB アンダーグロー](ja/feature_rgblight.md)および [RGB マトリックス](ja/feature_rgb_matrix.md)機能のどちらとも異なりますが、キーボードに複数の異なる単一色の LED を取り付けることは当然可能です。 - -QMK は *パルス幅変調* (*Pulse Width Modulation*) すなわち PWM として知られている技術で、一定の比率で素早くオンおよびオフを切り替えることで、これらの LED の輝度を制御できます。PWM 信号のデューティサイクルを変えることで、調光の錯覚を起こすことができます。 - -MCU は、GPIO ピンにはそんなに電流を供給できません。MCU から直接バックライトに給電せずに、バックライトピンは LED への電力を切り替えるトランジスタあるいは MOSFET に接続されます。 - -ほとんどのキーボードではバックライトをサポートしている場合にデフォルトで有効になっていますが、もし機能しない場合は `rules.mk` が以下を含んでいることを確認してください: - -```makefile -BACKLIGHT_ENABLE = yes -``` - -## キーコード :id=keycodes - -有効にすると、以下のキーコードを使ってバックライトレベルを変更することができます。 - -| キー | 説明 | -| --------- | ------------------------------------ | -| `BL_TOGG` | バックライトをオンあるいはオフにする | -| `BL_STEP` | バックライトレベルを循環する | -| `BL_ON` | バックライトを最大輝度に設定する | -| `BL_OFF` | バックライトをオフにする | -| `BL_INC` | バックライトレベルを上げる | -| `BL_DEC` | バックライトレベルを下げる | -| `BL_BRTG` | バックライトの明滅動作を切り替える | - -## 関数群 :id=functions - -次の関数を使って、カスタムコードでバックライトを変更することができます: - -| 関数 | 説明 | -| ------------------------ | -------------------------------------------- | -| `backlight_toggle()` | バックライトをオンあるいはオフにする | -| `backlight_enable()` | バックライトをオンにする | -| `backlight_disable()` | バックライトをオフにする | -| `backlight_step()` | バックライトレベルを循環する | -| `backlight_increase()` | バックライトレベルを上げる | -| `backlight_decrease()` | バックライトレベルを下げる | -| `backlight_level(x)` | バックライトのレベルを特定のレベルに設定する | -| `get_backlight_level()` | 現在のバックライトレベルを返す | -| `is_backlight_enabled()` | バックライトが現在オンかどうかを返す | - -バックライトの明滅が有効の場合(以下を参照)、以下の関数も利用できます: - -| 関数 | 説明 | -|-----------------------|----------------------------------------------| -| `breathing_toggle()` | バックライトの明滅動作をオンまたはオフにする | -| `breathing_enable()` | バックライトの明滅動作をオンにする | -| `breathing_disable()` | バックライトの明滅動作をオフにする | - -## 設定 :id=configuration - -どのドライバを使うかを選択するには、以下を使って `rules.mk` を設定します: - -```makefile -BACKLIGHT_DRIVER = software -``` - -有効なドライバの値は `pwm`, `software`, `custom`, `no` です。各ドライバについてのヘルプは以下を見てください。 - -バックライトを設定するには、`config.h` の中で以下の `#define` をします: - -| 定義 | デフォルト | 説明 | -| ----------------------------- | ------------------ | --------------------------------------------------------------------------------------------- | -| `BACKLIGHT_PIN` | *定義なし* | LED を制御するピン | -| `BACKLIGHT_LEVELS` | `3` | 輝度のレベルの数 (オフを除いて最大 31) | -| `BACKLIGHT_CAPS_LOCK` | *定義なし* | バックライトを使って Caps Lock のインジケータを有効にする (専用 LED の無いキーボードのため) | -| `BACKLIGHT_BREATHING` | *定義なし* | サポートされる場合は、バックライトの明滅動作を有効にする | -| `BREATHING_PERIOD` | `6` | 各バックライトの "明滅" の長さ(秒) | -| `BACKLIGHT_ON_STATE` | `1` | バックライトが "オン" の時のバックライトピンの状態 - high の場合は `1`、low の場合は `0` | -| `BACKLIGHT_LIMIT_VAL` | `255` | バックライトの最大デューティサイクル -- `255` で最大輝度になり、それ未満では最大値が減少する | -| `BACKLIGHT_DEFAULT_LEVEL` | `BACKLIGHT_LEVELS` | EEPROM をクリアする時に使うデフォルトのバックライトレベル | -| `BACKLIGHT_DEFAULT_BREATHING` | *定義なし* | EEPROM をクリアする時に、バックライトのブリージングを有効にするかどうか | - -独自のキーボードを設計しているわけではない限り、通常は `BACKLIGHT_PIN` または `BACKLIGHT_ON_STATE` を変更する必要はありません。 - -### バックライトオン状態 :id=backlight-on-state - -ほとんどのバックライトの回路は N チャンネルの MOSFET あるいは NPN トランジスタによって駆動されます。これは、トランジスタを *オン* にして LED を点灯させるには、ゲートまたはベースに接続されているバックライトピンを *high* に駆動する必要があることを意味します。 -ただし、P チャンネルの MOSFET あるいは PNP トランジスタが使われる場合があります。この場合、トランジスタがオンの時、ピンは代わりに *low* で駆動されます。 - -この機能は `BACKLIGHT_ON_STATE` を定義することでキーボードレベルで設定されます。 - -### AVR ドライバ :id=avr-driver - -`pwm` ドライバはデフォルトで設定されますが、`rules.mk` 内での同等の設定は以下の通りです: - -```makefile -BACKLIGHT_DRIVER = pwm -``` - -#### 注意事項 :id=avr-caveats - -AVR ボードでは、QMK はどのドライバを使うかを以下の表に従って自動的に決定します: - -| バックライトピン | AT90USB64/128 | AT90USB162 | ATmega16/32U4 | ATmega16/32U2 | ATmega32A | ATmega328/P | -| ---------------- | ------------- | ---------- | ------------- | ------------- | --------- | ----------- | -| `B1` | | | | | | Timer 1 | -| `B2` | | | | | | Timer 1 | -| `B5` | Timer 1 | | Timer 1 | | | | -| `B6` | Timer 1 | | Timer 1 | | | | -| `B7` | Timer 1 | Timer 1 | Timer 1 | Timer 1 | | | -| `C4` | Timer 3 | | | | | | -| `C5` | Timer 3 | Timer 1 | | Timer 1 | | | -| `C6` | Timer 3 | Timer 1 | Timer 3 | Timer 1 | | | -| `D4` | | | | | Timer 1 | | -| `D5` | | | | | Timer 1 | | - -他の全てのピンはタイマー支援ソフトウェア PWM を使います。 - -| オーディオピン | オーディオタイマ | ソフトウェア PWM タイマ | -| -------------- | ---------------- | ----------------------- | -| `C4` | Timer 3 | Timer 1 | -| `C5` | Timer 3 | Timer 1 | -| `C6` | Timer 3 | Timer 1 | -| `B5` | Timer 1 | Timer 3 | -| `B6` | Timer 1 | Timer 3 | -| `B7` | Timer 1 | Timer 3 | - -両方のタイマーがオーディオのために使われている場合、バックライト PWM はハードウェアタイマを使うことができず、代わりにマトリックススキャンの間に引き起こされます。この場合、PWM の計算は十分なタイミングの精度で呼ばれない可能性があるため、バックライトの明滅はサポートされず、バックライトもちらつくかもしれません。 - -#### ハードウェア PWM 実装 :id=hardware-pwm-implementation - -バックライト用にサポートされているピンを使う場合、QMK は PWM 信号を出力するように設定されたハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。 -希望の輝度が計算され、`OCRxx` レジスタに格納されます。カウンタがこの値まで達すると、バックライトピンは low になり、カウンタがリセットされると再び high になります。 -このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。`0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。 - -明滅動作の効果はカウンタがリセットされる(秒間あたりおよそ244回)たびに呼び出される `TIMER1_OVF_vect` の割り込みハンドラを登録することで可能になります。 -このハンドラで、増分カウンタの値が事前に計算された輝度曲線にマップされます。明滅動作をオフにするには、割り込みを単純に禁止し、輝度を EEPROM に格納されているレベルに再設定します。 - -#### タイマー支援 PWM 実装 :id=timer-assisted-implementation - -`BACKLIGHT_PIN` がハードウェアバックライトピンに設定されていない場合、QMK はソフトウェア割り込みを引き起こすように設定されているハードウェアタイマを使います。タイマーは 0 にリセットする前に `ICRx` (デフォルトでは `0xFFFF`) までカウントします。 -0 に再設定すると、CPU は LED をオンにする OVF (オーバーフロー)割り込みを発火し、デューティサイクルを開始します。 -希望の輝度が計算され、`OCRxx` レジスタに格納されます。カウンタがこの値に達すると、CPU は比較出力一致割り込みを発火し、LED をオフにします。 -このように `OCRxx` は基本的に LED のデューティサイクル、従って輝度を制御します。 `0x0000` は完全にオフで、 `0xFFFF` は完全にオンです。 - -明滅の効果はハードウェア PWM 実装と同じです。 - -### ARM ドライバ :id=arm-configuration - -まだ初期段階ですが、ARM バックライトサポートは最終的に AVR と同等の機能を持つことを目指しています。`pwm` ドライバはデフォルトで設定されますが、`rules.mk` 内での同等の設定は以下の通りです: - -```makefile -BACKLIGHT_DRIVER = pwm -``` - -#### ChibiOS の設定 :id=arm-configuration - -以下の `#define` は ARM ベースのキーボードにのみ適用されます: - -| 定義 | デフォルト | 説明 | -| ----------------------- | ---------- | ----------------------- | -| `BACKLIGHT_PWM_DRIVER` | `PWMD4` | 使用する PWM ドライバ | -| `BACKLIGHT_PWM_CHANNEL` | `3` | 使用する PWM チャンネル | -| `BACKLIGHT_PAL_MODE` | `2` | 使用するピン代替関数 | - -これらの値を決定するには、特定の MCU の ST データシートを参照してください。独自のキーボードを設計しているわけではない場合、通常はこれらを変更する必要はありません。 - -#### 注意事項 :id=arm-caveats - -現在のところ、ハードウェア PWM のみがサポートされ、タイマー支援はなく、自動設定は提供されません。 - -### ソフトウェア PWM ドライバ :id=software-pwm-driver - -このモードでは、他のキーボードのタスクを実行中に PWM は「エミュレート」されます。追加のプラットフォーム設定なしで最大のハードウェア互換性を提供します。トレードオフは、キーボードが忙しい時にバックライトが揺れる可能性があることです。有効にするには、`rules.mk` に以下を追加します: - -```makefile -BACKLIGHT_DRIVER = software -``` - -#### 複数のバックライトピン :id=multiple-backlight-pins - -ほとんどのキーボードは、全てのバックライト LED を制御するたった1つのバックライトピンを持ちます (特にバックライトがハードウェア PWM ピンに接続されている場合)。 -ソフトウェア PWM では、複数のバックライトピンを定義することができます。これらのピンは PWM デューティサイクル時に同時にオンおよびオフになります。 - -この機能により、例えば Caps Lock LED (またはその他の制御可能な LED) の輝度を、バックライトの他の LED と同じレベルに設定することができます。Caps Lock LED は通常バックライトとは別のピンに配線されるため、Caps Lock の代わりに Control をマップしていて、Caps Lock がオンの時に Caps Lock LED ではなくバックライトの一部をアクティブにする必要がある場合に便利です。 - -複数のバックライトピンをアクティブにするには、`config.h` に `BACKLIGHT_PIN` の代わりに次のようなものを追加します: - -```c -#define BACKLIGHT_PINS { F5, B2 } -``` - -### カスタムドライバ :id=custom-driver - -上記ドライバのいずれもキーボードに適用されていない場合(例えば、バックライトを制御するのに別の IC を使用している場合)、QMK が提供しているこの簡単な API を使ってカスタムバックライトドライバを実装することができます。有効にするには、`rules.mk` に以下を追加します: - -```makefile -BACKLIGHT_DRIVER = custom -``` - -それから次のフックのいずれかを実装します: - -```c -void backlight_init_ports(void) { - // オプション - 起動時に実行されます - // 通常、ここでピンを設定します -} -void backlight_set(uint8_t level) { - // オプション - レベルの変更時に実行されます - // 通常、ここで新しい値に応答します -} - -void backlight_task(void) { - // オプション - 定期的に実行されます - // これはメインキーボードループで呼び出されることに注意してください - // そのため、ここで長時間実行されるアクションはパフォーマンスの問題を引き起こします -} -``` - -## 回路図の例 - -この一般的な例では、バックライト LED は全て N チャンネル MOSFET に向かって並列に接続されています。そのゲートピンは、リンギングを回避するため 470Ωの抵抗を介してマイクロコントローラの GPIO ピンの1つに接続されています。 -プルダウン抵抗もゲートピンとグランドの間に配置されており、MCU によって駆動されていない場合にプルダウン抵抗を定義された状態に保ちます。 -これらの抵抗値は重要ではありません。詳細については、[this Electronics StackExchange question](https://electronics.stackexchange.com/q/68748) を参照してください。 - -![バックライトの回路例](https://i.imgur.com/BmAvoUC.png) diff --git a/docs/ja/feature_bluetooth.md b/docs/ja/feature_bluetooth.md deleted file mode 100644 index 3c71a18ec1f1..000000000000 --- a/docs/ja/feature_bluetooth.md +++ /dev/null @@ -1,49 +0,0 @@ -# Bluetooth - - - -## Bluetooth の既知のサポートハードウェア - -現在のところ Bluetooth のサポートは AVR ベースのチップに限られます。Bluetooth 2.1 については、QMK は RN-42 モジュールをサポートします。より最近の BLE プロトコルについては、現在のところ Adafruit Bluefruit SPI Friend のみが直接サポートされています。iOS デバイスに接続するには、BLE が必要です。iOS はマウス入力をサポートしないことに注意してください。 - -| ボード | Bluetooth プロトコル | 接続タイプ | rules.mk | Bluetooth チップ | -| ---------------------------------------------------------------- | -------------------- | ---------- | ------------------------- | ---------------- | -| Roving Networks RN-42 (Sparkfun Bluesmirf) | Bluetooth Classic | UART | `BLUETOOTH = RN42` | RN-42 | -| [Bluefruit LE SPI Friend](https://www.adafruit.com/product/2633) | Bluetooth Low Energy | SPI | `BLUETOOTH = AdafruitBLE` | nRF51822 | - -まだサポートされていませんが、可能性のあるもの: -* [Bluefruit LE UART Friend](https://www.adafruit.com/product/2479)。[tmk 実装がおそらく見つかります](https://github.com/tmk/tmk_keyboard/issues/514) -* RN-42 ファームウェアが書き込まれた HC-05 ボード。どちらも明らかに CSR BC417 チップを使っています。RN-42 ファームウェアを使って書き込むと、HID 機能が提供されます。 -* Sparkfun Bluetooth Mate -* HM-13 ベースのボード - -### Adafruit BLE SPI Friend -現在のところ QMK によってサポートされている唯一の bluetooth チップセットは、Adafruit Bluefruit SPI Friend です。Adafruit のカスタムファームウェアを実行する Nordic nRF5182 ベースのチップです。データは Hardware SPI を介した Adafruit の SDEP を使って転送されます。[Feather 32u4 Bluefruit LE](https://www.adafruit.com/product/2829) は Adafruit ファームウェアを搭載した Nordic BLE チップに SPI 経由で接続された AVR mcu であるため、サポートされます。SPI friend を使ってカスタムボードを構築する場合、32u4 feather が使用するピン選択を使うのが最も簡単ですが、以下の定義で config.h オプションでピンを変更することができます: -* #define AdafruitBleResetPin D4 -* #define AdafruitBleCSPin B4 -* #define AdafruitBleIRQPin E6 - -Bluefruit UART friend は SPI friend に変換することができますが、これにはMDBT40 チップへの直接の再書き込みとはんだ付けが[必要です](https://github.com/qmk/qmk_firmware/issues/2274)。 - - -## Bluetooth の Rules.mk オプション - -現在サポートされている Bluetooth チップセットは [N-キーロールオーバー (NKRO)](ja/reference_glossary.md#n-key-rollover-nkro) をサポートしていません。そのため、`rules.mk` に `NKRO_ENABLE = no` を含めなければなりません。 - -Bluetooth を有効にするには、以下のうちの1つだけを使ってください: -* BLUETOOTH_ENABLE = yes (レガシーオプション) -* BLUETOOTH = RN42 -* BLUETOOTH = AdafruitBLE - -## Bluetooth キーコード - -これは複数のキーボードの出力が選択できる場合に使われます。現在のところ、これは USB と Bluetooth の両方をサポートするキーボードで、それらの間の切り替えのみが可能です。 - -| 名前 | 説明 | -| ---------- | ------------------------------------- | -| `OUT_AUTO` | USB と Bluetooth を自動的に切り替える | -| `OUT_USB` | USB のみ | -| `OUT_BT` | Bluetooth のみ | diff --git a/docs/ja/feature_bootmagic.md b/docs/ja/feature_bootmagic.md deleted file mode 100644 index 2ad6fc85313a..000000000000 --- a/docs/ja/feature_bootmagic.md +++ /dev/null @@ -1,182 +0,0 @@ -# ブートマジック - - - -再書き込みせずにキーボードの挙動を変更することができる、3つの独立した関連する機能があります。それぞれは似たような機能を持ちますが、キーボードがどのように設定されているかによって異なる方法でアクセスされます。 - -**ブートマジック**は初期化の間にキーボードを設定するためのシステムです。ブートマジックコマンドを起動するには、ブートマジックキーと1つ以上のコマンドキーを押し続けます。 - -**ブートマジックキーコード** は前に `MAGIC_` が付いており、キーボードが初期化された*後で*ブートマジックの機能にアクセスすることができます。キーコードを使うには、他のキーコードと同じようにそれらをキーマップに割り当てます。 - -以前は**マジック**として知られていた**コマンド**は、キーボードの異なる側面を制御することができる別の機能です。ブートマジックと一部の機能を共有しますが、コンソールにバージョン情報を出力するような、ブートマジックにはできないこともできます。詳細は、[コマンド](ja/feature_command.md)を見てください。 - -一部のキーボードでは、ブートマジックはデフォルトで無効になっています。その場合、`rules.mk` 内で以下のように明示的に有効にする必要があります: - -```make -BOOTMAGIC_ENABLE = yes -``` - -?> `full` の代わりに `yes` が使われていることがあるかもしれませんが、これは問題ありません。ただし、`yes` は非推奨で、理想的には `full` (あるいは`lite`) が使われるべきです。 - -さらに、以下を `rules.mk` ファイルに追加することで、[ブートマジックライト](#bootmagic-lite) (スケールダウンした、とても基本的なバージョンのブートマジック)を使うことができます: - -```make -BOOTMAGIC_ENABLE = lite -``` - -## ホットキー - -キーボードを接続しながら、ブートマジックキー(デフォルトはスペース)と目的のホットキーを押します。例えば、スペースと `B` を押したままにすると、ブートローダに入ります。 - -| ホットキー | 説明 | -|------------------|---------------------------------------------| -| エスケープ | EEPROM のブートマジック設定を無視する | -| `B` | ブートローダに入る | -| `D` | シリアルを介するデバッグ出力の切り替え | -| `X` | キーマトリックスのデバッグ出力の切り替え | -| `K` | キーボードのデバッグの切り替え | -| `M` | マウスのデバッグの切り替え | -| `L` | EE_HANDS 左右設定に、"左手"を設定 | -| `R` | EE_HANDS 左右設定に、"右手"を設定 | -| Backspace | EEPROM をクリア | -| Caps Lock | Caps Lock を左コントロールとして扱うかを切り替え | -| 左 Control | Caps Lock と左コントロールの入れ替えを切り替え | -| 左 Alt | 左 Alt と左 GUI の入れ替えを切り替え | -| 右 Alt | 右 Alt と右 GUI の入れ替えを切り替え | -| 左 GUI | GUI キーの有効・無効を切り替え (ゲームの時に便利です) | -| ` | ` とエスケープの入れ替えを切り替え | -| `\` | `\` とバックスペースの入れ替えを切り替え | -| `N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | -| `0` | レイヤー 0 をデフォルトレイヤーにする | -| `1` | レイヤー 1 をデフォルトレイヤーにする | -| `2` | レイヤー 2 をデフォルトレイヤーにする | -| `3` | レイヤー 3 をデフォルトレイヤーにする | -| `4` | レイヤー 4 をデフォルトレイヤーにする | -| `5` | レイヤー 5 をデフォルトレイヤーにする | -| `6` | レイヤー 6 をデフォルトレイヤーにする | -| `7` | レイヤー 7 をデフォルトレイヤーにする | - -## キーコード :id=keycodes - -| キー | エイリアス | 説明 | -|----------------------------------|---------|--------------------------------------------------------------------------| -| `MAGIC_SWAP_CONTROL_CAPSLOCK` | `CL_SWAP` | Caps Lock と左コントロールの入れ替え | -| `MAGIC_UNSWAP_CONTROL_CAPSLOCK` | `CL_NORM` | Caps Lock と左コントロールの入れ替えの解除 | -| `MAGIC_CAPSLOCK_TO_CONTROL` | `CL_CTRL` | Caps Lock をコントロールとして扱う | -| `MAGIC_UNCAPSLOCK_TO_CONTROL` | `CL_CAPS` | Caps Lock をコントロールとして扱うことを止める | -| `MAGIC_SWAP_LCTL_LGUI` | `LCG_SWP` | 左コントロールと GUI の入れ替え | -| `MAGIC_UNSWAP_LCTL_LGUI` | `LCG_NRM` | 左コントロールと GUI の入れ替えを解除 | -| `MAGIC_SWAP_RCTL_RGUI` | `RCG_SWP` | 右コントロールと GUI の入れ替え | -| `MAGIC_UNSWAP_RCTL_RGUI` | `RCG_NRM` | 右コントロールと GUI の入れ替えを解除 | -| `MAGIC_SWAP_CTL_GUI` | `CG_SWAP` | 両側のコントロールと GUI の入れ替え | -| `MAGIC_UNSWAP_CTL_GUI` | `CG_NORM` | 両側のコントロールと GUI の入れ替えを解除 | -| `MAGIC_TOGGLE_CTL_GUI` | `CG_TOGG` | 両側のコントロールと GUI の入れ替えの切り替え | -| `MAGIC_SWAP_LALT_LGUI` | `LAG_SWP` | 左 Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_LALT_LGUI` | `LAG_NRM` | 左 Alt と GUI の入れ替えを解除 | -| `MAGIC_SWAP_RALT_RGUI` | `RAG_SWP` | 右 Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_RALT_RGUI` | `RAG_NRM` | 右 Alt と GUI の入れ替えを解除 | -| `MAGIC_SWAP_ALT_GUI` | `AG_SWAP` | 両側の Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_ALT_GUI` | `AG_NORM` | 両側の Alt と GUI の入れ替えを解除 | -| `MAGIC_TOGGLE_ALT_GUI` | `AG_TOGG` | 両側の Alt と GUI の入れ替えの切り替え | -| `MAGIC_NO_GUI` | `GUI_OFF` | GUI キーを無効にする | -| `MAGIC_UNNO_GUI` | `GUI_ON` | GUI キーを有効にする | -| `MAGIC_SWAP_GRAVE_ESC` | `GE_SWAP` | ` とエスケープの入れ替え | -| `MAGIC_UNSWAP_GRAVE_ESC` | `GE_NORM` | ` とエスケープの入れ替えを解除 | -| `MAGIC_SWAP_BACKSLASH_BACKSPACE` | `BS_SWAP` | `\` とバックスペースを入れ替え | -| `MAGIC_UNSWAP_BACKSLASH_BACKSPACE` | `BS_NORM` | `\` とバックスペースの入れ替えを解除する | -| `MAGIC_HOST_NKRO` | `NK_ON` | N キーロールオーバーを有効にする | -| `MAGIC_UNHOST_NKRO` | `NK_OFF` | N キーロールオーバーを無効にする | -| `MAGIC_TOGGLE_NKRO` | `NK_TOGG` | N キーロールオーバーの有効・無効を切り替え | -| `MAGIC_EE_HANDS_LEFT` | `EH_LEFT` | 分割キーボードのマスター側を左手に設定(`EE_HANDS` 用) | -| `MAGIC_EE_HANDS_RIGHT` | `EH_RGHT` | 分割キーボードのマスター側を右手に設定(`EE_HANDS` 用) | - -## 設定 - -ブートマジックのためのホットキーの割り当てを変更したい場合は、キーボードあるいはキーマップレベルのどちらかで、`config.h` にこれらを `#define` します。 - -| 定義 | デフォルト | 説明 | -|----------------------------------------|-------------|---------------------------------------------------| -| `BOOTMAGIC_KEY_SALT` | `KC_SPACE` | ブートマジックキー | -| `BOOTMAGIC_KEY_SKIP` | `KC_ESC` | EEPROM のブートマジック設定を無視する | -| `BOOTMAGIC_KEY_EEPROM_CLEAR` | `KC_BSPACE` | EEPROM 設定をクリアする | -| `BOOTMAGIC_KEY_BOOTLOADER` | `KC_B` | ブートローダに入る | -| `BOOTMAGIC_KEY_DEBUG_ENABLE` | `KC_D` | シリアルを介するデバッグ出力の切り替え | -| `BOOTMAGIC_KEY_DEBUG_MATRIX` | `KC_X` | マトリックスのデバッグを切り替え | -| `BOOTMAGIC_KEY_DEBUG_KEYBOARD` | `KC_K` | キーボードのデバッグの切り替え | -| `BOOTMAGIC_KEY_DEBUG_MOUSE` | `KC_M` | マウスのデバッグの切り替え | -| `BOOTMAGIC_KEY_EE_HANDS_LEFT` | `KC_L` | EE_HANDS 左右設定に、"左手"を設定 | -| `BOOTMAGIC_KEY_EE_HANDS_RIGHT` | `KC_R` | EE_HANDS 左右設定に、"右手"を設定 | -| `BOOTMAGIC_KEY_SWAP_CONTROL_CAPSLOCK` | `KC_LCTRL` | 左コントロールと Caps Lock の入れ替え | -| `BOOTMAGIC_KEY_CAPSLOCK_TO_CONTROL` | `KC_CAPSLOCK` | Caps Lock を左コントロールとして扱うかを切り替え | -| `BOOTMAGIC_KEY_SWAP_LALT_LGUI` | `KC_LALT` | 左 Alt と左 GUI の入れ替えを切り替え (macOS 用) | -| `BOOTMAGIC_KEY_SWAP_RALT_RGUI` | `KC_RALT` | 右 Alt と右 GUI の入れ替えを切り替え (macOS 用) | -| `BOOTMAGIC_KEY_NO_GUI` | `KC_LGUI` | GUI キーの有効・無効を切り替え (ゲームの時に便利です) | -| `BOOTMAGIC_KEY_SWAP_GRAVE_ESC` | `KC_GRAVE` | ` とエスケープの入れ替えを切り替え | -| `BOOTMAGIC_KEY_SWAP_BACKSLASH_BACKSPACE` | `KC_BSLASH` | `\` とバックスペースの入れ替えを切り替え | -| `BOOTMAGIC_HOST_NKRO` | `KC_N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_0` | `KC_0` | レイヤー 0 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_1` | `KC_1` | レイヤー 1 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_2` | `KC_2` | レイヤー 2 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_3` | `KC_3` | レイヤー 3 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_4` | `KC_4` | レイヤー 4 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_5` | `KC_5` | レイヤー 5 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_6` | `KC_6` | レイヤー 6 をデフォルトレイヤーにする | -| `BOOTMAGIC_KEY_DEFAULT_LAYER_7` | `KC_7` | レイヤー 7 をデフォルトレイヤーにする | - -# ブートマジックライト :id=bootmagic-lite - -本格的なブートマジック機能の他に、ブートローダへのジャンプのみを処理するブートマジックライトがあります。これは、物理的なリセットボタンが無くブートローダにジャンプする方法が必要だが、ブートマジックが引き起こす問題を扱いたくないキーボードに適しています。 - -ブートマジックのこのバージョンを有効にするには、以下を使って `rules.mk` で有効にする必要があります: - -```make -BOOTMAGIC_ENABLE = lite -``` - -さらに、どのキーを使うかを指定したほうが良いかもしれません。これは普通ではないマトリックスを持つキーボードで特に便利です。そのためには、使いたいキーの行と列を指定する必要があります。`config.h` ファイルにこれらのエントリを追加します: - -```c -#define BOOTMAGIC_LITE_ROW 0 -#define BOOTMAGIC_LITE_COLUMN 1 -``` - -デフォルトでは、これらは 0 と 0 に設定されます。これは通常はほとんどのキーボードで "ESC" キーです。 - -ブートローダを起動するには、キーボードを接続する時にこのキーを押し続けます。たった1つのキーです。 - -!> ブートマジックライトを使用すると、EEPROM を**常にリセットします**。つまり保存された全ての設定は失われます。 - -## 分割キーボード - -`SPLIT_HAND_PIN` のようなオプションで、左右の設定があらかじめ決められている場合は、キーボードの左右で別のキーを設定する必要があるかもしれません。これを行うには、`config.h` ファイルに以下のエントリを追加します。 - -```c -#define BOOTMAGIC_LITE_ROW_RIGHT 4 -#define BOOTMAGIC_LITE_COLUMN_RIGHT 1 -``` - -デフォルトでは、これらの値は設定されていません。 - -## 高度なブートマジックライト - -`bootmagic_lite` 関数は必要に応じてコード内で置き換えることができるように、弱く定義されています。これの良い例は Zeal60 キーボードで、追加の処理が必要です。 - -関数を置き換えるには、以下のようなものをコードに追加するだけです: - -```c -void bootmagic_lite(void) { - matrix_scan(); - wait_ms(DEBOUNCE * 2); - matrix_scan(); - - if (matrix_get_row(BOOTMAGIC_LITE_ROW) & (1 << BOOTMAGIC_LITE_COLUMN)) { - // ブートローダにジャンプする。 - bootloader_jump(); - } -} -``` - -追加の機能をここに追加することができます。例えば、eeprom のリセットやブートマジックを起動するために押す必要がある追加のキーです。`bootmagic_lite` はファームウェア内で大部分の機能が初期化される前に呼ばれることに注意してください。 diff --git a/docs/ja/feature_combo.md b/docs/ja/feature_combo.md deleted file mode 100644 index 0c0591e5f76c..000000000000 --- a/docs/ja/feature_combo.md +++ /dev/null @@ -1,108 +0,0 @@ -# コンボ - - - -コンボ機能は、同時押し方式でのカスタムアクション追加機能です。同時に複数のキーを押して、異なる効果を生み出すことができます。例えば、タッピング時間内で `A` と `S` を押すと、代わりに `ESC` が押されます。もっと複雑なタスクを実行させることもできます。 - -この機能を有効にするには、`rules.mk` に `COMBO_ENABLE = yes` を追加する必要があります。 - -さらに、使用するコンボの数を `config.h` の中で、`#define COMBO_COUNT 1` (1を使用するコンボの数で置き換えます)と書いて、指定する必要があります。 - - -また、デフォルトでは、コンボのタッピング時間は `TAPPING_TERM` と同じ値に設定されます (ほとんどのキーボードではデフォルトで 200)。ただし、`config.h` で定義することにより異なる値を指定することができます。例えば: `#define COMBO_TERM 300` はコンボのためのタイムアウト時間を 300ms に設定します。 - -次に、`keymap.c` ファイルに、`COMBO_END` で終了するキーのシーケンス、およびキーの組み合わせを列挙する構造体、その結果のアクションを定義する必要があります。 - -```c -const uint16_t PROGMEM test_combo[] = {KC_A, KC_B, COMBO_END}; -combo_t key_combos[] = {COMBO(test_combo, KC_ESC)}; -``` - -これは、A と B のキーを押した場合に、"Escape" を送信します。 - -!> このメソッドは[基本的なキーコード](ja/keycodes_basic.md)のみをサポートします。詳細な制御については例を見てください。 - -## 例 - -リストを追加したい場合は、以下のようなものを使います: - -```c -enum combos { - AB_ESC, - JK_TAB -}; - -const uint16_t PROGMEM ab_combo[] = {KC_A, KC_B, COMBO_END}; -const uint16_t PROGMEM jk_combo[] = {KC_J, KC_K, COMBO_END}; - -combo_t key_combos[] = { - [AB_ESC] = COMBO(ab_combo, KC_ESC), - [JK_TAB] = COMBO(jk_combo, KC_TAB) -}; -``` - -より複雑な実装として、カスタム処理を追加するために `process_combo_event` 関数を使うことができます。 - -```c -enum combo_events { - ZC_COPY, - XV_PASTE -}; - -const uint16_t PROGMEM copy_combo[] = {KC_Z, KC_C, COMBO_END}; -const uint16_t PROGMEM paste_combo[] = {KC_X, KC_V, COMBO_END}; - -combo_t key_combos[] = { - [ZC_COPY] = COMBO_ACTION(copy_combo), - [XV_PASTE] = COMBO_ACTION(paste_combo), -}; - -void process_combo_event(uint16_t combo_index, bool pressed) { - switch(combo_index) { - case ZC_COPY: - if (pressed) { - tap_code16(LCTL(KC_C)); - } - break; - case XV_PASTE: - if (pressed) { - tap_code16(LCTL(KC_V)); - } - break; - } -} -``` - -これは、Z と C を押すと Ctrl+C を送信し、X と V を押すと Ctrl+V を送信します。これを変更して、レイヤーの変更、サウンドの再生、設定の変更などを行うこともできます。 - -## 追加の設定 - -長いコンボあるいはさらに長いコンボを使っている場合、構造体があなたのしていることに対応するのに十分な大きさで無いかもしれないため、問題が発生するかもしれません。 - -この場合、`config.h` ファイルに `#define EXTRA_LONG_COMBOS` または `#define EXTRA_EXTRA_LONG_COMBOS` のどちらかを追加することができます。 - -`COMBO_ALLOW_ACTION_KEYS` を定義することでアクションキーを有効にすることもできます。 - -## キーコード - -その場でコンボ機能を有効、無効および切り替えすることができます。ゲームなどで、一時的にそれらを無効にする必要がある場合に便利です。 - -| キーコード | 説明 | -|----------|---------------------------------| -| `CMB_ON` | コンボ機能をオンにします | -| `CMB_OFF` | コンボ機能をオフにします | -| `CMB_TOG` | コンボ機能のオンとオフを切り替えます | - -## ユーザコールバック - -キーコードに加えて、状態を設定または状態をチェックするために使うことができる幾つかの関数があります: - -| 関数 | 説明 | -|-----------|--------------------------------------------------------------------| -| `combo_enable()` | コンボ機能を有効にします | -| `combo_disable()` | コンボ機能を無効にし、コンボバッファをクリアします | -| `combo_toggle()` | コンボ機能の状態を切り替えます | -| `is_combo_enabled()` | コンボ機能の状態(true か false)を返します | diff --git a/docs/ja/feature_command.md b/docs/ja/feature_command.md deleted file mode 100644 index f8b7e8929414..000000000000 --- a/docs/ja/feature_command.md +++ /dev/null @@ -1,56 +0,0 @@ -# コマンド - - - -コマンド(旧称:マジック)は、ファームウェアを書き込んだり、[ブートマジック](ja/feature_bootmagic.md)を使うためにプラグを抜いたりすることなくキーボードの挙動を変更する方法です。この機能と[ブートマジックキーコード](feature_bootmagic.md#keycodes)には多くの重複があります。可能な限り、コマンドでは無くブートマジックキーコードの機能を使うことをお勧めします。 - -一部のキーボードではコマンドがデフォルトで無効になっています。その場合、`rules.mk` 内で明示的に有効にする必要があります: - -```make -COMMAND_ENABLE = yes -``` - -## 使用法 - -コマンドを使うには、`IS_COMMAND()` マクロで定義されたキーの組み合わせを押し続けます。デフォルトでは、これは「左Shift + 右Shift」です。次に、目的のコマンドに対応するキーを押します。例えば、現在の QMK バージョンを QMK Toolbox コンソールに出力するには、「左Shift + 右Shift + `V`」を押します。 - -## 設定 - -コマンドのためのキーの割り当てを変更したい場合は、キーボードあるいはキーマップレベルのどちらかで、`config.h` にこれらを `#define` します。ここで割り当てる全てのキーコードは `KC_` 接頭辞を省略する必要があります。 - -| 定義 | デフォルト | 説明 | -|------------------------------------|--------------------------------|------------------------------------------------| -| `IS_COMMAND()` | `(get_mods() == MOD_MASK_SHIFT)` | コマンドをアクティブにするキーの組み合わせ | -| `MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS` | `true` | ファンクション行を使ってデフォルトレイヤーを設定 | -| `MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS` | `true` | 数字キーでデフォルトレイヤーを設定 | -| `MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM` | `false` | `MAGIC_KEY_LAYER0..9` を使ってデフォルトレイヤーを設定 | -| `MAGIC_KEY_DEBUG` | `D` | シリアルを介するデバッグの切り替え | -| `MAGIC_KEY_DEBUG_MATRIX` | `X` | キーマトリックスのデバッグの切り替え | -| `MAGIC_KEY_DEBUG_KBD` | `K` | キーボードのデバッグの切り替え | -| `MAGIC_KEY_DEBUG_MOUSE` | `M` | マウスのデバッグの切り替え | -| `MAGIC_KEY_CONSOLE` | `C` | コマンドコンソールを有効にする | -| `MAGIC_KEY_VERSION` | `V` | コンソールに実行中の QMK バージョンを出力 | -| `MAGIC_KEY_STATUS` | `S` | コンソールに現在のキーボードの状態を出力 | -| `MAGIC_KEY_HELP` | `H` | コンソールにコマンドのヘルプを出力 | -| `MAGIC_KEY_HELP_ALT` | `SLASH` | コンソールにコマンドのヘルプを出力 (代替) | -| `MAGIC_KEY_LAYER0` | `0` | レイヤー 0 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER0_ALT` | `GRAVE` | レイヤー 0 をデフォルトレイヤーにする (代替) | -| `MAGIC_KEY_LAYER1` | `1` | レイヤー 1 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER2` | `2` | レイヤー 2 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER3` | `3` | レイヤー 3 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER4` | `4` | レイヤー 4 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER5` | `5` | レイヤー 5 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER6` | `6` | レイヤー 6 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER7` | `7` | レイヤー 7 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER8` | `8` | レイヤー 8 をデフォルトレイヤーにする | -| `MAGIC_KEY_LAYER9` | `9` | レイヤー 9 をデフォルトレイヤーにする | -| `MAGIC_KEY_BOOTLOADER` | `B` | ブートローダにジャンプする | -| `MAGIC_KEY_BOOTLOADER_ALT` | `ESC` | ブートローダにジャンプする (代替) | -| `MAGIC_KEY_LOCK` | `CAPS` | 何も入力できないようにキーボードをロック | -| `MAGIC_KEY_EEPROM` | `E` | 保存された EEPROM 設定をコンソールに出力 | -| `MAGIC_KEY_EEPROM_CLEAR` | `BSPACE` | EEPROM をクリア | -| `MAGIC_KEY_NKRO` | `N` | N キーロールオーバー (NKRO) の有効・無効を切り替え | -| `MAGIC_KEY_SLEEP_LED` | `Z` | コンピュータがスリープの時に LED を切り替え | diff --git a/docs/ja/feature_debounce_type.md b/docs/ja/feature_debounce_type.md deleted file mode 100644 index 258ca194da4f..000000000000 --- a/docs/ja/feature_debounce_type.md +++ /dev/null @@ -1,128 +0,0 @@ -# 接点バウンス / 接点チャタリング - - - -メカニカルスイッチは押した状態と放した状態の間の移行が単純ではないことが良くあります。 - -理想的な世界では、スイッチを押すと、デジタルピンが次のようになることが期待されます: -(X 軸は時間を表します -``` -voltage +---------------------- - ^ | - | | - | ------------------+ - ----> time -``` - -しかし実際の世界では、値が最終的に落ち着くまでに 0 と 1 の間を行ったり来たりする接点バウンスを見ることになるでしょう。(訳注:日本語では、バウンスとチャタリングを区別せずにチャタリングと呼んでいることが多いようです。) -``` - +-+ +--+ +------------- - | | | | | - | | | | | -+-----------------+ +-+ +-+ -``` -スイッチが落ち着くまでにかかる時間は、スイッチの種類や経年、押す技術によって異なる場合があります。 - -デバイスが接点バウンスを緩和しないことを選択した場合、スイッチが押された時に起きるアクションが複数回繰り返されることがよくあります。 - -接点バウンス(「デバウンス」)を処理する方法はたくさんあります。RC フィルタのような追加のハードウェアを採用する方法もありますが、ソフトウェアでデバウンスを行う様々な方法もあり、よくデバウンスアルゴリズムと呼ばれます。このページでは、QMK で利用できるデバウンスメソッドについて説明します。 - -技術的には接点バウンス/接点チャタリングとは見なされませんが、一部のスイッチテクノロジーはノイズの影響を受けやすく、キーの状態が変化していない時に、時々短くランダムに 0 と 1 の間を行き来する様子がデジタル回路によって読み取られる場合があります。例えば: -``` - +-+ - | | - | | -+-----------------+ +-------------------- -``` - -多くのデバウンスメソッド(全てではないですが)は、デバイスにノイズ耐性を持たせます。 -ノイズの影響を受けやすい技術を使っている場合は、ノイズを緩和するデバウンスメソッドを選択しなければなりません。 - -## デバウンスアルゴリズムの種類 - -1) 時間の単位: タイムスタンプ (ミリ秒) vs 周期 (スキャン) - * デバウンスアルゴリズムは1つの「デバウンス時間」パラメータを持つことがよくあり、スイッチ接点の最大セトリング時間を指定します。 - この時間は様々な単位で測定される場合があります: - * 周期ベースデバウンスは n 周期(スキャン)待機し、matrix_scan ごとにカウントを1減らします。 - * タイムスタンプベースのデバウンスは、変更が発生したミリ秒のタイムスタンプを格納し、経過時間を計算するために減算を行います。 - * 通常、タイムスタンプベースのデバウンスは、特にノイズ耐性のあるデバイスで優れています。なぜなら、物理スイッチのセトリング時間は時間の単位で指定されており、キーボードのマトリックススキャンレートに依存しないからです。 - * 周期ベースのデバウンスは、補正できるセトリング時間がマトリックススキャンコードのパフォーマンスに依存するため、劣ると見なされる場合があります。 - 周期ベースのデバウンスを使う場合、スキャンコードのパフォーマンスを大幅に向上させると、デバウンスの効果が低下する場合があります。 - 周期ベースのデバウンスが望ましい状況は、ノイズが存在し、スキャンアルゴリズムが遅い、もしくは速度が可変である場合です。 - デバウンスアルゴリズムが基本的にノイズ耐性がある場合でも、スキャンが遅く、タイムスタンプベースのアルゴリズムを使っている場合は、 - 2つのサンプル値に基づいてデバウンスを決定するため、アルゴリズムのノイズ耐性は制限されます。 - * 現在、全ての組み込みデバウンスアルゴリズムは、タイムスタンプベースのデバウンスのみサポートしています。将来的には周期ベースのデバウンスを実装し、```config.h``` マクロを介して選択できるようになるでしょう。 - -2) 対称 vs 非対称 - * 対称 - キーアップとキーダウンイベントの両方に、同じデバウンスアルゴリズムを適用します。 - * 推奨される命名規則: ```sym_*``` - * 非対称 - キーダウンとキーアップイベントに異なるデバウンスアルゴリズムを適用します。例えば、キーダウンはイーガー、キーアップはデファー。 - * 推奨される命名規則: ```asym_*``` の後に、キーダウン、キーアップの順に使っているアルゴリズムタイプの詳細が続きます。 - -3) イーガー vs デファー - * イーガー - キーの変更はすぐに報告されます。DEBOUNCE ミリ秒以降の全ての入力は無視されます。 - * イーガーアルゴリズムはノイズ耐性はありません - * 推奨される命名規則: - * ```sym_eager_*``` - * ```asym_eager_*_*```: キーダウンはイーガーアルゴリズムを使います - * ```asym_*_eager_*```: キーアップはイーガーアルゴリズムを使います - * デファー - 変更を報告する前に DEBOUNCE ミリ秒の間変更がないことを待機します - * デファーアルゴリズムはノイズ耐性があります - * 推奨される命名規則: - * ```sym_defer_*``` - * ```asym_defer_*_*```: キーダウンはデファーアルゴリズムを使います - * ```asym_*_defer_*```: キーアップはデファーアルゴリズムを使います - -4) グローバル vs キーごと vs 行ごと - * グローバル - 全てのキーに対して1つのタイマー。キーの変更状態は、グローバルタイマーに影響を与えます。 - * 推奨される命名規則: ```*_g``` - * キーごと - キーごとに1つのタイマー。 - * 推奨される命名規則: ```*_pk``` - * 行ごと - 行ごとに1つのタイマー。 - * 推奨される命名規則: ```*_pr``` - * キーごとや行ごとのアルゴリズムはより多くのリソース(パフォーマンスと RAM 使用量の観点で)を消費しますが、高速なタイピストはグローバルよりもそれらを好む場合があります。 - -## QMK でサポートされるデバウンスアルゴリズム - -QMK はデバウンス API を介して複数のデバウンスアルゴリズムをサポートします。 - -### デバウンスの選択 - -| DEBOUNCE_TYPE | 説明 | 他に必要なもの | -| ------------- | ------------------------------------------------------------- | ---------------------------------------------------------------------------- | -| 未定義 | デフォルトのアルゴリズム、現在のところ sym_defer_g を使います | 無し | -| custom | 独自のデバウンスコードを使います | ```SRC += debounce.c``` で独自の debounce.c を追加し、必要な関数を実装します | -| その他 | quantum/debounce/* から他のアルゴリズムを使います | 無し | - -**分割キーボードについて**: -デバウンスコードは分割キーボードと互換性があります。 - -### インクルードされているデバウンスメソッドの選択 -キーボードは、```rules.mk``` に次の行を追加することで、既に実装されているデバウンスメソッドの1つを選択できます: -``` -DEBOUNCE_TYPE = <アルゴリズムの名前> -``` -アルゴリズムの名前は次のいずれかです: -* ```sym_defer_g``` - キーボードごとにデバウンスします。状態が変化すると、グローバルタイマが設定されます。```DEBOUNCE``` ミリ秒の間何も変化がなければ、全ての入力の変更がプッシュされます。 - * これは現在のデフォルトアルゴリズムです。これはメモリ使用量が最も少ない最高のパフォーマンスのアルゴリズムで、ノイズ耐性もあります。 -* ```sym_eager_pr``` - 行ごとにデバウンスします。状態が変化すると、応答は即座に行われ、その後その行は ```DEBOUNCE``` ミリ秒の間入力されません。 -```NUM_KEYS``` の 8ビットカウンタの更新に高い計算コストがかかる、もしくは低スキャンレートのキーボード用で、各指は通常一度に1行しか叩かないようになっています。これは ErgoDox モデルに適しています; マトリックスは90度回転しているため、その「行」は実際には「列」であり、通常の使用では各指は一度に1つの「行」にしか当たりません。 -* ```sym_eager_pk``` - キーごとにデバウンスします。状態が変化すると、応答は即座に行われ、その後そのキーは ```DEBOUNCE``` ミリ秒の間入力されません。 -* ```sym_defer_pk``` - キーごとにデバウンスします。状態が変化すると、キーごとのタイマーが設定されます。```DEBOUNCE``` ミリ秒の間そのキーに変化がなければ、キーの状態の変更がプッシュされます。 - -### 将来実装される可能性のあるいくつかのアルゴリズム: -* ```sym_defer_pr``` -* ```sym_eager_g``` -* ```asym_eager_defer_pk``` - -### 独自のデバウンスコードの使用 -独自のデバウンスアルゴリズムを実装するためのオプションがあります。次のようにします: -* ```rules.mk``` に ```DEBOUNCE_TYPE = custom``` を設定します。 -* ```rules.mk``` に ```SRC += debounce.c``` を追加します。 -* 独自の ```debounce.c``` を追加します。例については、```quantum/debounce``` にある現在の実装を見てください。 -* デバウンスは、全てのマトリクススキャンの後で発生します。 -* MATRIX_ROWS ではなく num_rows を使って、分割キーボードが正しくサポートされるようにします。 -* アルゴリズムが他のキーボードにも適用できる可能性がある場合、```quantum/debounce``` に追加することを検討してください。 diff --git a/docs/ja/feature_dip_switch.md b/docs/ja/feature_dip_switch.md deleted file mode 100644 index 8d0eeafa5a80..000000000000 --- a/docs/ja/feature_dip_switch.md +++ /dev/null @@ -1,115 +0,0 @@ -# DIP スイッチ - - - -DIP スイッチは、以下を `rules.mk` に追加することでサポートされます: - - DIP_SWITCH_ENABLE = yes - -さらに、以下を `config.h` に追加します: - -```c -// Connects each switch in the dip switch to the GPIO pin of the MCU -#define DIP_SWITCH_PINS { B14, A15, A10, B9 } -// For split keyboards, you can separately define the right side pins -#define DIP_SWITCH_PINS_RIGHT { ... } -``` - -あるいは - -```c -// Connect each switch in the DIP switch to an unused intersections in the key matrix. -#define DIP_SWITCH_MATRIX_GRID { {0,6}, {1,6}, {2,6} } // List of row and col pairs -``` - -## コールバック - -コールバック関数を `.c` に記述することができます: - -```c -bool dip_switch_update_kb(uint8_t index, bool active) { - if !(dip_switch_update_user(index, active)) { return false; } - return true; -} -``` - - -あるいは `keymap.c` に記述することもできます: - -```c -bool dip_switch_update_user(uint8_t index, bool active) { - switch (index) { - case 0: - if(active) { audio_on(); } else { audio_off(); } - break; - case 1: - if(active) { clicky_on(); } else { clicky_off(); } - break; - case 2: - if(active) { music_on(); } else { music_off(); } - break; - case 3: - if (active) { - #ifdef AUDIO_ENABLE - PLAY_SONG(plover_song); - #endif - layer_on(_PLOVER); - } else { - #ifdef AUDIO_ENABLE - PLAY_SONG(plover_gb_song); - #endif - layer_off(_PLOVER); - } - break; - } - return true; -} -``` - -更に、より複雑な処理ができるビットマスク関数をサポートします。 - - -```c -bool dip_switch_update_mask_kb(uint32_t state) { - if (!dip_switch_update_mask_user(state)) { return false; } - return true; -} -``` - - -あるいは `keymap.c` に記述することもできます: - -```c -bool dip_switch_update_mask_user(uint32_t state) { - if (state & (1UL<<0) && state & (1UL<<1)) { - layer_on(_ADJUST); // C on esc - } else { - layer_off(_ADJUST); - } - if (state & (1UL<<0)) { - layer_on(_TEST_A); // A on ESC - } else { - layer_off(_TEST_A); - } - if (state & (1UL<<1)) { - layer_on(_TEST_B); // B on esc - } else { - layer_off(_TEST_B); - } - return true; -} -``` - - -## ハードウェア - -### DIP スイッチの各スイッチを MCU の GPIO ピンに接続する - -DIP スイッチの片側は MCU のピンへ直接配線し、もう一方の側はグラウンドに配線する必要があります。機能的に同じであるため、どちら側がどちらに接続されているかは問題にはならないはずです。 - -### DIP スイッチの各スイッチをキーマトリクスの未使用の交点に接続する - -キースイッチと同じように、ダイオードと DIP スイッチが ROW 線と COL 線に接続します。 diff --git a/docs/ja/feature_dynamic_macros.md b/docs/ja/feature_dynamic_macros.md deleted file mode 100644 index fa1a1df931e9..000000000000 --- a/docs/ja/feature_dynamic_macros.md +++ /dev/null @@ -1,72 +0,0 @@ -# 動的マクロ: ランタイムでのマクロの記録および再生 - - - -QMK はその場で作られた一時的なマクロをサポートします。これらを動的マクロと呼びます。それらはユーザがキーボードから定義し、キーボードのプラグを抜くか再起動すると失われます。 - -1つまたは2つのマクロに合計128のキー押下を保存できます。RAM をより多く使用してサイズを増やすことができます。 - -有効にするには、最初に `rules.mk` に `DYNAMIC_MACRO_ENABLE = yes` を記述します。そして、以下のキーをキーマップに追加します: - -| キー | Alias | 説明 | -|------------------|----------|---------------------------------------------------| -| `DYN_REC_START1` | `DM_REC1` | マクロ 1 の記録を開始します | -| `DYN_REC_START2` | `DM_REC2` | マクロ 2 の記録を開始します | -| `DYN_MACRO_PLAY1` | `DM_PLY1` | マクロ 1 を再生します | -| `DYN_MACRO_PLAY2` | `DM_PLY2` | マクロ 2 を再生します | -| `DYN_REC_STOP` | `DM_RSTP` | 現在記録中のマクロの記録を終了します。 | - -これが必要な全てです。 - -マクロの記録を開始するには、`DYN_REC_START1` または `DYN_REC_START2` のどちらかを押します。 - -記録を終了するには、`DYN_REC_STOP` レイヤーボタンを押します。`DYN_REC_START1` または `DYN_REC_START2` をもう一度押すことでも記録を終了することができます。 - -マクロを再生するには、`DYN_MACRO_PLAY1` あるいは `DYN_MACRO_PLAY2` のどちらかを押します。 - -マクロの一部としてマクロを再生することができます。マクロ 1 を記録中にマクロ 2 を再生、またはその逆も問題ありません。ただし、再帰的なマクロ、つまりマクロ 1 を再生するマクロ 1 は作成しないでください。もしそうしてキーボードが反応しなくなった場合は、キーボードを取り外し再び接続します。これを完全に無効にするには、`config.h` ファイルで `DYNAMIC_MACRO_NO_NESTING` を定義します。 - -?> 動的マクロの内部の詳細については、`process_dynamic_macro.h` および `process_dynamic_macro.c` ファイルのコメントを読んでください。 - -## カスタマイズ - -ある程度のカスタマイズを可能にするオプションがいくつか追加されています。 - -| 定義 | デフォルト | 説明 | -|----------------------------|----------------|-----------------------------------------------------------------------------------------------------------------| -| `DYNAMIC_MACRO_SIZE` | 128 | 動的マクロが使用できるメモリ量を設定します。これは限られたリソースであり、コントローラに依存します。 | -| `DYNAMIC_MACRO_USER_CALL` | *定義なし* | これを定義すると、ユーザの `keymap.c` ファイルを使ってマクロが起動されます。 | -| `DYNAMIC_MACRO_NO_NESTING` | *定義なし* | これを定義すると、別のマクロからマクロを呼び出す(入れ子になったマクロ)機能を無効にします。 | -| `DYNAMIC_MACRO_DELAY` | *定義なし* | 各キーを送信する時の待ち時間(ms単位)を設定します。 | - - -記録中にキーを押すたびに LED が点滅し始めた場合は、マクロバッファにマクロを入れるスペースがもう無いことを意味します。マクロを入れるには、他のマクロ(それらは同じバッファを共有します)を短くするか、`config.h` に `DYNAMIC_MACRO_SIZE` 定義を追加することでバッファを増やします(デフォルト値: 128; ヘッダ内のコメントを読んでください)。 - - -### DYNAMIC_MACRO_USER_CALL - -以前のバージョンの動的マクロをお使いの方へ: 専用の `DYN_REC_STOP` キーを使わずに動的マクロキーへのアクセスに使われるレイヤーモディファイアのみを使って、マクロの記録を終了することもまだ可能です。この動作に戻したい場合は、`#define DYNAMIC_MACRO_USER_CALL` を `config.h` に追加し、以下のスニペットを `process_record_user()` 関数の先頭に記述します: - -```c - uint16_t macro_kc = (keycode == MO(_DYN) ? DYN_REC_STOP : keycode); - - if (!process_record_dynamic_macro(macro_kc, record)) { - return false; - } -``` - -### ユーザフック - -カスタム機能とフィードバックオプションを動的マクロ機能に追加するために使うことができるフックが幾つかあります。これによりある程度のカスタマイズが可能になります。 - -direction がどのマクロであるかを示すことに注意してください。`1` がマクロ 1、`-1` がマクロ 2、0 がマクロ無しです。 - -* `dynamic_macro_record_start_user(int8_t direction)` - マクロの記録を開始する時に起動されます。 -* `dynamic_macro_play_user(int8_t direction)` - マクロを再生する時に起動されます。 -* `dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record)` - マクロの記録中に各キー押下で起動されます。 -* `dynamic_macro_record_end_user(int8_t direction)` - マクロの記録を停止した時に起動されます。 - -さらに、動的マクロ機能が有効な場合にバックライトを点滅させるために `dynamic_macro_led_blink()` を呼び出すことができます。 diff --git a/docs/ja/feature_encoders.md b/docs/ja/feature_encoders.md deleted file mode 100644 index b93d9a9a281e..000000000000 --- a/docs/ja/feature_encoders.md +++ /dev/null @@ -1,85 +0,0 @@ -# エンコーダ - - - -以下を `rules.mk` に追加することで基本的なエンコーダがサポートされます: - -```make -ENCODER_ENABLE = yes -``` - -さらに、以下を `config.h` に追加します: - -```c -#define ENCODERS_PAD_A { B12 } -#define ENCODERS_PAD_B { B13 } -``` - -各 PAD_A/B 変数は配列を定義するため、複数のエンコーダを定義することができます。例えば: - -```c -#define ENCODERS_PAD_A { encoder1a, encoder2a } -#define ENCODERS_PAD_B { encoder1b, encoder2b } -``` - -エンコーダの時計回りの方向が間違っている場合は、A と B のパッド定義を交換することができます。define を使って逆にすることもできます: - -```c -#define ENCODER_DIRECTION_FLIP -``` - -さらに、エンコーダが各戻り止め(デテント)間に登録するパルス数を定義する解像度は、次のように定義できます: - -```c -#define ENCODER_RESOLUTION 4 -``` - -## 分割キーボード - -分割キーボードのそれぞれの側のエンコーダに異なるピン配列を使っている場合、右側のピン配列を以下のように定義することができます: - -```c -#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } -#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } -``` - -## コールバック - -コールバック関数を `.c` に記述することができます: - -```c -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!encoder_update_user(index, clockwise)) { - return false; - } - -} -``` - -あるいは `keymap.c` に記述することもできます: - -```c -bool encoder_update_user(uint8_t index, bool clockwise) { - if (index == 0) { /* First encoder */ - if (clockwise) { - tap_code(KC_PGDN); - } else { - tap_code(KC_PGUP); - } - } else if (index == 1) { /* Second encoder */ - if (clockwise) { - tap_code(KC_DOWN); - } else { - tap_code(KC_UP); - } - } - return false; -} -``` - -## ハードウェア - -エンコーダの A と B の線は MCU に直接配線し、C/common 線はグランドに配線する必要があります。 diff --git a/docs/ja/feature_grave_esc.md b/docs/ja/feature_grave_esc.md deleted file mode 100644 index 746e9e5d14e3..000000000000 --- a/docs/ja/feature_grave_esc.md +++ /dev/null @@ -1,37 +0,0 @@ -# グレイブエスケープ - - - -60% キーボード、またはファンクションキー行の無い他のレイアウトを使っている場合、専用の Escape キーが無いことに気付くでしょう。グレイブエスケープは grave キー (` および `~`) を Escape と共有することができる機能です。 - -## 使用法 - -キーマップ内の `KC_GRAVE` キー (通常は`1` キーの左)を `QK_GESC` に置き換えます。ほとんどの場合、このキーは押された時に `KC_ESC` を出力します。ただし、Shift あるいは GUI を押したままにすると、代わりに `KC_GRV` を出力します。 - -## OS に見えるもの - -メアリーがキーボードで GESC を押すと、OS には KC_ESC 文字が見えます。メアリーが Shift を押しながら GESC を押すと、`~` または Shift された時はバッククォートを出力します。彼女が GUI/CMD/WIN を押したままにすると、1つの ` 文字を出力します。 - -## キーコード - -| キー | エイリアス | 説明 | -|---------|-----------|------------------------------------------------------------------| -| `QK_GESC` | `GRAVE_ESC` | 押された場合に Escape。Shift あるいは GUI が押されたままの場合は ` | - -### 注意事項 - -macOS では、Command+` はデフォルトで "次のウィンドウを操作対象にする" にマップされます。つまりバッククォートを出力しません。さらに、ショートカットがキーボード環境設定で変更された場合でも、ターミナルは常にこのショートカットを認識してウィンドウを切り替えます。 - -## 設定 - -グレイブエスケープが壊す可能性のあるキーの組み合わせが幾つかあります。その中には、Windows では Control+Shift+Escape、macOSでは Command+Option+Escape があります。これを回避するには、`config.h` で以下のオプションを `#define` することができます: - -| 定義 | 説明 | -|--------------------------|-----------------------------------------| -| `GRAVE_ESC_ALT_OVERRIDE` | Alt が押された場合、常に Escape を送信する | -| `GRAVE_ESC_CTRL_OVERRIDE` | Control が押された場合、常に Escape を送信する | -| `GRAVE_ESC_GUI_OVERRIDE` | GUI が押された場合、常に Escape を送信する | -| `GRAVE_ESC_SHIFT_OVERRIDE` | Shift が押された場合、常に Escape を送信する | diff --git a/docs/ja/feature_haptic_feedback.md b/docs/ja/feature_haptic_feedback.md deleted file mode 100644 index 687788014aa5..000000000000 --- a/docs/ja/feature_haptic_feedback.md +++ /dev/null @@ -1,173 +0,0 @@ -# 触覚フィードバック - - - -## 触覚フィードバック の rules.mk オプション - -現在のところ、`rules.mk` で触覚フィードバック用に以下のオプションを利用可能です: - -``` -HAPTIC_ENABLE = yes - -HAPTIC_DRIVER += DRV2605L -HAPTIC_DRIVER += SOLENOID -``` - -## サポートされる既知のハードウェア - -| 名前 | 説明 | -|--------------------|-------------------------------------------------| -| [LV061228B-L65-A](https://www.digikey.com/product-detail/en/jinlong-machinery-electronics-inc/LV061228B-L65-A/1670-1050-ND/7732325) | z-axis 2v LRA | -| [Mini Motor Disc](https://www.adafruit.com/product/1201) | small 2-5v ERM | - -## 触覚キーコード - -以下のキーコードは、選択した触覚メカニズムに依存して動作するかどうか決まります。 - -| 名前 | 説明 | -|-----------|-------------------------------------------------------| -| `HPT_ON` | 触覚フィードバックをオン | -| `HPT_OFF` | 触覚フィードバックをオフ | -| `HPT_TOG` | 触覚フィードバックのオン/オフを切り替え | -| `HPT_RST` | 触覚フィードバック設定をデフォルトに戻す | -| `HPT_FBK` | キー押下またはリリースまたはその両方でフィードバックを切り替え | -| `HPT_BUZ` | ソレノイドのブザー音のオン/オフを切り替え | -| `HPT_MODI` | 次の DRV2605L 波形に移動 | -| `HPT_MODD` | 前の DRV2605L 波形に移動 | -| `HPT_CONT` | 連続触覚モードのオン/オフを切り替え | -| `HPT_CONI` | DRV2605L の連続触覚強度を増加 | -| `HPT_COND` | DRV2605L の連続触覚強度を減少 | -| `HPT_DWLI` | ソレノイドの滞留時間を増加 | -| `HPT_DWLD` | ソレノイドの滞留時間を減少 | - -### ソレノイド - -ほとんどの MCU はソレノイドのコイルを駆動するために必要な電流を供給できないため、最初に MOSFET を介してソレノイドを駆動する回路を構築する必要があります。 - -[Adafruit が提供する配線図](https://cdn-shop.adafruit.com/product-files/412/412_solenoid_driver.pdf) - - -| 設定 | デフォルト | 説明 | -|--------------------------|---------------|-------------------------------------------------------| -| `SOLENOID_PIN` | *定義なし* | ソレノイドが接続されているピンを設定する。 | -| `SOLENOID_DEFAULT_DWELL` | `12` ms | ソレノイドのデフォルトの滞留時間を設定する。 | -| `SOLENOID_MIN_DWELL` | `4` ms | 滞留時間の下限を設定する。 | -| `SOLENOID_MAX_DWELL` | `100` ms | 滞留時間の上限を設定する。 | -| `SOLENOID_DWELL_STEP_SIZE` | `1` ms | `HPT_DWL*` キーコードが送信される時に使われるステップサイズ | -| `SOLENOID_DEFAULT_BUZZ` | `0` (無効) | HPT_RST では、この値が "1" の場合、ブザー音が "on" に設定されます | -| `SOLENOID_BUZZ_ACTUATED` | `SOLENOID_MIN_DWELL` | ソレノイドがブザー音モードの場合の動作時間 | -| `SOLENOID_BUZZ_NONACTUATED` | `SOLENOID_MIN_DWELL` | ソレノイドがブザー音モードの場合の非動作時間 | - -* ソレノイドのブザー音がオフの場合、滞留時間は「プランジャー」が作動したままになる時間です。滞留時間により、ソレノイドの音が変わります。 -* ソレノイドのブザー音がオンの場合、滞留時間は振動の長さを設定しますが、`SOLENOID_BUZZ_ACTUATED` と `SOLENOID_BUZZ_NONACTUATED` はブザー音の間の(非)動作時間を設定します。 -* 現在の実装では、上記の時間設定のいずれについても、設定の精度はキーボードがマトリックスをスキャンできる速度によって影響を受ける可能性があります。 - したがって、キーボードのスキャンルーチンが遅い場合は、`SOLENOID_DWELL_STEP_SIZE` をキーボードのスキャンに掛かる時間よりもわずかに小さい値に設定することをお勧めします。 - -ブートローダ実行中に一部のピンが給電されているかもしれず (例えば、STM32F303 チップ上の A13)、そうすると書き込みプロセスの間ずっとソレノイドがオン状態になることに注意してください。これはソレノイドを加熱し損傷を与えるかもしれません。ソレノイドが接続されているピンがブートローダ/DFU 実行中にソレノイドをオンにしていることが分かった場合は、他のピンを選択してください。 - -### DRV2605L - -DRV2605Lは i2c プロトコルで制御され、SDA および SCL ピンに接続する必要があります。これらは使用する MCU によって異なります。 - -#### フィードバックモータのセットアップ - -このドライバは2つの異なるフィードバックモータをサポートします。選択したモータに基づいて、`config.h` で以下を設定します。 - -##### ERM - -偏心回転質量振動モータ (ERM) は偏りのある重りが取り付けられたモータで、駆動信号が取り付けられると偏りのある重りが回転し、正弦波が振動に変換されます。 - -``` -#define FB_ERM_LRA 0 -#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ -#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ - -/* 特定のモータに最適な設定については、データシートを参照してください。*/ -#define RATED_VOLTAGE 3 -#define V_PEAK 5 -``` -##### LRA - -線形共振アクチュエータ (LRA、線形バイブレータとしても知られています)は、ERM と異なります。LRA は重りと磁石をバネで吊るしたものとボイスコイルで構成されています。駆動信号が印加されるとされると、重りは単一の軸で振動します (左右または上下)。重りはバネに取り付けられているため、特定の周波数で共振効果があります。この周波数は LRA が最も効率的に動作する箇所です。この周波数の推奨範囲については、モータのデータシートを参照してください。 - -``` -#define FB_ERM_LRA 1 -#define FB_BRAKEFACTOR 3 /* For 1x:0, 2x:1, 3x:2, 4x:3, 6x:4, 8x:5, 16x:6, Disable Braking:7 */ -#define FB_LOOPGAIN 1 /* For Low:0, Medium:1, High:2, Very High:3 */ - -/* 特定のモータに最適な設定については、データシートを参照してください。*/ -#define RATED_VOLTAGE 2 -#define V_PEAK 2.8 -#define V_RMS 2.0 -#define V_PEAK 2.1 -#define F_LRA 205 /* 共振周波数 */ -``` - -#### DRV2605L 波形ライブラリ - -DRV2605L には呼び出して再生できる様々な波形シーケンスのプリロードライブラリが同梱されています。マクロを書く場合、これらの波形は `DRV_pulse(*sequence name or number*)` を使って再生することができます - -データシートの波形シーケンスのリスト - -| seq# | シーケンス名 | seq# | シーケンス名 | seq# | シーケンス名 | -|-----|---------------------|-----|-----------------------------------|-----|--------------------------------------| -| 1 | strong_click | 43 | lg_dblclick_med_60 | 85 | transition_rampup_med_smooth2 | -| 2 | strong_click_60 | 44 | lg_dblsharp_tick | 86 | transition_rampup_short_smooth1 | -| 3 | strong_click_30 | 45 | lg_dblsharp_tick_80 | 87 | transition_rampup_short_smooth2 | -| 4 | sharp_click | 46 | lg_dblsharp_tick_60 | 88 | transition_rampup_long_sharp1 | -| 5 | sharp_click_60 | 47 | buzz | 89 | transition_rampup_long_sharp2 | -| 6 | sharp_click_30 | 48 | buzz_80 | 90 | transition_rampup_med_sharp1 | -| 7 | soft_bump | 49 | buzz_60 | 91 | transition_rampup_med_sharp2 | -| 8 | soft_bump_60 | 50 | buzz_40 | 92 | transition_rampup_short_sharp1 | -| 9 | soft_bump_30 | 51 | buzz_20 | 93 | transition_rampup_short_sharp2 | -| 10 | dbl_click | 52 | pulsing_strong | 94 | transition_rampdown_long_smooth1_50 | -| 11 | dbl_click_60 | 53 | pulsing_strong_80 | 95 | transition_rampdown_long_smooth2_50 | -| 12 | trp_click | 54 | pulsing_medium | 96 | transition_rampdown_med_smooth1_50 | -| 13 | soft_fuzz | 55 | pulsing_medium_80 | 97 | transition_rampdown_med_smooth2_50 | -| 14 | strong_buzz | 56 | pulsing_sharp | 98 | transition_rampdown_short_smooth1_50 | -| 15 | alert_750ms | 57 | pulsing_sharp_80 | 99 | transition_rampdown_short_smooth2_50 | -| 16 | alert_1000ms | 58 | transition_click | 100 | transition_rampdown_long_sharp1_50 | -| 17 | strong_click1 | 59 | transition_click_80 | 101 | transition_rampdown_long_sharp2_50 | -| 18 | strong_click2_80 | 60 | transition_click_60 | 102 | transition_rampdown_med_sharp1_50 | -| 19 | strong_click3_60 | 61 | transition_click_40 | 103 | transition_rampdown_med_sharp2_50 | -| 20 | strong_click4_30 | 62 | transition_click_20 | 104 | transition_rampdown_short_sharp1_50 | -| 21 | medium_click1 | 63 | transition_click_10 | 105 | transition_rampdown_short_sharp2_50 | -| 22 | medium_click2_80 | 64 | transition_hum | 106 | transition_rampup_long_smooth1_50 | -| 23 | medium_click3_60 | 65 | transition_hum_80 | 107 | transition_rampup_long_smooth2_50 | -| 24 | sharp_tick1 | 66 | transition_hum_60 | 108 | transition_rampup_med_smooth1_50 | -| 25 | sharp_tick2_80 | 67 | transition_hum_40 | 109 | transition_rampup_med_smooth2_50 | -| 26 | sharp_tick3_60 | 68 | transition_hum_20 | 110 | transition_rampup_short_smooth1_50 | -| 27 | sh_dblclick_str | 69 | transition_hum_10 | 111 | transition_rampup_short_smooth2_50 | -| 28 | sh_dblclick_str_80 | 70 | transition_rampdown_long_smooth1 | 112 | transition_rampup_long_sharp1_50 | -| 29 | sh_dblclick_str_60 | 71 | transition_rampdown_long_smooth2 | 113 | transition_rampup_long_sharp2_50 | -| 30 | sh_dblclick_str_30 | 72 | transition_rampdown_med_smooth1 | 114 | transition_rampup_med_sharp1_50 | -| 31 | sh_dblclick_med | 73 | transition_rampdown_med_smooth2 | 115 | transition_rampup_med_sharp2_50 | -| 32 | sh_dblclick_med_80 | 74 | transition_rampdown_short_smooth1 | 116 | transition_rampup_short_sharp1_50 | -| 33 | sh_dblclick_med_60 | 75 | transition_rampdown_short_smooth2 | 117 | transition_rampup_short_sharp2_50 | -| 34 | sh_dblsharp_tick | 76 | transition_rampdown_long_sharp1 | 118 | long_buzz_for_programmatic_stopping | -| 35 | sh_dblsharp_tick_80 | 77 | transition_rampdown_long_sharp2 | 119 | smooth_hum1_50 | -| 36 | sh_dblsharp_tick_60 | 78 | transition_rampdown_med_sharp1 | 120 | smooth_hum2_40 | -| 37 | lg_dblclick_str | 79 | transition_rampdown_med_sharp2 | 121 | smooth_hum3_30 | -| 38 | lg_dblclick_str_80 | 80 | transition_rampdown_short_sharp1 | 122 | smooth_hum4_20 | -| 39 | lg_dblclick_str_60 | 81 | transition_rampdown_short_sharp2 | 123 | smooth_hum5_10 | -| 40 | lg_dblclick_str_30 | 82 | transition_rampup_long_smooth1 | | | -| 41 | lg_dblclick_med | 83 | transition_rampup_long_smooth2 | | | -| 42 | lg_dblclick_med_80 | 84 | transition_rampup_med_smooth1 | | | -### オプションの DRV2605L の定義 - -``` -#define DRV_GREETING *sequence name or number* -``` -触覚フィードバッグが有効な場合、キーボード起動時に特定のシーケンスに合わせて振動します。以下の定義を使って選択することができます: - -``` -#define DRV_MODE_DEFAULT *sequence name or number* -``` -これにより HPT_RST がアクティブモードとして設定するシーケンスを設定します。未定義の場合、HPT_RST が押された時にモードが 1 に設定されます。 - -### DRV2605L 連続触覚モード - -このモードは強さを増減するオプションを使って連続触覚フィードバッグを設定します。 diff --git a/docs/ja/feature_hd44780.md b/docs/ja/feature_hd44780.md deleted file mode 100644 index b4e1ef03ab37..000000000000 --- a/docs/ja/feature_hd44780.md +++ /dev/null @@ -1,62 +0,0 @@ -# HD44780 LCD ディスプレイ - - - -これは Peter Fleury の LCD ライブラリの統合です。このページは基本について説明します。[詳細なドキュメントについてはこのページをご覧ください](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) - -HD44780 ディスプレイのサポートを有効にするには、キーボードの `rules.mk` の `HD44780_ENABLE` フラグを yes に設定します。 - -## 設定 - -ディスプレイで使用されるピンとディスプレイの行と列の数を、キーボードの `config.h` に設定する必要があります。 - - -HD44780 のラベルが付いたセクションのコメントを外し、必要に応じてパラメータを変更します。 -```` -/* - * HD44780 LCD ディスプレイ設定 - */ - -#define LCD_LINES 2 //< ディスプレイの表示行数 -#define LCD_DISP_LENGTH 16 //< ディスプレイの行ごとの表示文字数 -#define LCD_IO_MODE 1 //< 0: メモリマップモード 1: IO ポートモード -#if LCD_IO_MODE -#define LCD_PORT PORTB //< LCD 行のためのポート -#define LCD_DATA0_PORT LCD_PORT //< 4ビットデータビット 0 のポート -#define LCD_DATA1_PORT LCD_PORT //< 4ビットデータビット 1 のポート -#define LCD_DATA2_PORT LCD_PORT //< 4ビットデータビット 2 のポート -#define LCD_DATA3_PORT LCD_PORT //< 4ビットデータビット 3 のポート -#define LCD_DATA0_PIN 4 //< 4ビットデータビット 0 のピン -#define LCD_DATA1_PIN 5 //< 4ビットデータビット 1 のピン -#define LCD_DATA2_PIN 6 //< 4ビットデータビット 2 のピン -#define LCD_DATA3_PIN 7 //< 4ビットデータビット 3 のピン -#define LCD_RS_PORT LCD_PORT //< RS 線のためのポート -#define LCD_RS_PIN 3 //< RS 線のためのピン -#define LCD_RW_PORT LCD_PORT //< RW 線のためのポート -#define LCD_RW_PIN 2 //< RW 線のためのピン -#define LCD_E_PORT LCD_PORT //< Enable 線のためのポート -#define LCD_E_PIN 1 //< Enable 線のためのピン -#endif -```` - -他のプロパティを設定する必要がある場合は、それらを `quantum/hd44780.h` からコピーし、`config.h` に設定することができます。(訳注)`quantum/hd44780.h` は `drivers/avr/hd44780.h` の間違いではないかと思われます。 - -## 使用法 - -ディスプレイを初期化するには、以下のパラメータのうちの1つを使って `lcd_init()` を呼び出します: -```` -LCD_DISP_OFF : ディスプレイオフ -LCD_DISP_ON : ディスプレイオン、カーソルオフ -LCD_DISP_ON_CURSOR : ディスプレイオン、カーソルオン -LCD_DISP_ON_CURSOR_BLINK : ディスプレイオン、点滅カーソル -```` -これはキーボードの `matrix_init_kb` またはキーマップの `matrix_init_user` で行うのが最適です。 -使用前にディスプレイをクリアすることをお勧めします。 -そのためには、`lcd_clrscr()` を呼びます。 - -ディスプレイに何かを表示するには、最初に `lcd_gotoxy(column, line)` を呼びます。最初の行の先頭に移動するには、`lcd_gotoxy(0, 0)` を呼び出し、その後 `lcd_puts("example string")` を使って文字列を出力します。 - -ディスプレイを制御することができる、より多くのメソッドがあります。[詳細なドキュメントについてはリンクされたページをご覧ください](http://www.peterfleury.epizy.com/doxygen/avr-gcc-libraries/group__pfleury__lcd.html) diff --git a/docs/ja/feature_key_lock.md b/docs/ja/feature_key_lock.md deleted file mode 100644 index 22cd9fb81090..000000000000 --- a/docs/ja/feature_key_lock.md +++ /dev/null @@ -1,27 +0,0 @@ -# キーロック - - - -特定のキーを長時間押すことが必要になる場合があります。キーロックは次に押すキーを押したままにします。もう一度押すと、リリースされます。 - -いくつかの文を全て大文字で入力する必要があるとしましょう。`KC_LOCK` を押し、次にシフトを押します。これで、シフトは次にタップするまで押していると見なされます。キーロックを Caps Lock と考えることができますが、さらに強力です。 - -## 使用法 - -最初に `rules.mk` で `KEY_LOCK_ENABLE = yes` を設定することでキーロックを有効にします。次に、キーマップでキーを選択し、それをキーコード `KC_LOCK` に割り当てます。 - -## キーコード - -| キーコード | 説明 | -|---------|--------------------------------------------------------------| -| `KC_LOCK` | キーが再び押されるまで次のキーを押したままにします。 | - -## 注意事項 - -キーロックは、標準アクションキーと[ワンショットモディファイア](ja/one_shot_keys.md)キー (例えば、Shift を `OSM(MOD_LSFT)` と定義した場合)のみを押し続けることができます。 -これは、QMK の特殊機能(ワンショットモディファイアを除く)、または `KC_LPRN` のような shift を押されたキーのバージョンは含みません。[基本的なキーコード](ja/keycodes_basic.md)リストにある場合、押したままにすることができます。 - -レイヤーの切り替えは、キーロックを解除しません。 diff --git a/docs/ja/feature_layers.md b/docs/ja/feature_layers.md deleted file mode 100644 index ca3e05583573..000000000000 --- a/docs/ja/feature_layers.md +++ /dev/null @@ -1,97 +0,0 @@ -# レイヤー :id=layers - - - -QMK ファームウェアの最も強力で良く使われている機能の一つは、レイヤーを使う機能です。ほとんどの人にとって、これはラップトップやタブレットキーボードにあるのと同じように、様々なキーを可能にするファンクションキーに相当します。 - -レイヤースタックがどのように動作するかの詳細な説明については、[キーマップの概要](ja/keymap.md#keymap-and-layers)を調べてください。 - -## レイヤーの切り替えとトグル :id=switching-and-toggling-layers - -以下の関数により、様々な方法でレイヤーをアクティブにすることができます。レイヤーは通常、独立したレイアウトでは無いことに注意してください -- 複数のレイヤーを一度にアクティブにすることができ、レイヤーが `KC_TRNS` を使ってキーの押下を下のレイヤーへと透過させることが一般的です。MO()、LM()、TT() あるいは LT() を使って一時的なレイヤーの切り替えを使う場合、上のレイヤーのキーを透過にするようにしてください。さもないと意図したように動作しないかもしれません。 - -* `DF(layer)` - デフォルトレイヤーを切り替えます。デフォルトレイヤーは、他のレイヤーがその上に積み重なっている、常にアクティブな基本レイヤーです。デフォルトレイヤーの詳細については以下を見てください。これは QWERTY から Dvorak レイアウトに切り替えるために使うことができます。(これは一時的な切り替えであり、キーボードの電源が切れるまでしか持続しないことに注意してください。デフォルトレイヤーを永続的に変更するには、[process_record_user](ja/custom_quantum_functions.md#programming-the-behavior-of-any-keycode) 内で `set_single_persistent_default_layer` 関数を呼び出すなど、より深いカスタマイズが必要です。) -* `MO(layer)` - 一時的に*レイヤー*をアクティブにします。キーを放すとすぐに、レイヤーは非アクティブになります。 -* `LM(layer, mod)` - (`MO` のように)一時的に*レイヤー*をアクティブにしますが、モディファイア *mod* がアクティブな状態です。layer 0-15 と、左モディファイアのみをサポートします: `MOD_LCTL`、`MOD_LSFT`、`MOD_LALT`、`MOD_LGUI` (`KC_` 定数の代わりに `MOD_` 定数を使うことに注意してください)。これらのモディファイアは、例えば `LM(_RAISE, MOD_LCTL | MOD_LALT)` のように、ビット単位の OR を使って組み合わせることができます。 -* `LT(layer, kc)` - ホールドされた時に*レイヤー*を一時的にアクティブにし、タップされた時に *kc* を送信します。layer 0-15 のみをサポートします。 -* `OSL(layer)` - 次のキーが押されるまで、一時的に*レイヤー*をアクティブにします。詳細と追加機能については、[ワンショットキー](ja/one_shot_keys.md)を見てください。 -* `TG(layer)` - *レイヤー*を切り替えます。非アクティブな場合はアクティブにし、逆も同様です。 -* `TO(layer)` - *レイヤー*をアクティブにし、他の全てのレイヤー(デフォルトレイヤーを除く)を非アクティブにします。この関数は特別です。1つのレイヤーをアクティブなレイヤースタックに追加/削除する代わりに、現在のアクティブなレイヤーを完全に置き換え、唯一上位のレイヤーを下位のレイヤーで置き換えることができるからです。これはキーダウンで(キーが押されるとすぐに)アクティブになります。 -* `TT(layer)` - レイヤーのタップ切り替え。キーを押したままにすると*レイヤー*がアクティブにされ、放すと非アクティブになります (`MO` 風)。繰り返しタップすると、レイヤーはオンあるいはオフを切り替えます (`TG` 風)。デフォルトでは5回のタップが必要ですが、`TAPPING_TOGGLE` を定義することで変更することができます -- 例えば、2回のタップだけで切り替えるには、`#define TAPPING_TOGGLE 2` を定義します。 - -### 注意事項 :id=caveats - -現在のところ、`LT()` の `layer` 引数はレイヤー 0-15 に制限され、`kc` 引数は[基本的なキーコードセット](ja/keycodes_basic.md)に制限されています。つまり、`LCTL()`、`KC_TILD` あるいは `0xFF` より大きなキーコードを使うことができません。これは、QMK が16ビットのキーコードを使うためです。4ビットは機能の識別のために使われ、4ビットはレイヤーのために使われ、キーコードには8ビットしか残されていません。 - -これを拡張してもせいぜい複雑になるだけでしょう。32ビットキーコードに移行すると、これの多くが解決されますが、キーマップマトリックスが使用する領域が2倍になります。また、問題が起きる可能性もあります。タップしたキーコードにモディファイアを適用する必要がある場合は、[タップダンス](ja/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys)を使うことができます。 - -## レイヤーとの連携 :id=working-with-layers - -レイヤーを切り替える時は注意してください。(キーボードを取り外さずに)そのレイヤーを非アクティブにすることができずレイヤーから移動できなくなる可能性があります。最も一般的な問題を避けるためのガイドラインを作成しました。 - -### 初心者 :id=beginners - -QMK を使い始めたばかりの場合は、全てを単純にしたいでしょう。レイヤーをセットアップする時は、これらのガイドラインに従ってください: - -* デフォルトの "base" レイヤーとして、layer 0 をセットアップします。これは通常の入力レイヤーであり、任意のレイアウト (qwerty、dvorak、colemak など)にすることができます。通常はキーボードのキーのほとんどまたは全てが定義されているため、これを最下位のレイヤーとして設定することが重要です。そうすることで、もしそれが他のレイヤーの上 (つまりレイヤー番号が大きい)にある場合の影響を防ぎます。 -* layer 0 をルートとして、レイヤーを "ツリー" レイアウトに配置します。他の複数のレイヤーから同じレイヤーに行こうとしないでください。 -* 各レイヤーのキーマップでは、より高い番号のレイヤーのみを参照します。レイヤーは最大の番号(最上位)のアクティブレイヤーから処理されるため、下位レイヤーの状態を変更するのは難しくエラーが発生しやすくなります。 - -### 中級ユーザ :id=intermediate-users - -複数の基本レイヤーが必要な場合があります。例えば、QWERTY と Dvorak を切り替える場合、国ごとに異なるレイアウトを切り替える場合、あるいは異なるビデオゲームごとにレイアウトを切り替える場合などです。基本レイヤーは常に最小の番号のレイヤーである必要があります。複数の基本レイヤーがある場合、常にそれらを相互排他的に扱う必要があります。1つの基本レイヤーがオンの場合、他をオフにします。 - -### 上級ユーザ :id=advanced-users - -レイヤーがどのように動作し、何ができるかを理解したら、より創造的になります。初心者のセクションで列挙されている規則は、幾つかの巧妙な詳細を回避するのに役立ちますが、特に超コンパクトなキーボードのユーザにとって制約になる場合があります。レイヤーの仕組みを理解することで、レイヤーをより高度な方法で使うことができます。 - -レイヤーは番号順に上に積み重なっています。キーの押下の動作を決定する時に、QMK は上から順にレイヤーを走査し、`KC_TRNS` に設定されていない最初のアクティブなレイヤーに到達すると停止します。結果として、現在のレイヤーよりも数値的に低いレイヤーをアクティブにし、現在のレイヤー(あるいはアクティブでターゲットレイヤーよりも高い別のレイヤー)に `KC_TRNS` 以外のものがある場合、それが送信されるキーであり、アクティブ化したばかりのレイヤー上のキーではありません。これが、ほとんどの人の "なぜレイヤーが切り替わらないのか" 問題の原因です。 - -場合によっては、マクロ内あるいはタップダンスルーチンの一部としてレイヤーを切り替えほうが良いかもしれません。`layer_on` はレイヤーをアクティブにし、`layer_off` はそれを非アクティブにします。もっと多くのレイヤーに関する関数は、[action_layer.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/action_layer.h) で見つけることができます。 - -## 関数 :id=functions - -レイヤーの使用あるいは操作に関係する多くの関数(と変数)があります。 - -| 関数 | 説明 | -| -------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | -| `layer_state_set(layer_mask)` | 直接レイヤーの状態を設定する (推奨。何をしているのか分かっていない場合は使わないでください)。 | -| `layer_clear()` | 全てのレイヤーを消去する (全てをオフにします)。 | -| `layer_move(layer)` | 指定されたレイヤーをオンにし、それ以外をオフにする。 | -| `layer_on(layer)` | 指定されたレイヤーをオンにし、それ以外を既存の状態のままにする。 | -| `layer_off(layer)` | 指定されたレイヤーをオフにし、それ以外を既存の状態のままにする。 | -| `layer_invert(layer)` | 指定されたレイヤーの状態を反転/トグルする。 | -| `layer_or(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で一致するビットに基づいてレイヤーをオンにする。 | -| `layer_and(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で有効なビットに基づいてレイヤーをオンにする。 | -| `layer_xor(layer_mask)` | 指定されたレイヤーと既存のレイヤー状態の間で一致しないビットに基づいてレイヤーをオンにする。 | -| `layer_debug(layer_mask)` | デバッガのコンソールに現在のビットマスクと最も高いレイヤーを出力する。 | -| `default_layer_set(layer_mask)` | 直接デフォルトレイヤーの状態を設定する (推奨。何をしているのか分かっていない場合は使わないでください)。 | -| `default_layer_or(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致するビットに基づいてレイヤーをオンにする。 | -| `default_layer_and(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致する有効なビットに基づいてレイヤーをオンにする。 | -| `default_layer_xor(layer_mask)` | 指定されたレイヤーと既存のデフォルトレイヤー状態の間で一致しないビットに基づいてレイヤーをオンにする。 | -| `default_layer_debug(layer_mask)` | デバッガのコンソールに現在のビットマスクと最も高いアクティブなレイヤーを出力する。 | -| [`set_single_persistent_default_layer(layer)`](ja/ref_functions.md#setting-the-persistent-default-layer) | デフォルトレイヤーを設定し、それを永続化メモリ (EEPROM) に書き込む。 | -| [`update_tri_layer(x, y, z)`](ja/ref_functions.md#update_tri_layerx-y-z) | レイヤー `x` と `y` の両方がオンであるかを調べ、それに基づいて `z` を設定する(両方がオンの場合オン、そうでなければオフ)。 | -| [`update_tri_layer_state(state, x, y, z)`](ja/ref_functions.md#update_tri_layer_statestate-x-y-z) | `update_tri_layer(x, y, z)` と同じことをするが、`layer_state_set_*` 関数から呼ばれる。 | - - -呼び出すことができる関数に加えて、レイヤーが変更されるたびに呼び出されるコールバック関数が幾つかあります。これはレイヤー状態を関数に渡し、読み取りや変更することができます。 - -| コールバック | 説明 | -| --------------------------------------------------- | ------------------------------------------------------------------------------------------------ | -| `layer_state_set_kb(layer_state_t state)` | キーボードレベルのレイヤー関数のためのコールバック。 | -| `layer_state_set_user(layer_state_t state)` | ユーザレベルのレイヤー関数のためのコールバック。 | -| `default_layer_state_set_kb(layer_state_t state)` | キーボードレベルのデフォルトレイヤー関数のためのコールバック。キーボードの初期化時に呼ばれます。 | -| `default_layer_state_set_user(layer_state_t state)` | ユーザレベルのデフォルトレイヤー関数のためのコールバック。キーボードの初期化時に呼ばれます。 | - -?> これらのコールバックを使うための追加の情報については、[レイヤー変換コード](ja/custom_quantum_functions.md#layer-change-code)のドキュメントを調べてください。 - -次の関数やマクロを使って、特定のレイヤーの状態を確認することもできます。 - -| 関数 | 説明 | 別名 | -| ------------------------------- | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- | -| `layer_state_is(layer)` | 指定された `layer` がグローバルに有効かどうかを確認する。 | `IS_LAYER_ON(layer)`, `IS_LAYER_OFF(layer)` | -| `layer_state_cmp(state, layer)` | `state` を確認して指定された `layer` が有効かどうかを確認する。レイヤーのコールバックで使うことを目的とする。 | `IS_LAYER_ON_STATE(state, layer)`, `IS_LAYER_OFF_STATE(state, layer)` | diff --git a/docs/ja/feature_layouts.md b/docs/ja/feature_layouts.md deleted file mode 100644 index 9b36a1eda562..000000000000 --- a/docs/ja/feature_layouts.md +++ /dev/null @@ -1,114 +0,0 @@ -# レイアウト: 複数のキーボードで1つのキーマップを使用 - - - -`layouts/` フォルダは、様々なキーボードに適用できる色々な物理キーレイアウトを含みます。 - -``` -layouts/ -+ default/ -| + 60_ansi/ -| | + readme.md -| | + layout.json -| | + a_good_keymap/ -| | | + keymap.c -| | | + readme.md -| | | + config.h -| | | + rules.mk -| | + / -| | + ... -| + / -+ community/ -| + / -| + ... -``` - -`layouts/default/` と `layouts/community/` は、レイアウト「repositories」の2つの例です。現在のところ、`default` にはユーザの参考用に、レイアウトに関する全ての情報および、`default_` という名前の1つのデフォルトのキーマップが含まれています。`community` には全ての共有キーマップが含まれており、それらはユーザが `layouts/` にクローンするための別のリポジトリに分割することを最終的な目的としていますQMK は `layouts/` 内のすべてのフォルダを検索するため、ここに複数のリポジトリを持つことができます。 - -各レイアウトフォルダは、レイアウトの物理的な側面に基づいて、可能な限り一般的な名称で(`[a-z0-9_]`)という名前が付けられ、キーボードで定義されるレイアウトと一緒に `readme.md` を含みます。 - -```md -# 60_ansi - - LAYOUT_60_ansi -``` - -新しい名前は既存のレイアウトで設定された標準に準拠しようと努力する必要があり、必要に応じて PR/Issue で議論することができます。 - -## レイアウトのサポート - -キーボードがレイアウトをサポートするために、変数は `.h` で定義し、引数/キー (できれば物理レイアウト)の数に一致している必要があります。 - - #define LAYOUT_60_ansi KEYMAP_ANSI - -レイアウトの名前は次の正規表現に一致しなければなりません: `[a-z0-9_]+` - -フォルダ名はキーボードの `rules.mk` に追加する必要があります: - - LAYOUTS = 60_ansi - -`LAYOUTS` は任意のキーボードフォルダレべルの `rules.mk` に設定することができます: - - LAYOUTS = 60_iso - -ただし、`LAYOUT_` 変数は `.h` でも定義する必要があります。 - -## キーマップのビルド - -以下の形式でコマンドを使ってキーボードキーマップを作成できるはずです: - - make : - -### レイアウトの競合 -キーボードが複数のレイアウトオプションをサポートし、 - - LAYOUTS = ortho_4x4 ortho_4x12 - -なおかつ両方のオプションについてレイアウトが存在する場合、 -``` -layouts/ -+ community/ -| + ortho_4x4/ -| | + / -| | | + ... -| + ortho_4x12/ -| | + / -| | | + ... -| + ... -``` - -FORCE_LAYOUT 引数はどのレイアウトをビルドするかを指定するために使うことができます - - make : FORCE_LAYOUT=ortho_4x4 - make : FORCE_LAYOUT=ortho_4x12 - -## キーボードに依存しないレイアウトを作成するためのヒント - -### インクルード - -`#include "planck.h"` を使う代わりに、以下の行を使ってコンパイルされる `.h` (`.h` はここでインクルードすべきではありません)ファイルをインクルードすることができます: - - #include QMK_KEYBOARD_H - -キーボード固有のコードを保持したい場合は、これらの変数を使って `#ifdef` 文でエスケープすることができます: - -* `KEYBOARD__` - -例えば: - -```c -#ifdef KEYBOARD_planck - #ifdef KEYBOARD_planck_rev4 - planck_rev4_function(); - #endif -#endif -``` - -名前は小文字でキーボード/リビジョンのフォルダ/ファイル名と正確に一致することに注意してください。 - -### キーマップ - -同じレイアウトで分割および非分割キーボードをサポートするためには、キーマップでキーボード非依存の `LAYOUT_` マクロを使う必要があります。例えば、Let's Split および Planck が同じレイアウトを共有するには、`LAYOUT_planck_grid` や C 配列の場合の単なる `{}` の代わりに、`LAYOUT_ortho_4x12` を使う必要があります。 diff --git a/docs/ja/feature_leader_key.md b/docs/ja/feature_leader_key.md deleted file mode 100644 index b826b068eb24..000000000000 --- a/docs/ja/feature_leader_key.md +++ /dev/null @@ -1,164 +0,0 @@ -# リーダーキー: 新しい種類のモディファイア - - - -もしあなたが Vim を使ったことがある場合、リーダーキーは何であるかを知っています。そうでなければ、素晴らしい概念を発見しようとしています。:) 例えば、Alt+Shift+W を押す(3つのキーを同時に押す)代わりに、キーの_シーケンス_を押すことができたらどうでしょう?つまり、特別なモディファイア (リーダーキー)を押して、続けて W と C を押すと (単純にキーを高速に繋げます)、何かが起こります。 - -それが `KC_LEAD` の機能です。以下は例です: - -1. リーダーキーとして使いたいキーボードのキーを選択します。それにキーコード `KC_LEAD` を割り当てます。このキーはこのためだけの専用です -- 単一アクションのキーで、他の用途には使うことができません。 -2. `config.h` に `#define LEADER_TIMEOUT 300` という行を追加します。これによって `KC_LEAD` キーのタイムアウトを設定します。具体的には、`KC_LEAD` キーを押してからリーダーキーのシーケンスを完了するまで一定の時間しかありません。ここでの `300` はそれを300msに設定します。この値を増やして、シーケンスを入力する時間を増やすことができます。ただし、この時間中に押されたキーは全て途中で遮られ、送信されません。そのためこの値は小さくしておいたほうが良いかもしれません。 - * デフォルトでは、このタイムアウトは、`KC_LEAD` を押してからシーケンス全体が完了するまでに掛かる時間です。これは一部の人にとっては非常に短いかもしれません。そのため、このタイムアウトを増やしたほうが良い場合もあります。必要に応じて、`LEADER_PER_KEY_TIMING` オプションを有効にしたほうが良い場合もあります。これは各キーがタップされる度にタイムアウトまでの時間をリセットする機能です。これにより、タイムアウト時間を短くしつつも、比較的長いシーケンスを使うことができます。このオプションを有効にするには、`config.h` に `#define LEADER_PER_KEY_TIMING` を追加します。 -3. `matrix_scan_user` 関数の中で、以下のようなものを追加します: - -```c -LEADER_EXTERNS(); - -void matrix_scan_user(void) { - LEADER_DICTIONARY() { - leading = false; - leader_end(); - - SEQ_ONE_KEY(KC_F) { - // マクロ内でできること - SEND_STRING("QMK is awesome."); - } - SEQ_TWO_KEYS(KC_D, KC_D) { - SEND_STRING(SS_LCTL("a") SS_LCTL("c")); - } - SEQ_THREE_KEYS(KC_D, KC_D, KC_S) { - SEND_STRING("https://start.duckduckgo.com\n"); - } - SEQ_TWO_KEYS(KC_A, KC_S) { - register_code(KC_LGUI); - register_code(KC_S); - unregister_code(KC_S); - unregister_code(KC_LGUI); - } - } -} -``` - -ご覧のとおり、幾つかの関数があります。`SEQ_ONE_KEY` を単一キーシーケンス (リーダーの後に1つのキーのみ)に使い、より長いシーケンスについては `SEQ_TWO_KEYS`、`SEQ_THREE_KEYS` から `SEQ_FIVE_KEYS` を使うことができます。 - -これらはそれぞれ1つ以上のキーコードを引数として受け付けます。これは重要な点です: **キーボードの任意のレイヤー**のキーコードを使うことができます。当たり前ですが、リーダーマクロが発動するにはそのレイヤーがアクティブである必要があります - -## `rules.mk` にリーダーキーサポートを追加 - -リーダーキーのサポートを追加するには、単純にキーマップの `rules.mk` に1行を追加します: - -```make -LEADER_ENABLE = yes -``` - -## リーダーキーのキーごとのタイミング - -長いリーダーキー文字列のためや 200wpm のタイピングスキルが無い場合に、非常に長いタイムアウト時間に頼るのではなく、キーを押すごとに入力を完了するまでの時間を増やす機能を使用することができます。これは、リーダーキーを使ってタップダンスを再現する場合に非常に役立ちます (C, C, C のような同じキーを複数回タップする場合)。 - -これを有効にするには、以下を `config.h` に配置します: -```c -#define LEADER_PER_KEY_TIMING -``` - -この後、`LEADER_TIMEOUT` を 300ms 未満に下げることをお勧めします。 - -```c -#define LEADER_TIMEOUT 250 -``` - -これで、リーダーキーのタイムアウト時間を 1000ms に設定することなく以下のようなことが可能になると思われます。 - -```c -SEQ_THREE_KEYS(KC_C, KC_C, KC_C) { - SEND_STRING("Per key timing is great!!!"); -} -``` - -## リーダーキーの無限タイムアウト - -リーダーキーが、シーケンスの残りのキーのような快適な場所にない場合があります。リーダーキーが右上の外側のキーの1つである場合、リーダーキーに届くように手の位置を変えなければならないことがあります。 -これにより、シーケンスの大部分をすばやく入力できたとしても、シーケンス全体を時間通りに入力するのが難しい場合があります。例えば、シーケンスが `Leader + asd` の場合、手をホーム行に置けば `asd` を素早く打つのは非常に簡単です。しかし、リーダーキーに届くようにホーム行から手を移動し、戻った後、時間内にシーケンスを開始することはできません。 -この状況が手に与えるストレスを取り除くために、リーダーキーだけに無限のタイムアウトを有効にすることができます。つまり、リーダーキーを押した後、シーケンスの残りを開始するまでの時間が無限になり、シーケンスの残りを快適に入力するための最適な位置に手を置くことができます。 -この無限のタイムアウトはリーダーキーにのみ影響するため、前述の `Leader + asd` の例では、`Leader` と `a` の間に無限の時間があります。ただし、シーケンスを開始すると、(グローバルまたはキーごとに)設定したタイムアウトは正常に機能します。 -このようにして、非常に短い `LEADER_TIMEOUT` を設定できますが、それでも手を置く時間は十分にあります。 - -これを有効にするには、以下を `config.h` に配置します: -```c -#define LEADER_NO_TIMEOUT -``` - -## 厳密なキー処理 - -デフォルトでは、リーダーキー機能は、リーダーシーケンスの確認時に [`モッドタップ`](ja/mod_tap.md) および [`レイヤータップ`](ja/feature_layers.md#switching-and-toggling-layers) 機能からのキーコードをフィルターします。つまり、`LT(3, KC_A)` を使っている場合、`LT(3, KC_A)` ではなくシーケンスの `KC_A` として取り出され、新しいユーザにとってより期待される動作を提供します。 - -ほとんどの場合これで問題ありませんが、シーケンスでキーコード全体(例えば、上の例での `LT(3, KC_A)`) を指定したい場合は、`config.h` ファイルに `#define LEADER_KEY_STRICT_KEY_PROCESSING` を追加することこのような機能を有効にすることができます。これでフィルタリングが無効になり、キーコード全体を指定する必要があります。 - -## カスタマイズ - -リーダーキー機能には、リーダーキー機能の動作にいくらかのカスタマイズを追加する方法があります。リーダーキー機能のプロセスの特定の部分で呼び出すことができる2つの関数、`leader_start()` と `leader_end()` です。 - -`KC_LEAD` キーがタップされた時に `leader_start()` 関数が呼ばれ、リーダーシーケンスが完了するか、リーダータイムアウトの時間に達した時に `leader_end()` 関数が呼ばれます。 - -リーダーシーケンスにフィードバック(ビープまたは音楽を再生するなど)を追加するために、これらの関数をコード (通常 は`keymap.c`)に追加することができます。 - -```c -void leader_start(void) { - // シーケンスの開始 -} - -void leader_end(void) { - // シーケンスの終了 (成功しない/失敗を検知) -} -``` - -### 例 - -この例では、リーダーシーケンスを開始するために `KC_LEAD` を押すとマリオの "One Up" 音が再生され、正常に完了した場合は "All Star" が再生され、失敗した場合は "Rick Roll" を再生されます。 - -```c -bool did_leader_succeed; -#ifdef AUDIO_ENABLE -float leader_start[][2] = SONG(ONE_UP_SOUND ); -float leader_succeed[][2] = SONG(ALL_STAR); -float leader_fail[][2] = SONG(RICK_ROLL); -#endif -LEADER_EXTERNS(); - -void matrix_scan_user(void) { - LEADER_DICTIONARY() { - did_leader_succeed = leading = false; - - SEQ_ONE_KEY(KC_E) { - // マクロ内でできること - SEND_STRING(SS_LCTL(SS_LSFT("t"))); - did_leader_succeed = true; - } else - SEQ_TWO_KEYS(KC_E, KC_D) { - SEND_STRING(SS_LGUI("r") "cmd\n" SS_LCTL("c")); - did_leader_succeed = true; - } - leader_end(); - } -} - -void leader_start(void) { -#ifdef AUDIO_ENABLE - PLAY_SONG(leader_start); -#endif -} - -void leader_end(void) { - if (did_leader_succeed) { -#ifdef AUDIO_ENABLE - PLAY_SONG(leader_succeed); -#endif - } else { -#ifdef AUDIO_ENABLE - PLAY_SONG(leader_fail); -#endif - } -} -``` diff --git a/docs/ja/feature_led_indicators.md b/docs/ja/feature_led_indicators.md deleted file mode 100644 index 94ee06323484..000000000000 --- a/docs/ja/feature_led_indicators.md +++ /dev/null @@ -1,119 +0,0 @@ -# LED インジケータ - - - -QMK は HID 仕様で定義された5つの LED の読み取りメソッドを提供します: - -* Num Lock -* Caps Lock -* Scroll Lock -* Compose -* Kana - -ロック LED の状態を取得するには3つの方法があります: -* `config.h` で設定オプションを指定する -* `bool led_update_kb(led_t led_state)` あるいは `_user(led_t led_state)` を実装する、または -* `led_t host_keyboard_led_state()` を呼び出す - -!> `host_keyboard_led_state()` は `led_update_user()` が呼ばれる前に新しい値を既に反映している場合があります。 - -LED の状態を `uint8_t` として提供する2つの非推奨の関数があります: - -* `uint8_t led_set_user(uint8_t usb_led)` -* `uint8_t host_keyboard_leds()` - -## 設定オプション :id=configuration-options - -インジケータを設定するには、`config.h` で以下の `#define` をします: - -| 定義 | 既定値 | 説明 | -|-----------------------|------------|----------------------------------| -| `LED_NUM_LOCK_PIN` | *定義なし* | `Num Lock` LED を制御するピン | -| `LED_CAPS_LOCK_PIN` | *定義なし* | `Caps Lock` LED を制御するピン | -| `LED_SCROLL_LOCK_PIN` | *定義なし* | `Scroll Lock` LED を制御するピン | -| `LED_COMPOSE_PIN` | *定義なし* | `Compose` LED を制御するピン | -| `LED_KANA_PIN` | *定義なし* | `Kana` LED を制御するピン | -| `LED_PIN_ON_STATE` | `1` | LED が "オン" の時のインジケータピンの状態 - high の場合は`1`、low の場合は`0` | - -独自のキーボードを設計しているわけではない限り、通常は上記の設定オプションを変更する必要はありません。 - -## `led_update_*()` - -設定オプションが十分な柔軟性を提供しない場合は、提供される API フックにより LED の挙動の独自の制御ができます。これらの関数はこれら5つの LED のいずれかの状態が変化すると呼ばれます。LED の状態を構造体のパラメータとして受け取ります。 - -慣例により、`led_update_kb()` にそのコードを実行するようフックさせるために `led_update_user()` から `true` を返し、`led_update_kb()` でコードを実行したくない場合は `false` を返します。 - -以下はいくつかの例です: - -- レイヤー表示のような何かのために LED を使うために LED を上書きする - - `_kb()` 関数を実行したくないので、`false` を返します。これはレイヤーの挙動を上書きするためです。 -- LED がオンあるいはオフになった時に音楽を再生する。 - - `_kb` 関数を実行したいので、`true` を返します。これはデフォルトの LED の挙動に追加されます。 - -?> `led_set_*` 関数は `bool` の代わりに `void` を返すため、キーボードの LED 制御を上書きすることができません。従って、代わりに `led_update_*` を使うことをお勧めします。 - -### `led_update_kb()` の実装例 - -```c -bool led_update_kb(led_t led_state) { - bool res = led_update_user(led_state); - if(res) { - // writePin は 1 でピンを high に、0 で low に設定します。 - // この例では、ピンは反転していて、 - // low/0 は LED がオンになり、high/1 は LED がオフになります。 - // この挙動は、LED がピンと VCC の間にあるか、ピンと GND の間にあるかどうかに依存します。 - writePin(B0, !led_state.num_lock); - writePin(B1, !led_state.caps_lock); - writePin(B2, !led_state.scroll_lock); - writePin(B3, !led_state.compose); - writePin(B4, !led_state.kana); - } - return res; -} -``` - -### `led_update_user()` の実装例 - -この不完全な例は Caps Lock がオンまたはオフになった場合に音を再生します。また LED の状態を保持する必要があるため、`true` を返します。 - -```c -#ifdef AUDIO_ENABLE - float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND); - float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND); -#endif - -bool led_update_user(led_t led_state) { - #ifdef AUDIO_ENABLE - static uint8_t caps_state = 0; - if (caps_state != led_state.caps_lock) { - led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off); - caps_state = led_state.caps_lock; - } - #endif - return true; -} -``` - -### `led_update_*` 関数のドキュメント - -* キーボード/リビジョン: `bool led_update_kb(led_t led_state)` -* キーマップ: `bool led_update_user(led_t led_state)` - -## `host_keyboard_led_state()` - -最後に受信した LED の状態を `led_t` として取得するためにこの関数を呼びます。これは、`led_update_*` の外部から、例えば [`matrix_scan_user()`](#matrix-scanning-code) の中で LED の状態を読み取るのに便利です。 - -## 物理的な LED の状態の設定 - -一部のキーボードの実装は、物理的な LED の状態を設定するための便利なメソッドを提供しています。 - -### Ergodox キーボード - -Ergodox の実装は、個々の LED をオンあるいはオフにするために `ergodox_right_led_1`/`2`/`3_on`/`off()` と、インデックスによってそれらをオンあるいはオフにするために `ergodox_right_led_on`/`off(uint8_t led)` を提供します。 - -さらに、LED の明度を指定することができます。全ての LED に同じ明度を指定するなら `ergodox_led_all_set(uint8_t n)` を使い、個別の LED の明度を指定するなら `ergodox_right_led_1`/`2`/`3_set(uint8_t n)` を使い、LED のインデックスを指定して明度を指定するには `ergodox_right_led_set(uint8_t led, uint8_t n)` を使います。 - -Ergodox キーボードは、最低の明度として `LED_BRIGHTNESS_LO` を、最高の輝度(これはデフォルトです)として `LED_BRIGHTNESS_HI` も定義しています。 diff --git a/docs/ja/feature_led_matrix.md b/docs/ja/feature_led_matrix.md deleted file mode 100644 index 2b1979ec68ba..000000000000 --- a/docs/ja/feature_led_matrix.md +++ /dev/null @@ -1,96 +0,0 @@ -# LED マトリックスライト - - - -この機能により、外部ドライバによって駆動される LED マトリックスを使うことができます。この機能は、バックライト制御と同じキーコードを使えるようにするため、バックライトシステムに接続します。 - -RGB LED を使いたい場合は、代わりに [RGB マトリックスサブシステム](ja/feature_rgb_matrix.md) を使うべきです。 - -## ドライバ設定 - -### IS31FL3731 - -I2C IS31FL3731 RGB コントローラを使ったアドレス指定可能な LED マトリックスライトのための基本的なサポートがあります:有効にするには、`rules.mk` に以下を追加します: - - LED_MATRIX_ENABLE = yes - LED_MATRIX_DRIVER = IS31FL3731 - -1から4個の IS31FL3731 IC を使うことができます。キーボード上に存在しない IC の `LED_DRIVER_ADDR_` 定義を指定しないでください。`config.h` に以下の項目を定義することができます: - -| 変数 | 説明 | デフォルト | -|----------|-------------|---------| -| `ISSI_TIMEOUT` | (オプション) i2c メッセージを待つ時間 | 100 | -| `ISSI_PERSISTENCE` | (オプション) 失敗したメッセージをこの回数再試行する | 0 | -| `LED_DRIVER_COUNT` | (必須) LED ドライバ IC の数 | | -| `DRIVER_LED_TOTAL` | (必須) 全てのドライバの LED ライトの数 | | -| `LED_DRIVER_ADDR_1` | (必須) 最初の LED ドライバのアドレス | | -| `LED_DRIVER_ADDR_2` | (オプション) 2番目の LED ドライバのアドレス | | -| `LED_DRIVER_ADDR_3` | (オプション) 3番目の LED ドライバのアドレス | | -| `LED_DRIVER_ADDR_4` | (オプション) 4番目の LED ドライバのアドレス | | - -2つのドライバを使う例です。 - - // これは7ビットのアドレスで、左シフトされます - // ビット0に0を設定すると書き込み、1を設定すると読み込みです (I2C プロトコルに従う) - // アドレスは配線によって変わります: - // 0b1110100 AD <-> GND - // 0b1110111 AD <-> VCC - // 0b1110101 AD <-> SCL - // 0b1110110 AD <-> SDA - #define LED_DRIVER_ADDR_1 0b1110100 - #define LED_DRIVER_ADDR_2 0b1110110 - - #define LED_DRIVER_COUNT 2 - #define LED_DRIVER_1_LED_COUNT 25 - #define LED_DRIVER_2_LED_COUNT 24 - #define DRIVER_LED_TOTAL LED_DRIVER_1_LED_TOTAL + LED_DRIVER_2_LED_TOTAL - -現在、2つのドライバのみがサポートされますが、4つの組み合わせ全てをサポートすることは簡単です。 - -`.c` に全ての LED を列挙する配列を定義します: - - const is31_led PROGMEM g_is31_leds[DRIVER_LED_TOTAL] = { - /* これらの位置については IS31 マニュアルを参照してください - * driver - * | LED address - * | | */ - {0, C3_3}, - .... - } - -ここで、`Cx_y` は[データシート](https://www.issi.com/WW/pdf/31FL3731.pdf)およびヘッダファイル `drivers/led/issi/is31fl3731-simple.h` で定義されるマトリックス内の LED の位置です。`driver` は `config.h` で定義したドライバのインデックス(`0`、`1`、`2`、`3`のいずれか)です。 - -## キーコード - -現在のところ、全ての LED マトリックスのキーコードは[バックライトシステム](ja/feature_backlight.md)と共有されます。 - -## LED マトリックス効果 - -現在のところ、LED マトリックス効果は作成されていません。 - -## カスタムレイヤー効果 - -カスタムレイヤー効果は `.c` 内で以下を定義することで行うことができます: - - void led_matrix_indicators_kb(void) { - led_matrix_set_value(index, value); - } - -同様の関数がキーマップ内で `led_matrix_indicators_user` として動作します。 - -## サスペンド状態 - -サスペンド機能を使うには、以下を `.c` に追加します: - - void suspend_power_down_kb(void) - { - led_matrix_set_suspend_state(true); - } - - void suspend_wakeup_init_kb(void) - { - led_matrix_set_suspend_state(false); - } diff --git a/docs/ja/feature_macros.md b/docs/ja/feature_macros.md deleted file mode 100644 index 6371f0c20a1e..000000000000 --- a/docs/ja/feature_macros.md +++ /dev/null @@ -1,303 +0,0 @@ -# マクロ - - - -マクロにより、1つのキーを押すだけで複数のキーストロークを送信することができます。QMK にはマクロを定義し使う方法が幾つかあります。これらはなんでもすることができます: よく使うフレーズの入力、コピーペースト、反復的なゲームの動き、あるいはコードを書くことさえ手助けします。 - -!> **セキュリティの注意**: マクロを使って、パスワード、クレジットカード番号、その他の機密情報のいずれも送信することが可能ですが、それは非常に悪い考えです。あなたのキーボードを手に入れた人は誰でもテキストエディタを開いてその情報にアクセスすることができます。 - -## `SEND_STRING()` と `process_record_user` - -単語またはフレーズを入力するキーが欲しい時があります。最も一般的な状況のために `SEND_STRING()` を提供しています。これは文字列(つまり、文字のシーケンス)を入力します。簡単にキーコードに変換することができる全ての ASCII 文字がサポートされています (例えば、`qmk 123\n\t`)。 - -以下は2キーのキーボードのための `keymap.c` の例です: - -```c -enum custom_keycodes { - QMKBEST = SAFE_RANGE, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QMKBEST: - if (record->event.pressed) { - // キーコード QMKBEST が押された時 - SEND_STRING("QMK is the best thing ever!"); - } else { - // キーコード QMKBEST が放された時 - } - break; - } - return true; -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = { - {QMKBEST, KC_ESC}, - // ... - }, -}; -``` - -ここで起きることは以下の通りです: -最初に他のキーコードで使用されていない範囲で新しいカスタムキーコードを定義します。 -次に、`process_record_user` 関数を使います。これはキーが押されるか放されるたびに呼び出され、カスタムキーコードがアクティブかどうかを確認します。 -アクティブな場合、`SEND_STRING` マクロ (これは C プロセッサのマクロで、QMK のマクロと混同しないでください)を介して文字列 `"QMK is the best thing ever!"` をコンピュータに送信します。 -呼び出し元に、処理したばかりのキー押下を通常通り(機能を置き換えたり変更したりしなかったので)処理し続けるよう指示するため、`true` を返します。 -最後に、最初のボタンがマクロをアクティブにし、2番目のボタンが単なるエスケープボタンになるようにキーマップを定義します。 - -複数のマクロを追加することもできます。 -以下のように、別のキーコードを追加し、switch 文に別の case ラベルを追加することで、それを行うことができます: - -```c -enum custom_keycodes { - QMKBEST = SAFE_RANGE, - QMKURL, - MY_OTHER_MACRO, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QMKBEST: - if (record->event.pressed) { - // キーコード QMKBEST が押された時 - SEND_STRING("QMK is the best thing ever!"); - } else { - // キーコード QMKBEST が放された時 - } - break; - - case QMKURL: - if (record->event.pressed) { - // キーコード QMKURL が押された場合 - SEND_STRING("https://qmk.fm/\n"); - } else { - // キーコード QMKURL が放された場合 - } - break; - - case MY_OTHER_MACRO: - if (record->event.pressed) { - SEND_STRING(SS_LCTL("ac")); // 全てを選択しコピーします - } - break; - } - return true; -}; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = { - {MY_CUSTOM_MACRO, MY_OTHER_MACRO}, - // ... - }, -}; -``` - -### 高度なマクロ - -`process_record_user()` 関数のほかに、`post_process_record_user()` 関数があります。これは `process_record` の後に実行され、キーストロークが送信された後の処理に使用できます。これは例えば、通常のキーの前に押され、通常のキーの後で放されるキーがほしい場合に便利です。 - -この例では、通常のキー入力を変更して、キーストロークが通常送信される前に `F22` が押されるようにし、キーが放された__後にのみ__ `F22` キーを放します。 - -```c -static uint8_t f22_tracker; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_A ... KC_F21: // F22 をスキップする方法に注意してください - case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです - if (record->event.pressed) { - register_code(KC_F22); //これは F22 を押したことを送信することを意味します - f22_tracker++; - register_code(keycode); - return false; - } - break; - } - return true; -} - -void post_process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_A ... KC_F21: // F22 をスキップする方法に注意してください - case KC_F23 ... KC_EXSEL: //exsel は修飾キーの直前のキーです - if (!record->event.pressed) { - f22_tracker--; - if (!f22_tracker) { - unregister_code(KC_F22); //これは F22 を放したことを送信することを意味します - } - } - break; - } -} -``` - - -### タップ、ダウン、アップ - -`Ctrl` あるいは `Home` など、ソースコードに文字列として表記できないキーをマクロで使うこともできます。 -以下のようにラップすることで任意のコードを送信することができます: - -* `SS_TAP()` キーを押して放します。 -* `SS_DOWN()` キーを押します (ただし、放しません)。 -* `SS_UP()` キーを放します。 - -例えば: - - SEND_STRING(SS_TAP(X_HOME)); - -`KC_HOME` をタップします - プリフィックスが `X_` で `KC_` ではないことに注意してください。以下のように、他の文字列と組み合わせることもできます: - - SEND_STRING("VE"SS_TAP(X_HOME)"LO"); - -これは "VE" に続けて `KC_HOME` をタップ、そして "LO" (新しい行の場合は "LOVE" と綴る)を送信します。 - -文字列に遅延を追加することもできます: - -* `SS_DELAY(msecs)` は指定されたミリ秒だけ遅らせます。 - -例えば: - - SEND_STRING("VE" SS_DELAY(1000) SS_TAP(X_HOME) "LO"); - -これは "VE" 、1秒の遅延、`KC_HOME` をタップ、"LO" (新しい行の場合は "LOVE" と綴るが、中間に遅延がある) を送信します。 - -使用できるモッドショートカットもいくつかあります: - -* `SS_LCTL(文字列)` -* `SS_LSFT(文字列)` -* `SS_LALT(文字列)`、`SS_LOPT(文字列)` -* `SS_LGUI(文字列)`、`SS_LCMD(文字列)`、`SS_LWIN(文字列)` -* `SS_RCTL(文字列)` -* `SS_RSFT(文字列)` -* `SS_RALT(文字列)`、`SS_ROPT(文字列)`、`SS_ALGR(文字列)` -* `SS_RGUI(文字列)`、`SS_RCMD(文字列)`、`SS_RWIN(文字列)` - -これらはそれぞれの修飾キーを押し、指定された文字列を送信してから、修飾キーを解放します。 -それらは以下のように使うことができます: - - SEND_STRING(SS_LCTL("a")); - -これは、左 Control +`a` (左 Control をダウンし、`a`、左 Control をアップ)を送信します - それらは文字列(例えば `"k"`)であり、`X_K` キーコードでは無いことに注意してください。 - -### 代替キーマップ - -デフォルトでは、QWERTY レイアウトの US キーマップを想定しています; それを変更したい場合(例えば OS がソフトウェア Colemak を使う場合)、キーマップのどこかに以下を含めます: - -```c -#include "sendstring_colemak.h" -``` - -### メモリ内の文字列 - -何らかの理由で文字列を操作していて、(リテラル、文字列定数の代わりに)生成したばかりのものを出力する必要がある場合は、以下のように `send_string()` を使うことができます: - -```c -char my_str[4] = "ok."; -send_string(my_str); -``` - -上で定義したショートカットは `send_string()` では動作しないですが、必要に応じて別の行に分けることができます: - -```c -char my_str[4] = "ok."; -SEND_STRING("I said: "); -send_string(my_str); -SEND_STRING(".."SS_TAP(X_END)); -``` - - -## 高度なマクロ関数 :id=advanced-macro-functions - -マクロの生成に役立つ関数が幾つかあります。マクロの中にかなり高度なコードを書くことができますが、機能が複雑になりすぎる場合は、代わりにカスタムキーコードを定義することをお勧めします。マクロはシンプルにしなければなりません。 - -?> 追加の機能として、[便利な関数](ja/ref_functions.md) の中で説明される関数を使うこともできます。例えば `reset_keyboard()` によりマクロの一部としてキーボードをリセットすることができます。 - -### `record->event.pressed` - -これでスイッチが押されているか放されているかどうかをテストすることができます。以下が例です。 - -```c - if (record->event.pressed) { - // キーダウン時 - } else { - // キーアップ時 - } -``` - -### `register_code();` - -これはコンピュータに `` キーダウンイベントを送信します。例として `KC_ESC`、`KC_C`、`KC_4` や、`KC_LSFT` と `KC_LGUI` のような修飾キーなどもあります。 - -### `unregister_code();` - -`register_code` 関数と対応して、これは `` キーアップイベントをコンピュータに送信します。これを使わない場合、キーは送信されるまで押し続けられます。 - -### `tap_code();` - -これは `register_code()` を送信し、その後 `unregister_code()` を送信します。押下とリリースイベントの両方を送信する場合に便利です (押し続けるのではなく、キーを"タップ"する)。 - -タップの登録(解除)に問題がある場合、`config.h` ファイルで `#define TAP_CODE_DELAY 100` を設定することで、登録イベントと解除イベントの間に遅延を追加することができます。値はミリ秒です。 - -### `register_code16();`、`unregister_code16();`、`tap_code16();` - -これらの関数は対応する通常の関数と同様に機能しますが、修飾キーで修飾されたキーコードを使うことができます (Shift、Alt、Control、GUI を適用)。 - -例えば、修飾キーを押して(`register_code()`して)、キーコードを押す(`register_code()`する)代わりに、`register_code16(S(KC_5));` を使うことができます。 - -### `clear_keyboard();` - -これは現在押されている全ての修飾キーとキーをクリアします。 - -### `clear_mods();` - -これは現在押されている全ての修飾キーをクリアします。 - -### `clear_keyboard_but_mods();` - -これは現在押されている修飾キー以外の全てのキーをクリアします。 - -## 高度な例: - -### スーパー ALT↯TAB - -このマクロは `KC_LALT` を登録し、`KC_TAB` をタップして、1000ms 待ちます。キーが再度タップされると、別の `KC_TAB` が送信されます; タップが無い場合、`KC_LALT` が登録解除され、ウィンドウを切り替えることができます。 - -```c -bool is_alt_tab_active = false; // keymap.c の先頭付近にこれを追加します -uint16_t alt_tab_timer = 0; // すぐにそれらを使います - -enum custom_keycodes { // 素晴らしいキーコードを用意してください - ALT_TAB = SAFE_RANGE, -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { // これはキーコードを利用したつまらない作業のほとんどを行います。 - case ALT_TAB: - if (record->event.pressed) { - if (!is_alt_tab_active) { - is_alt_tab_active = true; - register_code(KC_LALT); - } - alt_tab_timer = timer_read(); - register_code(KC_TAB); - } else { - unregister_code(KC_TAB); - } - break; - } - return true; -} - -void matrix_scan_user(void) { // とても重要なタイマー - if (is_alt_tab_active) { - if (timer_elapsed(alt_tab_timer) > 1000) { - unregister_code(KC_LALT); - is_alt_tab_active = false; - } - } -} -``` diff --git a/docs/ja/feature_mouse_keys.md b/docs/ja/feature_mouse_keys.md deleted file mode 100644 index e4fa9dfb456a..000000000000 --- a/docs/ja/feature_mouse_keys.md +++ /dev/null @@ -1,147 +0,0 @@ -# マウスキー - - - -マウスキーは、キーボードを使ってマウスをエミュレートできる機能です。様々な速度でポインタを移動し、5つのボタンを押し、8方向にスクロールすることができます。 - -## キーボードにマウスキーを追加 - -マウスキーを使うためには、少なくともマウスキーサポートを有効にし、マウスアクションをキーボードのキーにマップする必要があります。 - -### マウスキーを有効にする - -マウスキーを有効にするには、キーマップの `rules.mk` に以下の行を追加します: - -```c -MOUSEKEY_ENABLE = yes -``` - -### マウスアクションのマッピング - -キーマップでキー押下をマウスアクションにマップするために、以下のキーコードを使うことができます: - -| キー | エイリアス | 説明 | -|----------------|---------|-----------------| -| `KC_MS_UP` | `KC_MS_U` | カーソルを上に移動 | -| `KC_MS_DOWN` | `KC_MS_D` | カーソルを下に移動 | -| `KC_MS_LEFT` | `KC_MS_L` | カーソルを左に移動 | -| `KC_MS_RIGHT` | `KC_MS_R` | カーソルを右に移動 | -| `KC_MS_BTN1` | `KC_BTN1` | ボタン1を押す | -| `KC_MS_BTN2` | `KC_BTN2` | ボタン2を押す | -| `KC_MS_BTN3` | `KC_BTN3` | ボタン3を押す | -| `KC_MS_BTN4` | `KC_BTN4` | ボタン4を押す | -| `KC_MS_BTN5` | `KC_BTN5` | ボタン5を押す | -| `KC_MS_BTN6` | `KC_BTN6` | ボタン6を押す | -| `KC_MS_BTN7` | `KC_BTN7` | ボタン7を押す | -| `KC_MS_BTN8` | `KC_BTN8` | ボタン8を押す | -| `KC_MS_WH_UP` | `KC_WH_U` | ホイールを向こう側に回転 | -| `KC_MS_WH_DOWN` | `KC_WH_D` | ホイールを手前側に回転 | -| `KC_MS_WH_LEFT` | `KC_WH_L` | ホイールを左に倒す | -| `KC_MS_WH_RIGHT` | `KC_WH_R` | ホイールを右に倒す | -| `KC_MS_ACCEL0` | `KC_ACL0` | 速度を0に設定 | -| `KC_MS_ACCEL1` | `KC_ACL1` | 速度を1に設定 | -| `KC_MS_ACCEL2` | `KC_ACL2` | 速度を2に設定 | - -## マウスキーの設定 - -マウスキーはカーソルを移動するための3つの異なるモードをサポートします: - -* **加速 (デフォルト):** 移動キーを押したままにすると、カーソルが最大速度に達するまでカーソルを加速します。 -* **定速:** 移動キーを押したままにすると、カーソルを一定の速度で移動します。 -* **混合:** 移動キーを押したままにすると、カーソルが最大速度に達するまでカーソルを加速し、加速キーと移動キーを同時に押すとカーソルは一定の速度で移動します。 - -同じ原則がスクロールにも適用されます。 - -時間、間隔、遅延の設定オプションは、ミリ秒で指定されます。スクロール速度はデフォルトスクロールステップの倍数として渡されます。例えば、スクロール速度8は、各スクロールアクションがオペレーティングシステムまたはアプリケーションで定義されるデフォルトのスクロールステップの8倍の距離進むことを意味します。 - -### 加速モード - -これはデフォルトのモードです。キーマップの `config.h` ファイルの以下の設定を使ってカーソルとスクロールの加速を調整することができます: - -| 定義 | デフォルト | 説明 | -|----------------------------|-------|---------------------------------------------------------| -| `MOUSEKEY_DELAY` | 300 | 移動キーを押してからカーソルが移動するまでの遅延 | -| `MOUSEKEY_INTERVAL` | 50 | カーソル移動間の時間 | -| `MOUSEKEY_MAX_SPEED` | 10 | 加速が停止する最大のカーソル速度 | -| `MOUSEKEY_TIME_TO_MAX` | 20 | 最大カーソル速度に達するまでの時間 | -| `MOUSEKEY_WHEEL_DELAY` | 300 | ホイールキーを押してからホイールが動くまでの遅延 | -| `MOUSEKEY_WHEEL_INTERVAL` | 100 | ホイールの動きの間の時間 | -| `MOUSEKEY_WHEEL_MAX_SPEED` | 8 | スクロールアクションごとのスクロールステップの最大数 | -| `MOUSEKEY_WHEEL_TIME_TO_MAX` | 40 | 最大スクロール速度に達するまでの時間 | - -ヒント: - -* `MOUSEKEY_DELAY` の設定が低すぎるとカーソルが応答しなくなります。設定が高すぎると小さな動きが難しくなります。 -* カーソルの動きをスムーズにするには、`MOUSEKEY_INTERVAL` の値を低くします。ディスプレイのリフレッシュレートが60Hzの場合、`16` (1/60) に設定することができます。これによりカーソルの速度が大幅に向上するため、`MOUSEKEY_MAX_SPEED` を下げた方が良いかもしれません。 -* `MOUSEKEY_TIME_TO_MAX` または `MOUSEKEY_WHEEL_TIME_TO_MAX` を `0` に設定すると、それぞれカーソルの速度またはスクロールの加速が無効になります。この方法では、一方を加速しながら他方を一定にすることができますが、これは定速モードでは不可能です。 -* `MOUSEKEY_WHEEL_INTERVAL` の設定が低すぎるとスクロールがとても速くなります。設定が高すぎるとホイールキーを押したままにした時にスクロールがとても遅くなります - -カーソルの加速は、X Window System MouseKeysAccel 機能と同じアルゴリズムを使います。詳細については [Wikipedia](https://en.wikipedia.org/wiki/Mouse_keys) をご覧ください。 - -### 定速モード - -このモードでは、カーソルおよびマウスホイールの両方について複数の異なる速度を定義することができます。加速はありません。`KC_ACL0`、`KC_ACL1` および `KC_ACL2` は、カーソルとスクロールの速度をそれぞれの設定に変更します。 - -速度の選択は、一時的とタップ選択のどちらかを選べます: - -* **一時的:** 選択された速度は、それぞれのキーを押している間のみアクティブになります。キーを放すと、マウスキーは変更される前の速度に戻ります。 -* **タップ選択:** それぞれのキーを押すと選択された速度がアクティブになり、キーを放した後もアクティブのままになります。デフォルトの速度は `KC_ACL1` です。未変更の速度はありません。 - -最も遅い速度から最も速い速度までのデフォルトの速度は以下の通りです: - -* **一時的:** `KC_ACL0` < `KC_ACL1` < *変更無し* < `KC_ACL2` -* **タップ選択:** `KC_ACL0` < `KC_ACL1` < `KC_ACL2` - -定速モードを使うには、少なくともキーマップの keymaps ディレクトリの `config.h` ファイルに `MK_3_SPEED` を定義する必要があります。 - -```c -#define MK_3_SPEED -``` - -一時的モードを有効にするには、`MK_MOMENTARY_ACCEL` も定義します: - -```c -#define MK_MOMENTARY_ACCEL -``` - -カーソル移動あるいはスクロールを調整する場合は、以下の設定を使います: - -| 定義 | デフォルト | 説明 | -|---------------------|-------------|-------------------------------------------| -| `MK_3_SPEED` | *定義なし* | 定速カーソルを有効にする | -| `MK_MOMENTARY_ACCEL` | *定義なし* | 一時的モードを有効にする | -| `MK_C_OFFSET_UNMOD` | 16 | 移動ごとのカーソルオフセット (変更無し) | -| `MK_C_INTERVAL_UNMOD` | 16 | カーソルの移動間の時間 (変更無し) | -| `MK_C_OFFSET_0` | 1 | 移動ごとのカーソルオフセット (`KC_ACL0`) | -| `MK_C_INTERVAL_0` | 32 | カーソル移動間の時間 (`KC_ACL0`) | -| `MK_C_OFFSET_1` | 4 | 移動ごとのカーソルオフセット (`KC_ACL1`) | -| `MK_C_INTERVAL_1` | 16 | カーソル移動間の時間 (`KC_ACL1`) | -| `MK_C_OFFSET_2` | 32 | 移動ごとのカーソルオフセット (`KC_ACL2`) | -| `MK_C_INTERVAL_2` | 16 | カーソル移動間の時間 (`KC_ACL2`) | -| `MK_W_OFFSET_UNMOD` | 1 | スクロールアクションごとのスクロールステップ (変更無し) | -| `MK_W_INTERVAL_UNMOD` | 40 | スクロールステップ間の時間 (変更無し) | -| `MK_W_OFFSET_0` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL0`) | -| `MK_W_INTERVAL_0` | 360 | スクロールステップ間の時間 (`KC_ACL0`) | -| `MK_W_OFFSET_1` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL1`) | -| `MK_W_INTERVAL_1` | 120 | スクロールステップ間の時間 (`KC_ACL1`) | -| `MK_W_OFFSET_2` | 1 | スクロールアクションごとのスクロールステップ (`KC_ACL2`) | -| `MK_W_INTERVAL_2` | 20 | スクロールステップ間の時間 (`KC_ACL2`) | - -### 混合モード - -このモードは **加速** モードのように機能しますが、`KC_ACL0`、`KC_ACL1`、`KC_ACL2` を押したままにすることで -一時的(押している間)にカーソルとスクロール速度を定速に設定できます。 -加速キーが押されていない場合、このモードは **加速** モードと同じで、関連する全ての設定を使って変更できます。 - -* **KC_ACL0:** この加速はカーソルをできるだけ遅い速度に設定します。これはカーソルを非常に小さく詳細に移動する場合に便利です。 -* **KC_ACL1:** この加速はカーソルを最大(ユーザ定義)速度の半分に設定します。 -* **KC_ACL2:** この加速はカーソルを最大(コンピュータ定義)速度に設定します。これは、正確性を多少犠牲にしてカーソルを大きく移動する場合に便利です。 - -混合モードを使うには、キーマップの `config.h` ファイルに少なくとも `MK_COMBINED` を定義しなければなりません: - -```c -#define MK_COMBINED -``` diff --git a/docs/ja/feature_pointing_device.md b/docs/ja/feature_pointing_device.md deleted file mode 100644 index 0f472f0ffe76..000000000000 --- a/docs/ja/feature_pointing_device.md +++ /dev/null @@ -1,58 +0,0 @@ -# ポインティングデバイス :id=pointing-device - - - -ポインティングデバイスは汎用的な機能の総称です: システムポインタを移動します。マウスキーのような他のオプションも確かにありますが、これは簡単に変更可能で軽量であることを目指しています。機能を制御するためにカスタムキーを実装したり、他の周辺機器から情報を収集してここに直接挿入したりできます - QMK に処理を任せてください。 - -ポインティングデバイスを有効にするには、rules.mk の以下の行のコメントを解除します: - -```makefile -POINTING_DEVICE_ENABLE = yes -``` - -マウスレポートを操作するために、以下の関数を使うことができます: - -* `pointing_device_get_report()` - ホストコンピュータに送信された情報を表す現在の report_mouse_t を返します。 -* `pointing_device_set_report(report_mouse_t mouse_report)` - ホストコンピュータに送信される report_mouse_t を上書き保存します。 - -report_mouse_t (ここでは "mouseReport") が以下のプロパティを持つことを覚えておいてください: - -* `mouseReport.x` - これは、x軸の動き(+ 右へ、- 左へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 -* `mouseReport.y` - これは、y軸の動き(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 -* `mouseReport.v` - これは、垂直スクロール(+ 上へ、- 下へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 -* `mouseReport.h` - これは、水平スクロール(+ 右へ、- 左へ)を表す -127 から 127 (128ではなく、USB HID 仕様で定義されています)の符号付き整数です。 -* `mouseReport.buttons` - これは uint8_t で、8ビット全てを使っています。これらのビットはマウスボタンの状態を表します - ビット 0 はマウスボタン 1、ビット 7 はマウスボタン 8 です。 - -マウスレポートに必要な変更を行ったら、それを送信する必要があります: - -* `pointing_device_send()` - マウスレポートをホストに送信し、レポートをゼロにします。 - -マウスレポートが送信されると、x、y、v、h のいずれの値も 0 に設定されます (これは `pointing_device_send()` で行われます。この挙動を回避するためにオーバーライドすることができます)。このように、ボタンの状態は持続しますが、動きは1度だけ起こります。さらにカスタマイズするために、`pointing_device_init` と `pointing_device_task` のどちらもオーバーライドすることができます。 - -さらに、デフォルトでは、`pointing_device_send()` はレポートが実際に変更された場合のみレポートを送信します。これにより、マウスレポートが継続的に送信されてホストシステムが起動されたままになることを防ぎます。この動作は、独自の `pointing_device_send()` 関数を作成することで変更できます。 - -また、`has_mouse_report_changed(new_report, old_report)` 関数を使って、レポートが変更されたかどうかを確認できます。(訳注:独自の `pointing_device_send()` 関数を作成する場合でも、その中で `has_mouse_report_changed(new_report, old_report)` 関数でチェックして、デフォルトの `pointing_device_send()` と類似の無駄なレポートの抑制をして、ホストシステムがスリープ状態に入れる余地を残すようにしておくのが良いでしょう。) - -以下の例では、カスタムキーを使ってマウスをクリックし垂直および水平方向に127単位スクロールし、リリースされた時にそれを全て元に戻します - なぜならこれは完全に便利な機能だからです。いいですか、以下はひとつの例です: - -```c -case MS_SPECIAL: - report_mouse_t currentReport = pointing_device_get_report(); - if (record->event.pressed) { - currentReport.v = 127; - currentReport.h = 127; - currentReport.buttons |= MOUSE_BTN1; // this is defined in report.h - } else { - currentReport.v = -127; - currentReport.h = -127; - currentReport.buttons &= ~MOUSE_BTN1; - } - pointing_device_set_report(currentReport); - pointing_device_send(); - break; -``` - -マウスレポートは送信されるたびに 0 (ボタンを除く)に設定されることを思い出してください。そのため、スクロールはそれぞれの場合に1度だけ発生します。 diff --git a/docs/ja/feature_ps2_mouse.md b/docs/ja/feature_ps2_mouse.md deleted file mode 100644 index 2798f612830b..000000000000 --- a/docs/ja/feature_ps2_mouse.md +++ /dev/null @@ -1,288 +0,0 @@ -# PS/2 マウスサポート :id=ps2-mouse-support - - - -PS/2 マウス (例えばタッチパッドあるいはトラックポイント)を複合デバイスとしてキーボードに接続することができます。 - -トラックポイントを接続するには、トラックポイントモジュールを入手し (つまり、Thinkpad キーボードから部品を取って)、モジュールの各ピンの機能を特定し、コントローラとトラックポイントモジュールの間に必要な回路を作成する必要があります。詳細については、Deskthority Wiki の[トラックポイントハードウェア](https://deskthority.net/wiki/TrackPoint_Hardware)ページを参照してください。 - -PS/2 デバイスの接続は、USART(最善)、割り込み(次善)、 または busywait(非推奨)の3つのやり方が有ります。 - -## トラックポイントとコントローラ間の回路 :id=the-circuitry-between-trackpoint-and-controller - -動作させるには、DATA と CLK のふたつのラインを 4.7k の抵抗で 5V にプルアップしてやる必要があります。 - -``` - DATA ----------+--------- PIN - | - 4.7K - | -MODULE 5+ --------+--+--------- PWR CONTROLLER - | - 4.7K - | - CLK ------+------------ PIN -``` - - -## Busywait バージョン :id=busywait-version - -注意: これは非推奨です。ギクシャクした動きや、未送信の入力が発生するかもしれません。可能であれば、割り込みまたは USART バージョンを使ってください。 - -rules.mk で: - -```makefile -PS2_MOUSE_ENABLE = yes -PS2_ENABLE = yes -PS2_DRIVER = busywait -``` - -キーボードの config.h で: - -```c -#ifdef PS2_DRIVER_BUSYWAIT -# define PS2_CLOCK_PIN D1 -# define PS2_DATA_PIN D2 -#endif -``` - -## 割り込みバージョン :id=interrupt-version - -以下の例はクロックのために D2 を、データのために D5 を使います。クロックには任意の INT あるいは PCINT ピンを、データには任意のピンを使うことができます。 - -rules.mk で: - -```makefile -PS2_MOUSE_ENABLE = yes -PS2_ENABLE = yes -PS2_DRIVER = interrupt -``` - -キーボードの config.h で: - -```c -#ifdef PS2_DRIVER_INTERRUPT -#define PS2_CLOCK_PIN D2 -#define PS2_DATA_PIN D5 - -#define PS2_INT_INIT() do { \ - EICRA |= ((1< - -Raw HID は、HID インタフェースを介して QMK とホストコンピュータ間の双方向通信を可能にします。これには、キーマップをその場で切り替えたり、RGB LED の色とモードを変更したりなど、多くの潜在的な使用方法があります。 - -キーボードで raw HID を機能させるには、2つの主要なコンポーネントがあります。 - -## キーボードファームウェア - -ファームウェアの実装はとても簡単です。 -`rules.mk` に以下を追加します: - -```make -RAW_ENABLE = yes -``` - -`keymap.c` に `"raw_hid.h"` を include し、以下を実装します: - -```C -void raw_hid_receive(uint8_t *data, uint8_t length) { - // ここにコードを書きます。data はホストから受信したパケットです。 -} -``` - -`"raw_hid.h"` ヘッダは、キーボードからホストにパケットを送信できる `void raw_hid_send(uint8_t *data, uint8_t length);` も宣言します。例として、全てのデータをホストに返すことで、ホストアプリケーションを構築する時のデバッグに使うこともできます。 - -```C -void raw_hid_receive(uint8_t *data, uint8_t length) { - raw_hid_send(data, length); -} -``` - -これら2つの関数は、ホストとの間で長さ `RAW_EPSIZE` バイトのパケットを送受信します (LUFA/ChibiOS/V-USB では 32、ATSAM では 64)。 - -ホスト側での作業を進める前に、raw 対応のファームウェアを書き込むようにしてください。 - -## ホスト (Windows/macOS/Linux) - -これは幾つかの掘り下げが必要になるため、より複雑な部分です。 - -ホストコンピュータを raw HID を使ってキーボードに接続するには、キーボードについての4つの情報が必要です。 - -1. Vendor ID -2. Product ID -3. Usage Page -4. Usage - -前半の2つは、キーボードのメインディレクトリにあるキーボードの `config.h` で、`VENDOR_ID` と `PRODUCT_ID` で簡単に見つかります。 - -後半の2つは、キーボードのメインディレクトリにあるキーボードの `config.h` で、値を再定義することで上書きすることができます: `#define RAW_USAGE_PAGE 0xFF60` と `#define RAW_USAGE_ID 0x61`。 - -デフォルトでは、**Usage Page** は `0xFF60` で、**Usage** は `0x61` です。 - -### ホストの構築 - -独自に作成したくない場合は、利用可能な HID 実装ライブラリがある任意の言語を使ってホストを構築することができます。人気のある言語でよく使われるライブラリは以下の通りです: - -* Node: [node-hid](https://github.com/node-hid/node-hid)。 -* C: [hidapi](https://github.com/libusb/hidapi)。 -* Java: [purejavahidapi](https://github.com/nyholku/purejavahidapi) と [hid4java](https://github.com/gary-rowe/hid4java)。 -* Python: [pyhidapi](https://pypi.org/project/hid/)。 - -これは完全なクロスプラットフォームのリストではありませんが、最初に始めるのに十分なはずです。raw HID を使うための特別な要件は無いため、どの HID ライブラリでも動作するはずです。 - -これで、キーボードへの HID インタフェースを開くために必要な4つの情報全てが揃いました。必要なのは、ライブラリの利用可能な関数を使って ID パラメータを使ってデバイスを開くことだけです。 - -Vendor ID と Product ID はデバイスを開くために実際には必要ないことに注意してください。それらは接続した多くの HID デバイスから特定のデバイスをフィルターするためだけに使われます。多くのライブラリでは、代わりに製品名と製造元名を使ってデバイスを開くオプションがあります。`node-hid` が代表的な例です。これは USB ハブが組み込まれているデバイスや、同じ製品名または同じ製造元の複数のインタフェースがある特別な HID インタフェースで問題になります。Product ID と Vendor ID を合わせると単一のインタフェースの固有名を作成できるため、この問題を防げます。したがって、ライブラリで必要が無い場合でも、この問題を防ぐためにそれらを使うことをお勧めします。 -ただし、Vendor ID や Product ID と異なり、Usage Page と Usage は通信を成功させるために必要です。 - -言うまでもなく、使っているライブラリに関係なく、終了したらインタフェースを必ず閉じる必要があります。オペレーティングシステムと特定の環境によっては、明示的に接続が閉じられていない場合、後で他のクライアントまたは同じクライアントの他のインスタンスに接続しなおした時に問題が発生する可能性があります。 diff --git a/docs/ja/feature_split_keyboard.md b/docs/ja/feature_split_keyboard.md deleted file mode 100644 index 3bdf96d1c7d1..000000000000 --- a/docs/ja/feature_split_keyboard.md +++ /dev/null @@ -1,251 +0,0 @@ -# 分割キーボード - - - -QMK ファームウェアリポジトリの多くのキーボードは、"分割"キーボードです。それらは2つのコントローラを使います — 1つは USB に接続し、もう1つは TRRS または同様のケーブルを介してシリアルまたは I2C 接続で接続します。 - -分割キーボードには多くの利点がありますが、有効にするには追加の作業が必要です。 - -QMK ファームウェアには、任意のキーボードで使用可能な一般的な実装と、多くのキーボード固有の実装があります。 - -このため、主に Let's Split とその他のキーボードで使われる一般的な実装について説明します。 - -!> ARM はまだ完全には分割キーボードをサポートしておらず、様々な制限があります。進捗はしていますが、機能の100%にはまだ達していません。 - - -## 互換性の概要 - -| Transport | AVR | ARM | -|------------------------------|--------------------|--------------------| -| ['serial'](ja/serial_driver.md) | :heavy_check_mark: | :white_check_mark: 1 | -| I2C | :heavy_check_mark: | | - -注意: - -1. ハードウェアとソフトウェアの両方の制限は、[ドライバーのドキュメント](ja/serial_driver.md)の中で説明されます。 - -## ハードウェア設定 - -2つの Pro Micro 互換のコントローラを使っており、キーボードの左右を接続するために TRRS ジャックを使っていることを前提とします。 - -### ハードウェア要件 - -左右それぞれのキーボードマトリックスのためのダイオードとスイッチとは別に、2個の TRRS ソケットと 1本の TRRS ケーブルが必要です。 - -あるいは、少なくとも3本のワイヤがあるケーブルとソケットを使うことができます。 - -キーボードの左右間で通信するために I2C を使いたい場合は、少なくとも4本のワイヤを備えたケーブルと 2個の 4.7kΩ プルアップ抵抗が必要です。 - -#### 考慮事項 - -最も一般的に使われる接続は、TRRS ケーブルとジャックです。これらは4本のワイヤを提供し、分割キーボードに非常に有用で、簡単に見つけることができます。 - -ただし、ワイヤのうちの1本が Vcc を供給するため、キーボードはホットプラグ不可能です。TRRS ケーブルを抜き差しする前に、必ずキーボードのUSB接続をはずす必要があります。そうしなければ、コントローラを短絡させたり、もっと悪いことが起こるかもしれません。 - -別のオプションは電話ケーブルを使うことです (例えば、旧式の RJ-11/RJ-14 ケーブル)。実際に4本のワイヤ/レーンをサポートするものを使うようにしてください。 - -ただし、USB ケーブル、SATA ケーブル、そして単に4本の電線でもコントローラ間の通信に使用できることがわかっています。 - -!> コントローラ間の通信に USB ケーブルを使っても問題ありませんが、コネクタは通常の USB 接続と間違えられるかもしれず、配線方法によってはキーボードが短絡する可能性があります。このため、分割キーボードの接続のためにはお勧めできません。 - -### シリアル配線 - -2つの Pro Micro 間で GND、Vcc、D0/D1/D2/D3 (別名 PD0/PD1/PD2/PD3) を TRS/TRRS ケーブルの3本のワイヤで接続します。 - -?> ここで使われるピンは実際には以下の `SOFT_SERIAL_PIN` によって設定されることに注意してください。 - -sk-pd0-connection-mono -sk-pd2-connection-mono - -### I2C 配線 - -2つの Pro Micro 間で GND、Vcc、さらに SCL と SDA (それぞれ 別名 PD0/ピン3 および PD1/ピン2) を TRRS ケーブルの4本のワイヤで接続します。 - -プルアップ抵抗はキーボードの左右どちら側にも配置することができます。もし各側を単独で使いたい場合は、4つの抵抗を使い、両側にプルアップ抵抗を配置することもできます。 - -sk-i2c-connection-mono - -## ファームウェア設定 - -分割キーボード機能を有効にするには、以下を `rules.mk` に追加してください: - -```make -SPLIT_KEYBOARD = yes -``` - -カスタムトランスポート (通信メソッド)を使っている場合は、以下を追加する必要もあります: - -```make -SPLIT_TRANSPORT = custom -``` - -### 左右の設定 - -デフォルトでは、ファームウェアはどちら側がどちらであるかを認識しません; 決定するには幾つかの助けが必要です。これを行うには幾つかの方法があり、以下に優先順に列挙します。 - -#### ピンによる左右の設定 - -左右を決定するためにコントローラ上のピンを読むようにファームウェアを設定することができます。これを行うには、以下を `config.h` ファイルに追加します: - -```c -#define SPLIT_HAND_PIN B7 -``` - -これは指定されたピンを読み込みます。high の場合、コントローラはそれを左側だと仮定し、low の場合、それは右側であると仮定します。 - -#### マトリックスピンによる左右の設定 - -左右を決定するためにコントローラのキーマトリックスピンを読むようにファームウェアを設定することができます。これを行うには、以下を `config.h` ファイルに追加します: - -```c -#define SPLIT_HAND_MATRIX_GRID D0, F1 -``` - -最初のピンは出力ピンで、2つ目は入力ピンです。 - -キーマトリックスに未使用の交点があるキーボードがあります。この設定は、左右の決定にこれらの未使用の交点の1つを使用します。 - -通常、ダイオードが交点に接続されている場合、左側と判断されます。次の定義を追加すると、右側と判断されます。 - -```c -#define SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT -``` - -#### EEPROM による左右の設定 - -このメソッドは永続ストレージ(`EEPROM`)のフラグを設定することで、キーボードの左右を設定します。これはコントローラが最初に起動する時にチェックされ、キーボードのどちら側であるかとキーボードのレイアウトの向きを決定します。 - - -このメソッドを有効にするには、以下を `config.h` ファイルに追加します: - -```c -#define EE_HANDS -``` - -ただし、各コントローラに正しい側の EEPROM ファイルを書き込む必要があります。これを手動で行うこともできますが、ファームウェアを書き込む時にこれを行う avrdude および dfu のターゲットが存在します。 - -* `:avrdude-split-left` -* `:avrdude-split-right` -* `:dfu-split-left` -* `:dfu-split-right` -* `:dfu-util-split-left` -* `:dfu-util-split-right` - -この設定は、`EEP_RST` キーや `eeconfig_init()` 関数を使って EEPROM を再初期化する時には変更されません。ただし、ファームウェアの組み込みオプション以外で EEPROM をリセット([QMK Toolbox]() の "Reset EEPROM" ボタンの動作のように、`EEPROM` を上書きするファイルを書きこむなど)した場合、`EEPROM` ファイルを再書き込みする必要があります。 - -`EEPROM` ファイルは、QMK ファームウェアのリポジトリ内の[ここ](https://github.com/qmk/qmk_firmware/tree/master/quantum/split_common)にあります。 - -#### `#define` による左右の設定 - -コンパイル時に左右を設定することができます。これは以下を `config.h` ファイルに追加することで行うことができます: - -```c -#define MASTER_RIGHT -``` - -あるいは - -```c -#define MASTER_LEFT -``` - -どちらも定義されていない場合、左右のデフォルトは `MASTER_LEFT` になります。 - - -### 通信オプション - -全ての分割キーボードが同一であるとは限らないため、`config.h` ファイル内で設定することができる多くの追加のオプションがあります。 - -```c -#define USE_I2C -``` - -これは分割キーボードの I2C サポートを有効にします。これは厳密には通信用ではありませんが、OLED あるいは I2C ベースのデバイスに使うことができます。 - -```c -#define SOFT_SERIAL_PIN D0 -``` - -これはシリアル通信用に使われるピンを設定します。シリアルを使っていない場合は、これを定義する必要はありません。 - -ただし、キーボード上でシリアルおよび I2C を使っている場合は、これを設定し、D0 および D1 以外の値に設定する必要があります (これらは I2C 通信のために使われます)。 - -```c -#define SELECT_SOFT_SERIAL_SPEED {#}` -``` - -シリアル通信に問題がある場合は、この値を変更して、シリアル用の通信速度を制御することができます。デフォルトは1で、可能な値は以下の通りです: - -* **`0`**: 約189kbps (実験用途専用) -* **`1`**: 約137kbps (デフォルト) -* **`2`**: 約75kbps -* **`3`**: 約39kbps -* **`4`**: 約26kbps -* **`5`**: 約20kbps - -### ハードウェア設定オプション - -ハードウェアのセットアップ方法に基づいて、設定する必要のある設定が幾つかあります。 - -```c -#define MATRIX_ROW_PINS_RIGHT { } -#define MATRIX_COL_PINS_RIGHT { } -``` - -これにより、右側のマトリックスに異なるピンのセットを指定することができます。これは、左右の形が違うキーボード (Keebio の Quefrency など)で、左右で別の構成が必要な場合に便利です。 - -```c -#define DIRECT_PINS_RIGHT { { F1, F0, B0, C7 }, { F4, F5, F6, F7 } } -``` - -これにより右側のための異なる直接ピンのセットを指定することができます。 - -```c -#define ENCODERS_PAD_A_RIGHT { encoder1a, encoder2a } -#define ENCODERS_PAD_B_RIGHT { encoder1b, encoder2b } -``` - -これにより右側のための異なるエンコーダピンのセットを指定することができます。 - -```c -#define RGBLIGHT_SPLIT -``` - -このオプションは、分割キーボードのコントローラ間で RGB ライトモードの同期を有効にします。これはコントローラに直接配線されている RGB LED を持つキーボード用です (つまり、それらは TRRS ケーブルで "追加データ"オプションを使っていません)。 - -```c -#define RGBLED_SPLIT { 6, 6 } -``` - -これは各コントローラに直接接続されている LED の数を設定します。最初の数は左側、2番目の数は右側です。 - -?> この設定は `RGBLIGHT_SPLIT` が有効になっていることを意味し、有効になっていない場合は強制的に有効にします。 - - -```c -#define SPLIT_USB_DETECT -``` -このオプションは、スタートアップの挙動を変更して、マスタ/スレーブの決定時にアクティブな USB 接続を検出します。このオプションがタイムアウトになった場合、その片側はスレーブと見なされます。これは ARM のデフォルトの挙動で、AVR Teensy ボードに必要です (ハードウェアの制限のため)。 - -?> この設定はバッテリパックを使ったデモの機能を停止します。 - -```c -#define SPLIT_USB_TIMEOUT 2000 -``` -これは、`SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合の最大タイムアウトを設定します。 - -```c -#define SPLIT_USB_TIMEOUT_POLL 10 -``` -これは `SPLIT_USB_DETECT` を使う時のマスタ/スレーブを検出する場合のポーリング頻度を設定します - -## 追加のリソース(英語) - -Nicinabox には Let's Split キーボードのための[非常に優れた詳細なガイド](https://github.com/nicinabox/lets-split-guide)があり、トラブルシューティング情報を含む知っておくべきほとんど全てをカバーします。 - -ただし、RGB ライトセクションは、RGB Split コードが QMK ファームウェアに追加されるずっと前に書かれたため、古くなっています。ガイドに従う代わりに、各 LED テーブ(訳注: LED strip とも呼びます)を直接コントローラに配線します。 - - diff --git a/docs/ja/feature_stenography.md b/docs/ja/feature_stenography.md deleted file mode 100644 index 9551221696c2..000000000000 --- a/docs/ja/feature_stenography.md +++ /dev/null @@ -1,135 +0,0 @@ -# QMK での速記 :id=stenography-in-qmk - - - -[速記](https://en.wikipedia.org/wiki/Stenotype)は裁判所のレポート、字幕および耳が不自由な人のためのリアルタイムの文字起こしで最もよく使われる記述方法です。速記では単語はスペル、音声およびショートカット(短い)ストロークが混在する音節ごとに音節化されます。プロの速記者は、標準的なタイピングで通常見られる負担を掛けずに、はるかに少ないエラー(99.9%より高い精度)で、200-300 WPM に到達できます。 - -[Open Steno Project](https://www.openstenoproject.org/)は、速記ストロークを単語とコマンドにリアルタイムに変換する Plover と呼ばれるオープンソースプログラムを構築しました。確立された辞書とサポートがあります。 - -## QWERTY キーボードを使った Plover :id=plover-with-qwerty-keyboard - -Plover は全ての標準的な QWERTY キーボードで動作しますが、キーボードが NKRO (n-キーロールオーバー)をサポートする場合は Plover は一度に押された全てのキーが分かるためより効率的です。Plover 用のキーマップの例は `planck/keymaps/default` で見つかります。`PLOVER` レイヤーに切り替えると、数字バーをサポートするためにキーボードの位置が調整されます。 - -QMK で Plover を使うには、NKRO を有効にし、標準レイアウト以外のレイアウトの場合はオプションでレイアウトを調整します。複数のキーを押しやすくするために、なんらかの速記フレンドリなキーキャップを購入することもできます。 - -## 速記プロトコルを使った Plover :id=plover-with-steno-protocol - -Plover は幾つかの速記マシンの言語も理解します。QMK はこれらの言語の内2つの言語、TX Bolt と GeminiPR を話すことができます。レイアウトの例は `planck/keymaps/steno` で見つけることができます。 - -QMKが steno プロトコルを使って Plover と話す場合は、Plover は入力としてキーボードを使いません。標準のキーボードと速記キーボードを行き来したり、あるいは Plover をアクティブ/非アクティブにする必要なく Plover と標準のレイヤーを行き来することができることを意味します。 - -このモードでは、Plover はシリアルポートを介して速記マシンと通信すると想定しているため、QMK はオペレーティングシステムに対してキーボードに加えて仮想シリアルポートとして存在しています。デフォルトでは、QMK は TX Bolt プロトコルを話しますが、GeminiPR に切り替えることができます; 最後に使われたプロトコルが不揮発性メモリに格納されるため QMK は再起動時に同じプロトコルを使います。 - -> 注意: ハードウェアの制限により、仮想シリアルポートとマウスエミュレーションの両方を同時に実行することができないかもしれません。 - -### TX Bolt :id=tx-bolt - -TX Bolt は可変サイズ(1-5バイト)のパケットで非常に単純なプロトコルを介して24個のキーのステータスを通信します。 - -### GeminiPR :id=geminipr - -GeminiPR は42個のキーを6バイトのパケットにエンコードします。TX Bolt は標準的な速記に必要な全てを含んでいますが、GeminiPR は英語以外の速記法のサポートを含む、より多くのオプションにも開け放たれています。 - -## 速記のための QMK の設定 :id=configuring-qmk-for-steno - -最初にキーマップの Makefile で速記を有効にします。競合を避けるために、マウスキー、追加キーあるいはその他の USB エンドポイントを無効にする必要もあります。幾つかのプロセッサの内蔵の USB スタックは一定数の USB エンドポイントと仮想シリアルポートのみをサポートし、速記はそれらのうちの3つを使います。 - -```makefile -STENO_ENABLE = yes -MOUSEKEY_ENABLE = no -``` - -キーマップで Plover 用の新しいレイヤーを作成します。`keymap_steno.h` をインクルードする必要があります。例については `planck/keymaps/steno/keymap.c` を見てください。レイヤーに切り替えるためのキーとレイヤーから抜けるためのキーを作成することを忘れないでください。その場でモードを切り替えたい場合は、キーコード `QK_STENO_BOLT` および `QK_STENO_GEMINI` を使うことができます。プロトコルのうちの1つのみを使う場合は、初期化関数の中でそれをセットアップすることができます: - -```c -void eeconfig_init_user() { - steno_set_mode(STENO_MODE_GEMINI); // あるいは STENO_MODE_BOLT -} -``` - -キーボードを書き込んだら、Plover を起動します。'Configure...' ボタンをクリックします。'Machine' タブの中で目的のプロトコルに対応する速記マシンを選択します。このタブの 'Configure...' ボタンをクリックし、シリアルポートを入力するか 'Scan' をクリックします。ボーレートは 9600 で問題ありません (ただし、115200まで問題無く設定することができるはずです)。それ以外はデフォルトの設定(データビット長: 8、ストップビット長: 1、パリティチェック: なし、フロー制御なし)を使います。 - -ディスプレイタブで 'Open stroke display' をクリックします。Plover を無効にすると、キーボードのキーを押すとストローク表示ウィンドウにそれらが表示されるはずです。これを使ってキーマップが正しくセットアップされたことを確認してください。これで速記をする準備ができました! - -## 速記の学習 :id=learning-stenography - -* [Learn Plover!](https://sites.google.com/site/learnplover/) -* [Steno Jig](https://joshuagrams.github.io/steno-jig/) -* Plover [Learning Stenography](https://github.com/openstenoproject/plover/wiki/Learning-Stenography) wiki のより多くのリソース - -## コードとのインターフェイス :id=interfacing-with-the-code - -速記コードには3つの捕捉可能なフックがあります。これらの関数を定義した場合、処理の特定のポイントでそれらが呼び出されます; それらが true を返す場合処理が継続され、そうでなければあなたが物事を処理すると想定します。 - -```c -bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[6]); -``` - -この関数はコードが送信されようとしている時に呼ばれます。モードは `STENO_MODE_BOLT` あるいは `STENO_MODE_GEMINI` のいずれかです。これはいずれかのプロトコルを介して送信される実際のコードを表します。提供されるコードを修正して送信されるものを変更することができます。通常の送信プロセスにしたい場合は true を返すのを忘れないでください。 - -```c -bool process_steno_user(uint16_t keycode, keyrecord_t *record) { return true; } -``` - -この関数はキーが押されるとキーが処理される前に呼び出されます。キーコードは `QK_STENO_BOLT`、`QK_STENO_GEMINI` あるいは `STN_*` キー値のいずれかでなければなりません。 - -```c -bool post_process_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[6], int8_t pressed); -``` - -この関数はキーが処理された後、ただしコードを送信するかどうかを決める前に呼び出されます。`record->event.pressed` が false で、`pressed` が 0 または 1 の場合は、コードはまもなく送信されますが、まだ送信されてはいません。ここが速記コードあるいはキーのライブ表示などのフックを配置する場所です。 - - -## キーコードリファレンス :id=keycode-reference - -`keymap_steno.h` で定義されています。 - -> 注意: TX Bolt はキーの完全なセットをサポートしません。QMK での TX Bolt の実装は、GeminiPR キーを最も近い TX Bolt キーにマップします。そのため1つのキーマップが両方で動作します。 - -| GeminiPR | TX Bolt | Steno Key | -|--------|-------|-----------| -| `STN_N1` | `STN_NUM` | Number bar #1 | -| `STN_N2` | `STN_NUM` | Number bar #2 | -| `STN_N3` | `STN_NUM` | Number bar #3 | -| `STN_N4` | `STN_NUM` | Number bar #4 | -| `STN_N5` | `STN_NUM` | Number bar #5 | -| `STN_N6` | `STN_NUM` | Number bar #6 | -| `STN_N7` | `STN_NUM` | Number bar #7 | -| `STN_N8` | `STN_NUM` | Number bar #8 | -| `STN_N9` | `STN_NUM` | Number bar #9 | -| `STN_NA` | `STN_NUM` | Number bar #A | -| `STN_NB` | `STN_NUM` | Number bar #B | -| `STN_NC` | `STN_NUM` | Number bar #C | -| `STN_S1` | `STN_SL` | `S-` upper | -| `STN_S2` | `STN_SL` | `S-` lower | -| `STN_TL` | `STN_TL` | `T-` | -| `STN_KL` | `STN_KL` | `K-` | -| `STN_PL` | `STN_PL` | `P-` | -| `STN_WL` | `STN_WL` | `W-` | -| `STN_HL` | `STN_HL` | `H-` | -| `STN_RL` | `STN_RL` | `R-` | -| `STN_A` | `STN_A` | `A` vowel | -| `STN_O` | `STN_O` | `O` vowel | -| `STN_ST1` | `STN_STR` | `*` upper-left | -| `STN_ST2` | `STN_STR` | `*` lower-left | -| `STN_ST3` | `STN_STR` | `*` upper-right | -| `STN_ST4` | `STN_STR` | `*` lower-right | -| `STN_E` | `STN_E` | `E` vowel | -| `STN_U` | `STN_U` | `U` vowel | -| `STN_FR` | `STN_FR` | `-F` | -| `STN_PR` | `STN_PR` | `-P` | -| `STN_RR` | `STN_RR` | `-R` | -| `STN_BR` | `STN_BR` | `-B` | -| `STN_LR` | `STN_LR` | `-L` | -| `STN_GR` | `STN_GR` | `-G` | -| `STN_TR` | `STN_TR` | `-T` | -| `STN_SR` | `STN_SR` | `-S` | -| `STN_DR` | `STN_DR` | `-D` | -| `STN_ZR` | `STN_ZR` | `-Z` | -| `STN_FN` | (GeminiPR のみ) | -| `STN_RES1` | (GeminiPR のみ) | -| `STN_RES2` | (GeminiPR のみ) | -| `STN_PWR` | (GeminiPR のみ) | diff --git a/docs/ja/feature_swap_hands.md b/docs/ja/feature_swap_hands.md deleted file mode 100644 index cd0b150e5006..000000000000 --- a/docs/ja/feature_swap_hands.md +++ /dev/null @@ -1,36 +0,0 @@ -# スワップハンドアクション - - - -スワップハンドアクションにより、別のレイヤーを必要とせずに片手入力をサポートします。Makefile に `SWAP_HANDS_ENABLE` を設定し、キーマップに `hand_swap_config` エントリを定義します。これで `ACTION_SWAP_HANDS` コマンドキーが押されるたびにキーボードがミラーされます。例えば、QWERTY で "Hello, World" を入力するには、`^Ge^s^s^w^c W^wr^sd` を入力します。 - -## 設定 - -設定テーブルは列/行から新しい列/行にマップするための単純な2次元配列です。Planck の `hand_swap_config` の例: - -```C -const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS] = { - {{11, 0}, {10, 0}, {9, 0}, {8, 0}, {7, 0}, {6, 0}, {5, 0}, {4, 0}, {3, 0}, {2, 0}, {1, 0}, {0, 0}}, - {{11, 1}, {10, 1}, {9, 1}, {8, 1}, {7, 1}, {6, 1}, {5, 1}, {4, 1}, {3, 1}, {2, 1}, {1, 1}, {0, 1}}, - {{11, 2}, {10, 2}, {9, 2}, {8, 2}, {7, 2}, {6, 2}, {5, 2}, {4, 2}, {3, 2}, {2, 2}, {1, 2}, {0, 2}}, - {{11, 3}, {10, 3}, {9, 3}, {8, 3}, {7, 3}, {6, 3}, {5, 3}, {4, 3}, {3, 3}, {2, 3}, {1, 3}, {0, 3}}, -}; -``` - -配列のインデックスはマトリックスと同様に逆になり、値の型は `{col, row}` である `keypos_t` で、全ての値はゼロベースであることに注意してください。上の例では、`hand_swap_config[2][4]` (第3行, 第5列)は `{7, 2}` (第3行, 第8列) を返します。はい。紛らわしいです。 - -## キーコードの入れ替え - -| キー | 説明 | -|-----------|-------------------------------------------------------------------------| -| `SH_T(key)` | タップで `key` を送信する。押している時の一時的な入れ替え。 | -| `SH_ON` | 入れ替えをオンにして、そのままにする。 | -| `SH_OFF` | 入れ替えをオフにして、そのままにする。既知の状態に戻るのに適しています。 | -| `SH_MON` | 押すとスワップハンドし、放すと通常に戻る (一時的)。 | -| `SH_MOFF` | 一時的に入れ替えをオフする。 | -| `SH_TG` | キーを押すたびに入れ替えのオンとオフを切り替える。 | -| `SH_TT` | タップで切り替える。押されている時の一時的なもの。 | -| `SH_OS` | ワンショットスワップハンド: 押されている時あるいは次のキーを押すまで切り替える。 | diff --git a/docs/ja/feature_tap_dance.md b/docs/ja/feature_tap_dance.md deleted file mode 100644 index b4e025d2821e..000000000000 --- a/docs/ja/feature_tap_dance.md +++ /dev/null @@ -1,530 +0,0 @@ -# タップダンス: 1つのキーが3つ、5つまたは100の異なる動作をします - - - -## イントロダクション :id=introduction - -セミコロンキーを1回叩くと、セミコロンが送信されます。2回素早く叩くと、コロンが送信されます。3回叩くと、あなたのキーボードのLEDが激しく踊るように明滅します。これは、タップダンスでできることの一例です。それは、コミュニティが提案したとても素敵なファームウェアの機能の1つで、[algernon](https://github.com/algernon) がプルリクエスト [#451](https://github.com/qmk/qmk_firmware/pull/451) で考えて作ったものです。algernon が述べる機能は次の通りです: - -この機能を使うと、特定のキーが、タップした回数に基づいて異なる振る舞いをします。そして、割り込みがあった時は、割り込み前に上手く処理されます。 - -## タップダンスの使い方 :id=how-to-use -最初に、あなたの `rules.mk` ファイルで `TAP_DANCE_ENABLE = yes` と設定する必要があります。なぜならば、デフォルトでは無効になっているからです。これでファームウェアのサイズが1キロバイトほど増加します。 - -オプションで、あなたの `config.h` ファイルに次のような設定を追加して、`TAPPING_TERM` の時間をカスタマイズしたほうが良いです。 - -```c -#define TAPPING_TERM 175 -``` - -`TAPPING_TERM` の時間は、あなたのタップダンスのキーのタップとタップの間の時間として許可された最大の時間で、ミリ秒単位で計測されます。例えば、もし、あなたがこの上にある `#define` ステートメントを使い、1回タップすると `Space` が送信され、2回タップすると `Enter` が送信されるタップダンスキーをセットアップした場合、175ミリ秒以内に2回キーをタップすれば `ENT` だけが送信されるでしょう。もし、1回タップしてから175ミリ秒以上待ってからもう一度タップすると、`SPC SPC` が送信されます。 - -次に、いくつかのタップダンスのキーを定義するためには、`TD()` マクロを使うのが最も簡単です。これは数字を受け取り、この数字は後で `tap_dance_actions` 配列のインデックスとして使われます。 - -その後、`tap_dance_actions` 配列を使って、タップダンスキーを押した時のアクションを定義します。現在は、5つの可能なオプションがあります: - -* `ACTION_TAP_DANCE_DOUBLE(kc1, kc2)`: 1回タップすると `kc1` キーコードを送信し、2回タップすると `kc2` キーコードを送信します。キーを押し続けているときは、適切なキーコードが登録されます: キーを押し続けた場合は `kc1`、一度タップしてから続けてもう一度キーを押してそのまま押し続けたときは、 `kc2` が登録されます。 -* `ACTION_TAP_DANCE_LAYER_MOVE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` レイヤーに移動します(これは `TO` レイヤーキーコードのように機能します)。 -* `ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer)`: 1回タップすると `kc` キーコードが送信され、2回タップすると `layer` の状態をトグルします(これは `TG` レイヤーキーコードのように機能します)。 -* `ACTION_TAP_DANCE_FN(fn)`: ユーザーキーマップに定義した指定の関数が呼び出されます。タップダンス実行の回数分タップすると、最後の時点で呼び出されます。 -* `ACTION_TAP_DANCE_FN_ADVANCED(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn)`: タップする度にユーザーキーマップに定義した最初の関数が呼び出されます。タップダンスの実行が終わった時点で2番目の関数が呼び出され、タップダンスの実行をリセットするときに最後の関数が呼び出されます。 -* ~~`ACTION_TAP_DANCE_FN_ADVANCED_TIME(on_each_tap_fn, on_dance_finished_fn, on_dance_reset_fn, tap_specific_tapping_term)`~~: これは `ACTION_TAP_DANCE_FN_ADVANCED` 関数と同じように機能します。しかし、`TAPPING_TERM` で事前に定義した時間の代わりに、カスタマイズしたタップ時間を使います。 - * [ここ](ja/custom_quantum_functions.md#Custom_Tapping_Term)で概説するように、これはキーごとのタッピング時間機能を優先して非推奨になりました。この特定のタップダンス機能を使う代わりに、使いたい特定の `TD()` マクロ(`TD(TD_ESC_CAPS)` のような)を確認する必要があります。 - - -最初のオプションで、1つのキーに2つの役割を持たせる大抵のケースには十分です。例えば、`ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT)` は、1回タップすると `Space` を送信し、2回タップすると `Enter` を送信します。 - -!> ここでは [基本的なキーコード](ja/keycodes_basic.md) だけがサポートされていることを覚えておいてください。カスタムキーコードはサポートされていません。 - -最初のオプションに似ていますが、2番目のオプションは単純なレイヤー切替のケースに適しています。 - -これ以上に複雑なケースの場合、3番目か4番目のオプションを使います。(以下でそれらの例を列挙します) - -最後に、5番目のオプションは、もし、タップダンスキーをコードに追加した後、非タップダンスキーが奇妙な振る舞いを始めた時に特に役に立ちます。ありうる問題は、あなたがタップダンスキーを使いやすくするために `TAPPING_TERM` の時間を変更した結果、その他のキーが割り込みを処理する方法が変わってしまったというものです。 - - -## 実装の詳細 :id=implementation - -さて、説明の大部分はここまでです! 以下に挙げているいくつかの例に取り組むことができるようになり、あなた自身のタップダンスの機能を開発できるようになります。しかし、もし、あなたが裏側で起きていることをより深く理解したいのであれば、続けてそれが全てどのように機能するかの説明を読みましょう! - -メインエントリーポイントは、`process_tap_dance()` で、`process_record_quantum()` から呼び出されます。これはキーを押すたびに実行され、ハンドラは早期に実行されます。この関数は、押されたキーがタップダンスキーがどうか確認します。 -もし、押されたキーがタップダンスキーではなく、かつ、タップダンスが実行されていたなら、最初にそれを処理し、新しく押されたキーをキューに格納します。 -もし、押されたキーがタップダンスキーであるなら、既にアクティブなタップダンスと同じキーか確認します(もしアクティブなものがある場合、それと)。 -異なる場合、まず、古いタップダンスを処理し、続いて新しいタップダンスを登録します。 -同じ場合、カウンタの値を増やし、タイマーをリセットします。 - -このことは、あなたは再びキーをタップするまでの時間として `TAPPING_TERM` の時間を持っていることを意味します。そのため、あなたは1つの `TAPPING_TERM` の時間内に全てのタップを行う必要はありません。これにより、キーの反応への影響を最小限に抑えながら、より長いタップ回数を可能にします。 - -次は `tap_dance_task()` です。この関数はタップダンスキーのタイムアウトを制御します。 - -柔軟性のために、タップダンスは、キーコードの組み合わせにも、ユーザー関数にもなることができます。後者は、より高度なタップ回数の制御や、LED を点滅させたり、バックライトをいじったり、等々の制御を可能にします。これは、1つの共用体と、いくつかの賢いマクロによって成し遂げられています。 - -## 実装例 :id=examples - -### シンプルな実装例 :id=simple-example - -ここに1つの定義のための簡単な例があります。 - -1. `rules.mk` に `TAP_DANCE_ENABLE = yes` を追加します。 -2. `config.h` ファイル(`qmk_firmware/keyboards/planck/config.h` からあなたのキーマップディレクトリにコピーできます)に `#define TAPPING_TERM 200` を追加します。 -3. `keymap.c` ファイルに変数とタップダンスの定義を定義し、それからキーマップに追加します。 - -```c -// タップダンスの宣言 -enum { - TD_ESC_CAPS, -}; - -// タップダンスの定義 -qk_tap_dance_action_t tap_dance_actions[] = { - // 1回タップすると Escape キー、2回タップすると Caps Lock。 - [TD_ESC_CAPS] = ACTION_TAP_DANCE_DOUBLE(KC_ESC, KC_CAPS), -}; - -// キーマップにキーコードの代わりにタップダンスの項目を追加します -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - // ... - TD(TD_ESC_CAPS) - // ... -}; -``` - -### 複雑な実装例 :id=complex-examples - -このセクションでは、いくつかの複雑なタップダンスの例を詳しく説明します。 -例で使われている全ての列挙型はこのように宣言します。 - -```c -// 全ての例のための列挙型定義 -enum { - CT_SE, - CT_CLN, - CT_EGG, - CT_FLSH, - X_TAP_DANCE -}; -``` -#### 例1: 1回タップすると `:` を送信し、2回タップすると `;` を送信する :id=example-1 - -```c -void dance_cln_finished(qk_tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - register_code16(KC_COLN); - } else { - register_code(KC_SCLN); - } -} - -void dance_cln_reset(qk_tap_dance_state_t *state, void *user_data) { - if (state->count == 1) { - unregister_code16(KC_COLN); - } else { - unregister_code(KC_SCLN); - } -} - -// 全てのタップダンス関数はここに定義します。ここでは1つだけ示します。 -qk_tap_dance_action_t tap_dance_actions[] = { - [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), -}; -``` - -#### 例2: 100回タップした後に "Safety Dance!" を送信します :id=example-2 - -```c -void dance_egg(qk_tap_dance_state_t *state, void *user_data) { - if (state->count >= 100) { - SEND_STRING("Safety dance!"); - reset_tap_dance(state); - } -} - -qk_tap_dance_action_t tap_dance_actions[] = { - [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), -}; -``` - -#### 例3: 1つずつ LED を点灯させてから消灯する :id=example-3 - -```c -// タップする毎に、LED を右から左に点灯します。 -// 4回目のタップで、右から左に消灯します。 -void dance_flsh_each(qk_tap_dance_state_t *state, void *user_data) { - switch (state->count) { - case 1: - ergodox_right_led_3_on(); - break; - case 2: - ergodox_right_led_2_on(); - break; - case 3: - ergodox_right_led_1_on(); - break; - case 4: - ergodox_right_led_3_off(); - wait_ms(50); - ergodox_right_led_2_off(); - wait_ms(50); - ergodox_right_led_1_off(); - } -} - -// 4回目のタップで、キーボードをフラッシュ状態にセットします。 -void dance_flsh_finished(qk_tap_dance_state_t *state, void *user_data) { - if (state->count >= 4) { - reset_keyboard(); - } -} - -// もしフラッシュ状態にならない場合、LED を左から右に消灯します。 -void dance_flsh_reset(qk_tap_dance_state_t *state, void *user_data) { - ergodox_right_led_1_off(); - wait_ms(50); - ergodox_right_led_2_off(); - wait_ms(50); - ergodox_right_led_3_off(); -} - -// 全てのタップダンス関数を一緒に表示しています。この例3は "CT_FLASH" です。 -qk_tap_dance_action_t tap_dance_actions[] = { - [CT_SE] = ACTION_TAP_DANCE_DOUBLE(KC_SPC, KC_ENT), - [CT_CLN] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, dance_cln_finished, dance_cln_reset), - [CT_EGG] = ACTION_TAP_DANCE_FN(dance_egg), - [CT_FLSH] = ACTION_TAP_DANCE_FN_ADVANCED(dance_flsh_each, dance_flsh_finished, dance_flsh_reset) -}; -``` - -#### 例4: クアッドファンクションのタップダンス :id=example-4 - -[DanielGGordon](https://github.com/danielggordon) によるもの - -キーを押す回数と、キーを押し続けるかタップするかによって、1つのキーに4つ(またはそれ以上)の機能を持たせることができるようになります。 - -以下に例をあげます: -* 1回タップ = `x` を送信 -* 押し続ける = `Control` を送信 -* 2回タップ = `Escape` を送信 -* 2回タップして押し続ける = `Alt` を送信 - -'クアッドファンクションのタップダンス' を利用できるようにするには、いくつかのものが必要になります。 - -`keymap.c` ファイルの先頭、つまりキーマップの前に、以下のコードを追加します。 - -```c -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_TAP, - TD_DOUBLE_HOLD, - TD_DOUBLE_SINGLE_TAP, // Send two single taps - TD_TRIPLE_TAP, - TD_TRIPLE_HOLD -} td_state_t; - -typedef struct { - bool is_press_action; - td_state_t state; -} td_tap_t; - -// タップダンスの列挙型 -enum { - X_CTL, - SOME_OTHER_DANCE -}; - -td_state_t cur_dance(qk_tap_dance_state_t *state); - -// xタップダンスのための関数。キーマップで利用できるようにするため、ここに置きます。 -void x_finished(qk_tap_dance_state_t *state, void *user_data); -void x_reset(qk_tap_dance_state_t *state, void *user_data); -``` - -次に、`keymap.c` ファイルの末尾に、次のコードを追加する必要があります。 - -```c -/* 実行されるタップダンスの種類に対応する整数を返します。 - * - * タップダンスの状態を判別する方法: 割り込みと押下。 - * - * 割り込み: - * タップダンスの状態が「割り込み」の場合、他のキーがタップ時間中に押されたことを意味します。 - * これは通常、キーを「タップ」しようとしていることを示します。 - * - * 押下: - * キーがまだ押されているかどうか。この値が true の場合、タップ時間が終了したことを意味しますが、 - * キーはまだ押されたままです。これは通常、キーが「ホールド」されていることを意味します。 - * - * タップダンスに関して、qmk ソフトウェアで現在不可能なことの1つは、"permissive hold" 機能を - * 模倣することです。 - * 一般に、高度なタップダンスは一般的に入力される文字で使われた場合にうまく機能しません。 - * 例えば "A" の場合。タップダンスは文字の入力中に入力しない文字以外のキーで使うのが最適です。 - * - * 高度なタップダンスを配置するのに適した場所: - * z、q、x、j、k、v、b、ファンクションキー、home/end、コンマ、セミコロン - * - * タップダンスキーの「最適な配置場所」の基準: - * 文章中で頻繁に入力するキーでないこと - * ダブルタップに頻繁に使われるキーでないこと。例えば、'tab' はターミナルやウェブフォームで - * しばしばダブルタップされます。そのため、タップダンスでは 'tab' は良い選択ではありません。 - * 一般的な単語で2回続けて使われる文字でないこと。例えば 'pepper' 中の 'p'。もしタップダンス機能が - * 文字 'p' に存在する場合、'pepper' という単語は入力するのが非常にいらだたしいものになるでしょう。 - * - * 3つ目の点については、'TD_DOUBLE_SINGLE_TAP' が存在しますが、これは完全にはテストされていません - * - */ -td_state_t cur_dance(qk_tap_dance_state_t *state) { - if (state->count == 1) { - if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; - // キーは割り込まれていませんが、まだ押し続けられています。'HOLD' を送信することを意味します。 - else return TD_SINGLE_HOLD; - } else if (state->count == 2) { - // TD_DOUBLE_SINGLE_TAP は "pepper" と入力することと、'pp' と入力したときに実際に - // ダブルタップしたい場合とを区別するためのものです。 - // この戻り値の推奨されるユースケースは、'ダブルタップ' 動作やマクロではなく、 - // そのキーの2つのキー入力を送信したい場合です。 - if (state->interrupted) return TD_DOUBLE_SINGLE_TAP; - else if (state->pressed) return TD_DOUBLE_HOLD; - else return TD_DOUBLE_TAP; - } - - // 誰も同じ文字を3回入力しようとしていないと仮定します(少なくとも高速には)。 - // タップダンスキーが 'KC_W' で、"www." と高速に入力したい場合、ここに例外を追加して - // 'TD_TRIPLE_SINGLE_TAP' を返し、'TD_DOUBLE_SINGLE_TAP' のようにその列挙型を定義する必要があります。 - if (state->count == 3) { - if (state->interrupted || !state->pressed) return TD_TRIPLE_TAP; - else return TD_TRIPLE_HOLD; - } else return TD_UNKNOWN; -} - -//'x' タップダンスの 'td_tap_t' のインスタンスを生成します。 -static td_tap_t xtap_state = { - .is_press_action = true, - .state = TD_NONE -}; - -void x_finished(qk_tap_dance_state_t *state, void *user_data) { - xtap_state.state = cur_dance(state); - switch (xtap_state.state) { - case TD_SINGLE_TAP: register_code(KC_X); break; - case TD_SINGLE_HOLD: register_code(KC_LCTRL); break; - case TD_DOUBLE_TAP: register_code(KC_ESC); break; - case TD_DOUBLE_HOLD: register_code(KC_LALT); break; - // 最後の case は高速入力用です。キーが `f` であると仮定します: - // 例えば、`buffer` という単語を入力するとき、`Esc` ではなく `ff` を送信するようにします。 - // 高速入力時に `ff` と入力するには、次の文字は `TAPPING_TERM` 以内に入力する必要があります。 - // `TAPPING_TERM` はデフォルトでは 200ms です。 - case TD_DOUBLE_SINGLE_TAP: tap_code(KC_X); register_code(KC_X); - } -} - -void x_reset(qk_tap_dance_state_t *state, void *user_data) { - switch (xtap_state.state) { - case TD_SINGLE_TAP: unregister_code(KC_X); break; - case TD_SINGLE_HOLD: unregister_code(KC_LCTRL); break; - case TD_DOUBLE_TAP: unregister_code(KC_ESC); break; - case TD_DOUBLE_HOLD: unregister_code(KC_LALT); - case TD_DOUBLE_SINGLE_TAP: unregister_code(KC_X); - } - xtap_state.state = TD_NONE; -} - -qk_tap_dance_action_t tap_dance_actions[] = { - [X_CTL] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, x_finished, x_reset) -}; -``` - -これで、キーマップのどこでも簡単に `TD(X_CTL)` マクロが使えます。 - -> この設定の "hold" は、タップダンスのタイムアウト(`ACTION_TAP_DANCE_FN_ADVANCED_TIME` 参照)の **後** に起こります。即座に "hold" を得るためには、条件から `state->interrupted` の確認を除きます。結果として、複数回のタップのための時間をより多く持つことで快適な長いタップの期限を使うことができ、そして、"hold" のために長く待たないようにすることができます(2倍の `TAPPING TERM` で開始してみてください)。 - -#### 例5: タップダンスを高度なモッドタップとレイヤータップキーに使う :id=example-5 - -タップダンスは、タップされたコードが基本的なキーコード以外の場合に、 `MT()` と `LT()` マクロをエミュレートするのに利用できます。これは、通常 `Shift` を必要とする '(' や '{' のようなキーや、`Control + X` のように他の修飾されたキーコードをタップされたキーコードとして送信することに役立ちます。 - -あなたのレイヤーとカスタムキーコードの下に、以下のコードを追加します。 - -```c -// タップダンスのキーコード -enum td_keycodes { - ALT_LP // 例: 押していると `LALT`、タップすると `(`。それぞれのタップダンスの追加のキーコードを追加します -}; - -// 必要な数のタップダンス状態を含むタイプを定義します -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_SINGLE_TAP -} td_state_t; - -// タップダンスの状態の型のグローバルインスタンスを作ります -static td_state_t td_state; - -// タップダンス関数を宣言します: - -// 現在のタップダンスの状態を特定するための関数 -td_state_t cur_dance(qk_tap_dance_state_t *state); - -// それぞれのタップダンスキーコードに適用する `finished` と `reset` 関数 -void altlp_finished(qk_tap_dance_state_t *state, void *user_data); -void altlp_reset(qk_tap_dance_state_t *state, void *user_data); -``` - -キーレイアウト(`LAYOUT`)の下に、タップダンスの関数を定義します。 - -```c -// 返却するタップダンス状態を特定します -td_state_t cur_dance(qk_tap_dance_state_t *state) { - if (state->count == 1) { - if (state->interrupted || !state->pressed) return TD_SINGLE_TAP; - else return TD_SINGLE_HOLD; - } - - if (state->count == 2) return TD_DOUBLE_SINGLE_TAP; - else return TD_UNKNOWN; // 上記で返却する最大の状態の値より大きい任意の数 -} - -// 定義する各タップダンスキーコードのとりうる状態を制御します: - -void altlp_finished(qk_tap_dance_state_t *state, void *user_data) { - td_state = cur_dance(state); - switch (td_state) { - case TD_SINGLE_TAP: - register_code16(KC_LPRN); - break; - case TD_SINGLE_HOLD: - register_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_on(_MY_LAYER)` を使います - break; - case TD_DOUBLE_SINGLE_TAP: // タップ時間内に2つの括弧 `((` の入れ子を可能にします - tap_code16(KC_LPRN); - register_code16(KC_LPRN); - } -} - -void altlp_reset(qk_tap_dance_state_t *state, void *user_data) { - switch (td_state) { - case TD_SINGLE_TAP: - unregister_code16(KC_LPRN); - break; - case TD_SINGLE_HOLD: - unregister_mods(MOD_BIT(KC_LALT)); // レイヤータップキーの場合、ここでは `layer_off(_MY_LAYER)` を使います - break; - case TD_DOUBLE_SINGLE_TAP: - unregister_code16(KC_LPRN); - } -} - -// 各タップダンスキーコードの `ACTION_TAP_DANCE_FN_ADVANCED()` を定義し、`finished` と `reset` 関数を渡します -qk_tap_dance_action_t tap_dance_actions[] = { - [ALT_LP] = ACTION_TAP_DANCE_FN_ADVANCED(NULL, altlp_finished, altlp_reset) -}; -``` - -それぞれのタップダンスキーコードをキーマップに含めるときは、`TD()` マクロでキーコードをラップします。例: `TD(ALT_LP)` - -#### 例6: タップダンスを一時的なレイヤー切り替えとレイヤートグルキーに使う :id=example-6 - -タップダンスは、MO(layer) と TG(layer) 機能を模倣することにも使用できます。この例では、1回タップすると `KC_QUOT` 、1回押してそのまま押し続けたら `MO(_MY_LAYER)` 、2回タップしたときは `TG(_MY_LAYER)` として機能するキーを設定します。 - -最初のステップは、あなたの `keymap.c` ファイルの最初のあたりに以下のコードを追加することです。 - -```c -// 必要な数のタップダンス状態のタイプを定義します -typedef enum { - TD_NONE, - TD_UNKNOWN, - TD_SINGLE_TAP, - TD_SINGLE_HOLD, - TD_DOUBLE_TAP -} td_state_t; - -typedef struct { - bool is_press_action; - td_state_t state; -} td_tap_t; - -enum { - QUOT_LAYR, // カスタムタップダンスキー。他のタップダンスキーはこの列挙型に追加します -}; - -// タップダンスキーで使われる関数を宣言します - -// 全てのタップダンスに関連する関数 -td_state_t cur_dance(qk_tap_dance_state_t *state); - -// 個別のタップダンスに関連する関数 -void ql_finished(qk_tap_dance_state_t *state, void *user_data); -void ql_reset(qk_tap_dance_state_t *state, void *user_data); -``` - -あなたの `keymap.c` ファイルの最後の方に以下のコードを追加します。 - -```c -// 現在のタップダンスの状態を決定します -td_state_t cur_dance(qk_tap_dance_state_t *state) { - if (state->count == 1) { - if (!state->pressed) return TD_SINGLE_TAP; - else return TD_SINGLE_HOLD; - } else if (state->count == 2) return TD_DOUBLE_TAP; - else return TD_UNKNOWN; -} - -// この例のタップダンスキーに関連付けられた "tap" 構造体を初期化します -static td_tap_t ql_tap_state = { - .is_press_action = true, - .state = TD_NONE -}; - -// タップダンスキーの動作をコントロールする関数 -void ql_finished(qk_tap_dance_state_t *state, void *user_data) { - ql_tap_state.state = cur_dance(state); - switch (ql_tap_state.state) { - case TD_SINGLE_TAP: - tap_code(KC_QUOT); - break; - case TD_SINGLE_HOLD: - layer_on(_MY_LAYER); - break; - case TD_DOUBLE_TAP: - // レイヤーが既にセットされているか確認します - if (layer_state_is(_MY_LAYER)) { - // レイヤーが既にセットされていたら、オフにします。 - layer_off(_MY_LAYER); - } else { - // レイヤーがセットされていなかったら、オンにします。 - layer_on(_MY_LAYER); - } - break; - } -} - -void ql_reset(qk_tap_dance_state_t *state, void *user_data) { - // キーを押し続けていて今離したら、レイヤーをオフに切り替えます。 - if (ql_tap_state.state == TD_SINGLE_HOLD) { - layer_off(_MY_LAYER); - } - ql_tap_state.state = TD_NONE; -} - -// タップダンスキーを機能に関連付けます -qk_tap_dance_action_t tap_dance_actions[] = { - [QUOT_LAYR] = ACTION_TAP_DANCE_FN_ADVANCED_TIME(NULL, ql_finished, ql_reset, 275) -}; -``` - -上記のコードは、前の例で使われたコードに似ています。注意する1つのポイントは、必要に応じてレイヤーを切り替えられるように、どのレイヤーがアクティブになっているかいつでも確認できる必要があることです。これを実現するために、引数で与えられた `layer` がアクティブなら `true` を返す `layer_state_is(layer)` を使います。 - -`cur_dance()` と `ql_tap_state` の使い方は、上の例と似ています。 - -`ql_finished` 関数における `case: TD_SINGLE_TAP` は、上の例と似ています。`TD_SINGLE_HOLD` の case では、`ql_reset()` と連動してタップダンスキーを押している間 `_MY_LAYER` に切り替わり、キーを離した時に `_MY_LAYER` から離れます。これは、`MO(_MY_LAYER)` に似ています。`TD_DOUBLE_TAP` の case では、`_MY_LAYER` がアクティブレイヤーかどうかを確認することによって動きます。そして、その結果に基づいてレイヤーのオン・オフをトグルします。これは `TG(_MY_LAYER)` に似ています。 - -`tap_dance_actions[]` は、上の例に似ています。 `ACTION_TAP_DANCE_FN_ADVANCED()` の代わりに `ACTION_TAP_DANCE_FN_ADVANCED_TIME()` を使ったことに注意してください。 -この理由は、私は、非タップダンスキーを使うにあたり `TAPPING_TERM` が短い(175ミリ秒以内)方が好きなのですが、タップダンスのアクションを確実に完了させるには短すぎるとわかったからです——そのため、ここでは時間を275ミリ秒に増やしています。 - -最後に、このタップダンスキーを動かすため、忘れずに `TD(QUOT_LAYR)` を `keymaps[]` に加えてください。 diff --git a/docs/ja/feature_thermal_printer.md b/docs/ja/feature_thermal_printer.md deleted file mode 100644 index 508123bd64e7..000000000000 --- a/docs/ja/feature_thermal_printer.md +++ /dev/null @@ -1,15 +0,0 @@ -# 感熱式プリンタ - - - - - -## 感熱式プリンタのキーコード - -| キー | 説明 | -|-----------|----------------------------------------| -| `PRINT_ON` | ユーザが入力した全ての印刷を開始 | -| `PRINT_OFF` | ユーザが入力した全ての印刷を停止 | diff --git a/docs/ja/feature_unicode.md b/docs/ja/feature_unicode.md deleted file mode 100644 index 2158678f3c48..000000000000 --- a/docs/ja/feature_unicode.md +++ /dev/null @@ -1,266 +0,0 @@ -# Unicode サポート - - - -Unicode 文字はキーボードから直接入力することができます!ただし幾つかの制限があります。 - -キーボードで Unicode サポートを有効にするには、以下の事をする必要があります: - -1. サポートされている Unicode 実装のいずれかを選択します: [Basic Unicode](#basic-unicode)、[Unicode Map](#unicode-map)、[UCIS](#ucis)。 -2. オペレーティングシステムとセットアップに最適な[入力モード](#input-modes)を見つけます。 -3. コンフィギュレーションに適切な入力モード(または複数のモード)を[設定](#setting-the-input-mode)します。 -4. キーマップに Unicode キーコードを追加します。 - - -## 1. メソッド :id=methods - -QMK は、Unicode 入力を有効にし、キーマップに Unicode 文字を追加するための3つの異なる方法をサポートします。それぞれに柔軟性と使いやすさの点で長所と短所があります。あなたの使い方に最適なものを選んでください。 - -ほとんどのユーザには Basic Unicode で十分です。ただし、サポートされる文字の範囲が広い(絵文字、珍しい記号など)ことが必要な場合には、Unicode Map を使う必要があります。 - -
- -### 1.1. Basic Unicode :id=basic-unicode - -多少制限はありますが、最も使いやすい方法です。Unicode 文字をキーコードとしてキーマップ自体に格納するため、`0x7FFF` までのコードポイントのみをサポートします。これは、ほとんどの現代言語(東アジアを含む)の文字と記号を対象としますが、絵文字は対象外です。 - -以下を `rules.mk` に追加します: - -```make -UNICODE_ENABLE = yes -``` - -次に、`UC(c)` キーコードをキーマップに追加します。ここで、_c_ は目的の文字のコードポイントです (できれば16進数で最大4桁の長さが望ましいです)。例えば、`UC(0x40B)` は [Ћ](https://unicode-table.com/en/040B/) を出力し、`UC(0x30C4)` は [ツ](https://unicode-table.com/en/30C4) を出力します。 - -
- -### 1.2. Unicode Map :id=unicode-map - -このメソッドは、標準の文字の範囲に加えて、絵文字、古代文字、珍しい記号なども対象にしています。実際、可能な全てのコードポイント(`0x10FFFF`まで)がサポートされています。Unicode 文字は独立のマッピングテーブルに格納されています。キーマップファイルに `unicode_map` 配列を維持する必要があります。これには最大 16384 エントリを含めることができます。 - -以下を `rules.mk` に追加します: - -```make -UNICODEMAP_ENABLE = yes -``` - -次に、`X(i)` キーコードをキーマップに追加します。ここで _i_ はマッピングテーブル内の目的の文字のインデックスです。これは数値にできますが、インデックスを列挙型に保持し、名前でアクセスすることをお勧めします。 - -```c -enum unicode_names { - BANG, - IRONY, - SNEK -}; - -const uint32_t PROGMEM unicode_map[] = { - [BANG] = 0x203D, // ‽ - [IRONY] = 0x2E2E, // ⸮ - [SNEK] = 0x1F40D, // 🐍 -}; -``` - -そして、キーマップで `X(BANG)`、`X(SNEK)` などを使うことができます。 - -#### 小文字と大文字 - -文字は å や Å のような小文字と大文字のペアで提供されることがあります。これらの文字を入力しやすくするために、キーマップで `XP(i, j)` を使うことができます。ここで、_i_ および _j_ はそれぞれ小文字と大文字のマッピングテーブルのインデックスです。キーを押した時に、シフトを押したままか Caps Lock をオンにしている場合は、2番目(大文字)の文字が挿入されます; そうでなければ最初(小文字)バージョンが出力されます。 - -これは特殊文字がある国際レイアウトのためのキーマップを作成している時に最も役立ちます。別々のキーに文字の小文字および大文字バージョンを置く代わりに、`XP()` を使ってそれら両方を同じキーに持つことができます。これは Unicode キーを通常のアルファベットと混ぜるのに役立ちます。 - -キーコードのサイズの制約により、_i_ と _j_ はそれぞれ `unicode_map` の最初の128文字のうち1つだけを参照できます。別の言い方をすると、0 ≤ _i_ ≤ 127 かつ 0 ≤ _j_ ≤ 127 です。これはほとんどのユースケースで十分ですが、インデックス計算をカスタマイズしたい場合は、[`unicodemap_index()`](https://github.com/qmk/qmk_firmware/blob/71f640d47ee12c862c798e1f56392853c7b1c1a8/quantum/process_keycode/process_unicodemap.c#L36) 関数をオーバーライドすることができます。これにより、例えば Shift/Caps の代わりに Ctrl をチェックすることもできます。 - -
- -### 1.3. UCIS :id=ucis - -この方法も全ての可能なコードポイントをサポートします。Unicode Map の方法と同様に、キーマップファイル内にマッピングテーブルを保持する必要があります。ただし、この機能のための組み込みのキーコードはありません — この機能を起動するカスタムキーコードあるいは関数を作成する必要があります。 - -以下を `rules.mk` に追加します: - -```make -UCIS_ENABLE = yes -``` - -次に、キーマップファイルでこのようにテーブルを定義します: - -```c -const qk_ucis_symbol_t ucis_symbol_table[] = UCIS_TABLE( - UCIS_SYM("poop", 0x1F4A9), // 💩 - UCIS_SYM("rofl", 0x1F923), // 🤣 - UCIS_SYM("cuba", 0x1F1E8, 0x1F1FA), // 🇨🇺 - UCIS_SYM("look", 0x0CA0, 0x005F, 0x0CA0), // ಠ_ಠ -); -``` - -デフォルトでは、各テーブルエントリの長さは、最大3コードポイントです。この番号は `#define UCIS_MAX_CODE_POINTS n` を `config.h` ファイルに追加することで変更できます。 - -UCIS 入力を使うには、`qk_ucis_start()` を呼び出します。次に、文字のニーモニック ("rofl" など) を入力し、Space か Enter か Esc を押します。QMK は "rofl" テキストを消去し、笑っている絵文字を挿入するはずです。 - -#### カスタマイズ - -この機能をカスタマイズするためにキーマップで定義できる幾つかの関数があります。 - -* `void qk_ucis_start_user(void)` – これは "start" 関数を呼び出す時に実行され、フィードバックを提供するために使うことができます。デフォルトでは、キーボードの絵文字を入力します。 -* `void qk_ucis_success(uint8_t symbol_index)` – これは入力が何かに一致して完了した時に実行されます。デフォルトでは何もしません。 -* `void qk_ucis_symbol_fallback (void)` – これは入力が何にも一致しない時に実行されます。デフォルトでは、入力を Unicode コードとして試そうとします。 - -[`process_ucis.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_ucis.c) でこれらの関数のデフォルトの実装を見つけることができます。 - - -## 2. Input モード :id=input-modes - -QMK での Unicode の入力は、マクロのように、OS への一連の文字列を入力することで動作します。残念ながら、これが行われる方法はプラットフォームによって異なります。特に各プラットフォームでは Unicode 入力を引き起こすために、異なるキーの組み合わせが必要です。従って、対応する入力モードが QMK で設定されなければなりません。 - -以下の入力モードが利用可能です: - -* **`UC_MAC`**: macOS の組み込み Unicode 16進数入力。`0x10FFFF` までのコードポイント(全ての利用可能なコードポイント)をサポートします。 - - 有効にするには、_システム環境設定 > キーボード > 入力ソース_ に移動し、(_その他_ の下の) _Unicode 16進数入力_ をリストに追加し、次にメニューバーの入力ドロップダウンからそれをアクティブにします。 - デフォルトでは、このモードは Unicode 入力のために左 Option キー (`KC_LALT`) を使いますが、これは他のキーで [`UNICODE_KEY_MAC`](#input-key-configuration) を定義することで変更できます。 - - !> _Unicode 16進数入力_ 入力ソースの使用は、Option + 左矢印および Option + 右矢印 のような、幾つかの Option ベースのショートカットを無効にするかもしれません。 - - !> `UC_OSX` は `UC_MAC` の非推奨のエイリアスで、QMK の将来のバージョンで削除されます。全ての新しいキーマップは、`UC_MAC` を使うべきです。 - -* **`UC_LNX`**: Linux の組み込み IBus Unicode 入力。`0x10FFFF` までのコードポイント(全ての利用可能なコードポイント)をサポートします。 - - デフォルトで有効になっていて、IBus が有効になったディストリビューションのほとんどどれでも動作します。IBus が無い場合、このモードは GTK アプリ下で動作しますが、他の場所ではほとんど動作しません。 - デフォルトでは、このモードは Unicode 入力を開始するために Ctrl+Shift+U (`LCTL(LSFT(KC_U))`) を使いますが、これは他のキーコードで [`UNICODE_KEY_LNX`](#input-key-configuration) を定義することで変更できます。これは、Ctrl+Shift+U の挙動が Ctrl+Shift+E に統合された IBus バージョン 1.5.15 以上を必要とするかもしれません。 - -* **`UC_WIN`**: _(非推奨)_ Windows の組み込み16進数テンキー Unicode 入力。`0xFFFF` までのコードポイントをサポートします。 - - 有効にするには、`HKEY_CURRENT_USER\Control Panel\Input Method` の下に、`EnableHexNumpad` という名前の `REG_SZ` 型のレジストリキーを作成し、その値を `1` に設定します。これは、管理者権限でコマンドラインプロンプトから `reg add "HKCU\Control Panel\Input Method" -v EnableHexNumpad -t REG_SZ -d 1` を実行することでできます。その後再起動します。 - 信頼性と互換性の問題から、このモードはお勧めできません; 代わりに `UC_WINC` モードを使ってください。 - -* **`UC_BSD`**: _(未実装)_ BSD での Unicode 入力。現時点では実装されていません。BSD ユーザでサポートを追加したい場合は、[GitHub で issue を開いて](https://github.com/qmk/qmk_firmware/issues)ください。 - -* **`UC_WINC`**: [WinCompose](https://github.com/samhocevar/wincompose) を使った Windows Unicode 入力。v0.9.0 の時点で、`0x10FFFF` までのコードポイント(全ての利用可能なコードポイント)をサポートします。 - - 有効にするには、[最新のリリース](https://github.com/samhocevar/wincompose/releases/latest)をインストールします。インストールすると、起動時に WinCompose が自動的に実行されます。このモードはアプリがサポートする全てのバージョンの Windows で確実に動作します。 - デフォルトでは、このモードは Compose キーとして右 Alt (`KC_RALT`) を使いますが、これは WinCompose 設定と他のキーで [`UNICODE_KEY_WINC`](#input-key-configuration) を定義することで変更できます。 - - -## 3. 入力モードの設定 :id=setting-the-input-mode - -目的の入力モードを設定するには、以下の定義を `config.h` に追加します: - -```c -#define UNICODE_SELECTED_MODES UC_LNX -``` - -この例では、キーボードのデフォルトの入力モードを `UC_LNX` に設定します。これは、`UC_MAC` か `UC_WINC` か[上記](#input-modes)に列挙されている他のモードのいずれかに置き換えることができます。手動で別のモード([下記](#keycodes)を見てください)に切り替えない限り、キーボードは起動時に選択したモードを自動的に使います。 - -複数の入力モードを選択することもできます。これにより、`UC_MOD`/`UC_RMOD` キーコードを使ってそれらを簡単に切り替えることができます。 - -```c -#define UNICODE_SELECTED_MODES UC_MAC, UC_LNX, UC_WINC -``` - -値はカンマで区切られていることに注意してください。キーボードは最後に使われた入力モードを記憶し、次の電源投入時にそれを使い続けます。`config.h` に `#define UNICODE_CYCLE_PERSIST false` を追加することで、これを無効にして常にリストの最初のモードで開始するように強制できます。 - -#### キーコード - -以下のキーコードを使って、いつでも入力モードを切り替えることができます。これらをキーマップに追加すると、`UNICODE_SELECTED_MODES` に列挙されていないモードを含む特定の入力モードに素早く切り替えることができます。 - -| キーコード |エイリアス | 入力モード | 説明 | -|------------------------|-----------|--------------|--------------------------------------------------------------------| -| `UNICODE_MODE_FORWARD` | `UC_MOD` | リストの次へ | 選択したモードを切り替えます。Shift が押された場合は逆方向 | -| `UNICODE_MODE_REVERSE` | `UC_RMOD` | リストの前へ | 逆方向に選択したモードを切り替えます。Shift が押された場合は順方向 | -| `UNICODE_MODE_MAC` | `UC_M_MA` | `UC_MAC` | macOS 入力に切り替え | -| `UNICODE_MODE_LNX` | `UC_M_LN` | `UC_LNX` | Linux 入力に切り替え | -| `UNICODE_MODE_WIN` | `UC_M_WI` | `UC_WIN` | Windows 入力に切り替え | -| `UNICODE_MODE_BSD` | `UC_M_BS` | `UC_BSD` | BSD 入力に切り替え _(未実装)_ | -| `UNICODE_MODE_WINC` | `UC_M_WC` | `UC_WINC` | WinCompose を使う Windows 入力に切り替え | - -コード内で `set_unicode_input_mode(x)` を呼び出すことで、入力モードを切り替えることもできます。ここで、_x_ は上記の入力モード定数のいずれか (例えば、`UC_LNX`) です。 - -?> `matrix_init_user()` または同様の関数の中で `set_unicode_input_mode()` を呼び出すよりも、`UNICODE_SELECTED_MODES` を使うほうが望ましいです。Unicode システムとの統合性が高く、EEPROM への不要な書き込みを回避できるという利点があるからです。 - -#### オーディオフィードバック - -キーボードで[オーディオ機能](ja/feature_audio.md)を有効にした場合、上記のキーを押したときにメロディーを再生するように設定できます。そのようにして、入力モードを切り替えた時になんらかのオーディオフィードバックを得ることができます。 - -例えば、`config.h` ファイルに下記の定義を追加することができます: - -```c -#define UNICODE_SONG_MAC AUDIO_ON_SOUND -#define UNICODE_SONG_LNX UNICODE_LINUX -#define UNICODE_SONG_BSD TERMINAL_SOUND -#define UNICODE_SONG_WIN UNICODE_WINDOWS -#define UNICODE_SONG_WINC UNICODE_WINDOWS -``` - - -## 追加のカスタマイズ - -Unicode は大規模で多目的な機能のため、システムでより適切に動作するようにカスタマイズできるオプションが幾つかあります。 - -### 入力関数の開始と終了 - -プラットフォームで Unicode 入力を開始および終了する機能は、ローカルで上書きできます。可能な用途には、デフォルトキーを使用しない場合の入力モードの挙動のカスタマイズ、あるいは Unicode 入力への視覚/音声フィードバックの追加があります。 - -* `void unicode_input_start(void)` – これはプラットフォームに Unicode 入力モードの入力を指示する初期シーケンスを送信します。例えば、Windows では左 Alt キーの後に Num+ を押したままにし、Linux では `UNICODE_KEY_LNX` の組み合わせ(デフォルト: Ctrl+Shift+U) を押します。 -* `void unicode_input_finish(void)` – これは、例えば Space を押すか Alt キーを放すなどして、Unicode 入力モードを終了するために呼ばれます。 - -[`process_unicode_common.c`](https://github.com/qmk/qmk_firmware/blob/master/quantum/process_keycode/process_unicode_common.c) でこれらの関数のデフォルトの実装を見つけることができます。 - -### 入力キーの設定 - -`config.h` に対応する定義を追加することで、macOS、Linux、WinCompose で Unicode 入力を引き起こすために使われるキーをカスタマイズできます。デフォルト値はプラットフォームのデフォルト設定に一致するため、Unicode 入力が動作しない、あるいは(例えば左あるいは右 Alt を解放するために)異なるキーを使いたい場合以外はこれを変更する必要はありません。 - -| 定義 | 型 | 既定値 | 例 | -|--------------------|------------|--------------------|---------------------------------------------| -| `UNICODE_KEY_MAC` | `uint8_t` | `KC_LALT` | `#define UNICODE_KEY_MAC KC_RALT` | -| `UNICODE_KEY_LNX` | `uint16_t` | `LCTL(LSFT(KC_U))` | `#define UNICODE_KEY_LNX LCTL(LSFT(KC_E))` | -| `UNICODE_KEY_WINC` | `uint8_t` | `KC_RALT` | `#define UNICODE_KEY_WINC KC_RGUI` | - - -## Unicode 文字列の送信 - -QMK は、Unicode 入力をプログラムでホストに送信できるようにする幾つかの関数を提供します: - -### `send_unicode_string()` - -この関数は、`send_string()` によく似ていますが、UTF-8 文字を直接入力できます。選択された入力モードでもサポートされている場合は、全てのコードポイントをサポートします。`keymap.c` ファイルが UTF-8 エンコーディングを使ってフォーマットされていることを確認してください。 - -```c -send_unicode_string("(ノಠ痊ಠ)ノ彡┻━┻"); -``` - -使用例には、[Macros](ja/feature_macros.md) で説明されているように、キーが押された時に Unicode 文字列を送信することが含まれます。 - -## 追加の言語サポート - -`quantum/keymap_extras` には、様々な言語ファイルがあります — これらは Colemak または BÉPO のような代替レイアウトのファイルと同じように動作します。これらの言語ヘッダのいずれかを `#include` すると、その言語/国のレイアウトに固有のキーコードにアクセスできます。このようなキーコードは、2文字の国/言語コードの後に、アンダースコアとキーが対応する4文字の略語が続くことで定義されます。例えば、キーマップに `keymap_french.h` を含め、`FR_UGRV` を使うと、ネイティブのフランス語 AZERTY レイアウトを使うシステムで入力すると、`ù` が出力されます。 - -マシンで使うプライマリシステムレイアウトが US ANSI と異なる場合、これらの言語固有のキーコードを使うと、QMK キーマップが実際に画面に出力されるものとより一致するようになります。ただし、これらのキーコードは、内部の対応するデフォルトの US キーコードのエイリアスに過ぎず、キーボードで使われる HID プロトコル自体は本質的に US ANSI に基づいていることに注意してください。 - - -## Windows での国際文字 - -### AutoHotkey - -この方法はキーボード自体で Unicode サポートを必要としませんが、代わりにバックグラウンドで [AutoHotkey](https://autohotkey.com) が実行されていることを当てにします。 - -最初にプログラムで使われていないモディファイアの組み合わせを選択する必要があります。 -Ctrl+Alt+Win はあまり広く使われていないため、これに最適なはずです。 -mod-tab コンボ `LCAG_T` 用に定義されたマクロがあります。 -この mod-tab マクロをキーボードのキーに追加します。例えば: `LCAG_T(KC_TAB)`。 -これにより、キーを押してすぐ放すとキーはタブキーのように振る舞いますが、他のキーと一緒に使うとモディファイアに変わります。 - -AutoHotkey のデフォルトのスクリプトで、カスタムホットキーを定義できます。 - - <^ - -似たキーマップを複数のキーボードで使う場合、それらの間でコードを共有できるという利点が得られることがあります。`users/`に以下の構造でキーマップ(理想的には GitHub のユーザ名、``)と同じ名前の独自のフォルダを作成します: - -* `/users//` (パスに自動的に追加されます) - * `readme.md` (オプション、推奨) - * `rules.mk` (自動的に含まれます) - * `config.h` (自動的に含まれます) - * `.h` (オプション) - * `.c` (オプション) - * `cool_rgb_stuff.c` (オプション) - * `cool_rgb_stuff.h` (オプション) - - -以下のように、`` という名前のキーマップをビルドする時のみ、これが全て起きます: - - make planck: - -例えば、 - - make planck:jack - -は、`/users/jack/rules.mk` に加えて、パスに `/users/jack/` フォルダを含めます。 - -!> この `name` は必要に応じて[上書き](#override-default-userspace)することができます。 - -## `Rules.mk` - -`rules.mk` は自動的に処理される2つファイルのうちの1つです。これにより、コンパイル時に追加のソースファイル( `.c` など)を追加できます。 - -追加されるデフォルトのソースファイルとして `.c` を使うことを強くお勧めします。それを追加するために、以下のように `rules.mk` に SRC を追加する必要があります: - - SRC += .c - -追加のファイルも同じ方法で追加できます - ただし、``.c/.h という名前のファイルを最初に用意することをお勧めします。 - -ビルド時に `/users//rules.mk` ファイルはキーマップの `rules.mk` の_後_でインクルードされます。これにより、キーボードによっては利用できないことのある個々の QMK 機能を利用する機能をユーザスペース `rules.mk` に持つことができます。 - -例えば、RGB ライトをサポートする全てのキーボード間で RGB 制御機能を共有する場合、RGBLIGHT 機能が有効であればサポートを追加することができます: -```make -ifeq ($(strip $(RGBLIGHT_ENABLE)), yes) - # ここにファンシーな rgb 関数のソースを含める - SRC += cool_rgb_stuff.c -endif -``` - -別のやり方として、キーマップの `rules.mk` で `define RGB_ENABLE` と定義し、以下のようにユーザスペースの `rules.mk` で変数をチェックすることができます: -```make -ifdef RGB_ENABLE - # ここにファンシーな rgb 関数のソースを含める - SRC += cool_rgb_stuff.c -endif -``` - -### デフォルトのユーザスペースの上書き :id=override-default-userspace - -デフォルトでは、使用されるユーザスペース名はキーマップ名と同じです。状況によってはこれは望ましくありません。例えば、[レイアウト](ja/feature_layouts.md)機能を使う場合、異なるキーマップに同じ名前 (例えば、ANSI および ISO) を使うことができません。レイアウトに `mylayout-ansi` や `mylayout-iso` という名前を付け、以下の行をレイアウトの `rules.mk` に追加します: - -``` -USER_NAME := mylayout -``` - -これは、基板上に物理的に異なる機能を備えた、複数の異なるキーボード(RGBライトを備えたキーボード、オーディオを備えたキーボード、LEDの数が異なる、コントローラ上の異なるPINに接続されているなど)がある場合にも役立ちます。 - -## 設定オプション (`config.h`) - -さらに、ここにある `config.h` はキーマップフォルダ内の同名のファイルと同じように処理されます。これは `.h` ファイルとは別個に処理されます。 - -この理由は、`.h` は (`#define TAPPING_TERM 100` などのような)設定を追加する時には追加されず、`config.h` ファイル内の `` ファイルを含めるとコンパイルの問題を引き起こすからです。 - -!>`config.h` は[設定オプション](ja/config_options.md)のために使い、`.h` ファイルはユーザあるいは(レイヤーあるいはキーコードのための enum のような)キーマップ固有の設定のために使うべきです - - -## Readme (`readme.md`) - -作者情報 (あなたの名前、GitHub ユーザ名、eメール)およびオプションで[GPL 互換のライセンス](https://www.gnu.org/licenses/license-list.html#GPLCompatibleLicenses)を含めてください。 - -以下をテンプレートとして使うことができます: -``` -Copyright @ - -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 . -``` - -年、名前、eメールおよび GitHub ユーザ名をあなたの情報に置き換えます。 - -さらに、コードを他の人に共有したい場合、ここはコードを文章化するのに適した場所です。 - -## 特定のキーマップをサポートする全てのキーボードをビルドする - -1つのコマンドで全てのキーマップのビルドを確認したいですか?以下で実行することができます: - - make all: - -例えば、 - - make all:jack - -これは、[_プルリクエスト_](https://github.com/qmk/qmk_firmware/pulls) を準備する時に全てが正常にコンパイルされることを確認したい場合に最適です。 - -## 例 - -簡単な例については、[`/users/_example/`](https://github.com/qmk/qmk_firmware/tree/master/users/_example) を調べてください。 -より複雑な例については、[`/users/drashna/`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna) のユーザスペースを調べてください。 - - -### カスタマイズされた関数 :id=customized-functions - -QMK には、[`_quantum`、`_kb` および `_user` バージョン](ja/custom_quantum_functions.md#a-word-on-core-vs-keyboards-vs-keymap)を持つ使用可能な[関数](custom_quantum_functions.md)が山ほどあります。 ほとんどの場合、これらの関数のユーザバージョンを使う必要があります。しかし問題はそれらをユーザスペースで使う場合、キーマップで使うことができるバージョンが無いことです。 - -しかし、実際にはキーマップバージョンのサポートを追加し、ユーザスペースとキーマップの両方で使うことができます。 - - -例えば、`layer_state_set_user()` 関数を見てみましょう。全てのキーボードで [Tri Layer State](ja/ref_functions.md#olkb-tri-layers) 機能を有効にしながら、`keymap.c` ファイルで Tri Layer 機能を保持することができます。 - -`` ファイル内で、以下を追加する必要があります: -```c -__attribute__ ((weak)) -layer_state_t layer_state_set_keymap (layer_state_t state) { - return state; -} - -layer_state_t layer_state_set_user (layer_state_t state) { - state = update_tri_layer_state(state, 2, 3, 5); - return layer_state_set_keymap (state); -} -``` -`__attribute__ ((weak))` 部分は、コンパイラにこれが `keymap.c` 内のバージョンに置き換えられるプレースホルダ関数であることを伝えます。そうすれば、`keymap.c` に追加する必要はありませんが、追加しても関数が同じ名前を持つため競合することはありません。 - -ここでの `_keymap` 部分は重要では無く、`_quantum`、`_kb` あるいは `_user` は既に使われているため、それら以外のものである必要があります。`layer_state_set_mine`、`layer_state_set_fn` などを使うことができます。 - -[`users/drashna`](https://github.com/qmk/qmk_firmware/tree/master/users/drashna) 内の [`template.c`](https://github.com/qmk/qmk_firmware/blob/master/users/drashna/template.c) でこのリストと他の一般的な関数を見つけることができます。 - -### カスタム機能 - -ユーザスペース機能は膨大な数のキーボードをサポートすることができるため、特定の機能は有効にしたいが、他のキーボードでは有効にしたくないかもしれません。そして実際に自分のユーザスペースで有効あるいは無効にすることができる「機能」を作成することができます。 - -例えば、(スペースを節約するために)特定のキーボードでのみたくさんのマクロを利用したい場合、それらを `#ifdef MACROS_ENABLED` して「見えないように」してから、キーボードごとに有効にすることができます。これを行うには、以下を rules.mk に追加します。 -```make -ifeq ($(strip $(MACROS_ENABLED)), yes) - OPT_DEFS += -DMACROS_ENABLED -endif -``` -`OPT_DEFS` 設定は `MACROS_ENABLED` がキーボード用に定義されるようにし(名前の前に `-D` があることに注意してください)、c/h ファイルで状態をチェックするために `#ifdef MACROS_ENABLED` を使うことができ、それに基づいてそのコードを処理します。 - -次にキーマップの `rules.mk` に `MACROS_ENABLED = yes` を追加し、ユーザスペースでこの機能とコードを有効にします。 - -そして `process_record_user` 関数の中で、以下のようなことを行います: -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { -#ifdef MACROS_ENABLED - case MACRO1: - if (!record->event.pressed) { - SEND_STRING("This is macro 1!"); - } - break; - case MACRO2: - if (!record->event.pressed) { - SEND_STRING("This is macro 2!"); - } - break; -#endif - } - return true; -} -``` - - -### 結合マクロ - -全てのキーマップについてユーザスペースにマクロやそのほかの関数を統合したい場合は、そうすることができます。これは上記の[カスタマイズ関数](#customized-functions)の例に基づいています。これは異なるキーボード間で共有される大量のマクロを維持し、キーボード固有のマクロも可能です。 - -最初に、全ての `keymap.c` ファイルを調べ、代わりに `process_record_user` を `process_record_keymap` に置き換えます。この方法では、これらのキーボードでキーボード固有のコードを使用でき、カスタムの "global" キーコードも使うことができます。また、`SAFE_RANGE` を `NEW_SAFE_RANGE` に置き換えて、キーコードが重複しないようにすることもできます。 - -次に、全ての keymap.c ファイルに `#include ".h"` を追加します。これにより、各キーマップでそれらを再定義することなく新しいキーコードを使うことができます。 - -それが完了したら、必要なキーコードの定義を `.h` ファイルに設定します。例えば: -```c -#pragma once - -#include "quantum.h" -#include "action.h" -#include "version.h" - -// 全てを定義 -enum custom_keycodes { - KC_MAKE = SAFE_RANGE, - NEW_SAFE_RANGE // キーマップ固有のコードについては "NEW_SAFE_RANGE" を使用 -}; -``` - -ここで、`.c` ファイルを作成し、この内容をそれに追加します: - -```c -#include ".h" - -__attribute__ ((weak)) -bool process_record_keymap(uint16_t keycode, keyrecord_t *record) { - return true; -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case KC_MAKE: // ファームウェアをコンパイルし、キーボードのブートローダに基づく書き込みコマンドを追加します - if (!record->event.pressed) { - uint8_t temp_mod = get_mods(); - uint8_t temp_osm = get_oneshot_mods(); - clear_mods(); clear_oneshot_mods(); - SEND_STRING("make " QMK_KEYBOARD ":" QMK_KEYMAP); - #ifndef FLASH_BOOTLOADER - if ((temp_mod | temp_osm) & MOD_MASK_SHIFT) - #endif - { - SEND_STRING(":flash"); - } - if ((temp_mod | temp_osm) & MOD_MASK_CTRL) { - SEND_STRING(" -j8 --output-sync"); - } - tap_code(KC_ENT); - set_mods(temp_mod); - } - break; - - } - return process_record_keymap(keycode, record); -} -``` - -(マクロパッドのような) Shift ボタンを持たないキーボードについては、ブートローダオプションを常に含める方法が必要です。これを行うには、以下をユーザスペースフォルダ内の `rules.mk` に追加します: - -```make -ifeq ($(strip $(FLASH_BOOTLOADER)), yes) - OPT_DEFS += -DFLASH_BOOTLOADER -endif -``` - -これは任意のキーマップで使うことができる新しい `KC_MAKE` キーコードを追加します。そして、このキーコードは、`make :` を出力するため、頻繁なコンパイルを簡単にします。そして、これは現在のキーボードの情報を出力するため、全てのキーボードとキーマップで動作します。そのため毎回これを入力する必要はありません。 - -また、Shift を押したままにすると書き込みの対象 (`:flash`) をコマンドに追加します。Control を押したままにすると、複数のファイルを一度に処理することでコンパイル時間を短縮する幾つかのコマンドを追加します。 - -そして Shift キーが無いキーボード、あるいは常に書き込みを試したいキーボードについては、キーマップの `rules.mk` に `FLASH_BOOTLOADER = yes` を追加することができます。 - -?> これはブートローダの設定に基づいて正しいユーティリティを使って新しくコンパイルされたファームウェアを自動的に書き込むはずです (あるいはデフォルトで HEX ファイルを生成するだけ)。ただし、これは全てのシステムで動作するわけではないことに注意してください。はっきり言うと、AVRDUDE は WSL では動作しません。そして、これは BootloadHID あるいは mdloader をサポートしません。 diff --git a/docs/ja/feature_velocikey.md b/docs/ja/feature_velocikey.md deleted file mode 100644 index b13969a195e7..000000000000 --- a/docs/ja/feature_velocikey.md +++ /dev/null @@ -1,34 +0,0 @@ -# Velocikey - - - -Velocikey は入力の速度を使って(レインボー渦巻効果のような)ライト効果の速度を制御できる機能です。速く入力すればするほどライトが速くなります! - -## 使用法 -Velocikey を使うためには、2つのステップがあります。最初に、キーボードをコンパイルする時に、`rules.mk` に `VELOCIKEY_ENABLE=yes` を設定する必要があります。例えば: - -``` -MOUSEKEY_ENABLE = no -STENO_ENABLE = no -EXTRAKEY_ENABLE = yes -VELOCIKEY_ENABLE = yes -``` - -次に、キーボードの使用中に、VLK_TOG キーコードを使って Velocikey を有効にする必要もあります。これは機能をオンおよびオフにします。 - -以下の全てのライト効果が、Velocikey を有効にすることで制御されます: -- RGB 明滅動作 -- RGB レインボームード -- RGB レインボー渦巻 -- RGB スネーク -- RGB ナイト - -LED 明滅動作の効果のサポートは計画されていますがまだ利用できません。 - -Velocikey が有効になっている限り、現在オンになっている RGB ライトの他の全ての速度設定に関係なく、速度が制御されます。 - -## 設定 -Velocikey は現在のところキーボード設定を介したどのような設定もサポートしません。速度の増加あるいは減少率などを調整したい場合は、`velocikey.c` を編集し、そこで値を調整して、好みの速度を実現する必要があります。 diff --git a/docs/ja/feature_wpm.md b/docs/ja/feature_wpm.md deleted file mode 100644 index 3cb5e58fcb0f..000000000000 --- a/docs/ja/feature_wpm.md +++ /dev/null @@ -1,24 +0,0 @@ -# Word Per Minute (WPM) の計算 - - - -WPM 機能は、キーストローク間の時間から1分あたりの平均(移動平均)単語数を計算し、様々な用途で利用できるようにします。 - -`rules.mk` に以下を追加することで WPM システムを有効にします: - - WPM_ENABLE = yes - -ソフトシリアルを使っている分割キーボードについては、計算された WPM スコアがマスター側とスレーブ側で利用可能です。 - -## 公開関数 - -`uint8_t get_current_wpm(void);` -この関数は符号なし整数で現在の WPM を返します。 - - -## WPM 計算のためのカスタマイズ化されたキー - -デフォルトでは、WPM スコアは文字、空白、およびいくつかの句読点のみを含みます。WPM の計算に含むとみなす文字セットを変更したい場合は、`wpm_keycode_user(uint16_t keycode)` を実装し、計算に含めたい文字について true を返し、計算しない特定のキーコードに false を返すようにします。 diff --git a/docs/ja/flashing.md b/docs/ja/flashing.md deleted file mode 100644 index ce6646d4fece..000000000000 --- a/docs/ja/flashing.md +++ /dev/null @@ -1,247 +0,0 @@ -# 書き込みの手順とブートローダ情報 - - - -キーボードが使用するブートローダにはかなり多くの種類があり、ほぼ全てが異なる書き込みの方法を使います。幸いなことに、[QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) のようなプロジェクトは、あまり深く考える必要無しに様々なタイプと互換性を持つことを目指していますが、この文章では様々なタイプのブートローダとそれらを書き込むために利用可能な方法について説明します。 - -`rules.mk` の `BOOTLOADER` 変数で選択されたブートローダがある場合、QMK は .hex ファイルがデバイスに書き込むのに適切なサイズかどうかを自動的に計算し、合計サイズをバイト単位で(最大値とともに)出力します。 - -## DFU - -Atmel の DFU ブートローダはデフォルトで全ての atmega32u4 チップに搭載されており、PCB (旧 OLKB キーボード、Clueboard) に独自の IC を持つ多くのキーボードで使われています。一部のキーボードは、LUFA の DFU ブートローダ(または QMK のフォーク) (新しい OLKB キーボード)を使う場合もあり、そのハードウェアに固有の追加機能が追加されます。 - -DFU ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください(オプションとして代わりに `lufa-dfu` や `qmk-dfu` が使えます): - -```make -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp -BOOTLOADER = atmel-dfu -``` - -互換性のあるフラッシャ: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) -* QMK の [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / `:dfu` (推奨のコマンドライン) - -書き込み手順: - -1. `QK_BOOT` キーコードを押すか、RESET ボタンをタップします(または RST を GND にショートします)。 -2. OS がデバイスを検知するのを待ちます。 -3. メモリを消去します(自動的に実行されるかもしれません) -4. .hex ファイルを書き込みます -5. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - -あるいは: - - make ::dfu - -### QMK DFU - -QMK には LUFA DFU ブートローダのフォークがあり、ブートローダを終了してアプリケーションに戻る時に単純なマトリックススキャンを行うことができます。また、何かが起きた時に、LED を点滅したり、スピーカーでカチカチ音をたてたりします。これらの機能を有効にするには、`config.h` で以下のブロックを有効にします (ブートローダを終了するキーは、ここで定義された INPUT と OUTPUT に接続する必要があります): - - #define QMK_ESC_OUTPUT F1 // 通常 COL - #define QMK_ESC_INPUT D5 // 通常 ROW - #define QMK_LED E6 - #define QMK_SPEAKER C6 - -製造元と製品名は `config.h` から自動的に取得され、製品に「Bootloader」が追加されます。 - -このブートローダを生成するには、`bootloader` ターゲット、例えば `make planck/rev4:default:bootloader` を使います。 - -実稼働対応の .hex ファイル(アプリケーションおよびブートローダを含む)を生成するには、`production` ターゲット、例えば `make planck/rev4:default:production` を使います。 - -### DFU コマンド - -ファームウェアを DFU デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 - -* `:dfu` - これが通常のオプションで、DFU デバイスが使用可能になるまで待機したのちファームウェアを書き込みます。5秒ごとに、DFU デバイスが存在するかチェックしています。 -* `:dfu-ee` - 通常の hex ファイルの代わりに `eep` ファイルを書き込みます。これを使用するのはまれです。 -* `:dfu-split-left` - デフォルトオプション (`:dfu`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM ファイルも書き込まれます。_これは、Elite C ベースの分割キーボードに最適です。_ -* `:dfu-split-right` - デフォルトオプション (`:dfu`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM ファイルも書き込まれます。_これは、Elite C ベースの分割キーボードに最適です。_ - -## Caterina - -Arduino ボードとそのクローンは [Caterina ブートローダ](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina) (Pro Micro またはそのクローンで構築されたキーボード)を使用し、avr109 プロトコルを使って仮想シリアルを介して通信します。[A-Star](https://www.pololu.com/docs/0J61/9) のようなブートローダは Caterina に基づいています。 - -Caterina ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: - -```make -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp -BOOTLOADER = caterina -``` - -互換性のあるフラッシャ: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) -* avr109 を使った [avrdude](https://www.nongnu.org/avrdude/) / `:avrdude` (推奨のコマンドライン) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) - -書き込み手順: - -1. `QK_BOOT` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます) -2. OS がデバイスを検知するのを待ちます。 -3. .hex ファイルを書き込みます -4. デバイスが自動的にリセットされるのを待ちます - -あるいは - - make ::avrdude - - -### Caterina コマンド - -ファームウェアを DFU デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 - -* `:avrdude` - これが通常のオプションで、Caterina デバイスが(新しい COM ポートを検出して)使用可能になるまで待機し、ファームウェアを書き込みます。 -* `:avrdude-loop` - これは `:avrdude` と同じコマンドを実行します。ただし書き込みが終了すると再び Caterina デバイスの書き込み待ちに戻ります。これは何台ものデバイスへ書き込むのに便利です。_Ctrl+C を押して、手動でこの繰り返しを終了させる必要があります。_ -* `:avrdude-split-left` - デフォルトオプション (`:avrdude`) と同様に通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM ファイルも書き込まれます。_これは、Pro Micro ベースの分割キーボードに最適です。_ -* `:avrdude-split-right` - デフォルトオプション (`:avrdude`) と同様に通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM ファイルも書き込まれます。_これは、Pro Micro ベースの分割キーボードに最適です。_ - - - -## Halfkay - -Halfkay は PJRC によって開発された超スリムなプロトコルであり、HID を使用し、全ての Teensys (つまり 2.0)に搭載されています。 - -Halfkay ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: - -```make -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp -BOOTLOADER = halfkay -``` - -互換性のあるフラッシャ: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) -* [Teensy ローダー](https://www.pjrc.com/teensy/loader.html) -* [Teensy ローダーコマンドライン](https://www.pjrc.com/teensy/loader_cli.html) (推奨のコマンドライン) - -書き込み手順: - -1. `QK_BOOT` キーコードを押すか、RST をすばやく GND にショートします (入力後7秒で書き込みます) -2. OS がデバイスを検知するのを待ちます。 -3. .hex ファイルを書き込みます -4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - -## USBasploader - -USBasploader は matrixstorm によって開発されたブートローダです。V-USB を実行する ATmega328P のような非 USB AVR チップで使われます。 - -USBasploader ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: - -```make -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp -BOOTLOADER = USBasp -``` - -互換性のあるフラッシャ: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) -* `usbasp` プログラマを使った [avrdude](https://www.nongnu.org/avrdude/) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) - -書き込み手順: - -1. `QK_BOOT` キーコードを押すか、RST を GND にすばやくショートしながら、ブートピンを GND にショートしたままにします。 -2. OS がデバイスを検知するのを待ちます。 -3. .hex ファイルを書き込みます -4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - -## BootloadHID - -BootloadHID は AVR マイクロコントローラ用の USB ブートローダです。アップローダーツールは Windows でカーネルレベルのドライバを必要としないため、DLL をインストールせずに実行することができます。 - -bootloadHID ブートローダとの互換性を確保するために、以下のブロックが `rules.mk` にあることを確認してください: - -```make -# Bootloader selection -# Teensy halfkay -# Pro Micro caterina -# Atmel DFU atmel-dfu -# LUFA DFU lufa-dfu -# QMK DFU qmk-dfu -# ATmega32A bootloadHID -# ATmega328P USBasp -BOOTLOADER = bootloadHID -``` - -互換性のあるフラッシャ: - -* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) (推奨の Windows GUI) -* [bootloadhid コマンドライン](https://www.obdev.at/products/vusb/bootloadhid.html) / QMK の `:BootloadHID` (推奨のコマンドライン) - -書き込み手順: - -1. 以下のいずれかの方法を使ってブートローダに入ります: - * `QK_BOOT` キーコードをタップします (全てのデバイスでは動作しないかもしれません) - * キーボードを接続しながらソルトキーを押し続けます (通常はキーボードの readme に書かれています) -2. OS がデバイスを検知するのを待ちます。 -3. .hex ファイルを書き込みます -4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - -あるいは: - - make ::bootloadHID - -## STM32 - -全ての STM32 チップには、変更も削除もできない工場出荷時のブートローダがプリロードされています。一部の STM32 チップには USB プログラミングが付属していないブートローダがありますが(例えば STM32F103)、プロセスは同じです。 - -現時点では、STM32 の `rules.mk` には、`BOOTLOADER` 変数は不要です。 - -互換性のあるフラッシャ: - -* [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) (推奨の GUI) -* [dfu-util](https://github.com/Stefan-Schmidt/dfu-util) / `:dfu-util` (推奨のコマンドライン) - -書き込み手順: - -1. 以下のいずれかの方法を使ってブートローダに入ります: - * `QK_BOOT` キーコードをタップします (STM32F042 デバイスでは動作しないかもしれません) - * リセット回路が存在する場合、RESET ボタンをタップします - * それ以外の場合は、(BOOT0 ボタンあるいはブリッジ経由で)BOOT0 を VCC にブリッジし、(REEST ボタンあるいはブリッジ経由で)RESET を GND にショートし、BOOT0 ブリッジを放す必要があります。 -2. OS がデバイスを検知するのを待ちます。 -3. .bin ファイルを書き込みます - * DFU 署名に関する警告が表示されます; 無視してください -4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - * コマンドラインからビルドする場合(例えば、`make planck/rev6:default:dfu-util`)、`rules.mk` の中で `:leave` が `DFU_ARGS` 変数に渡されるようにしてください (例えば、`DFU_ARGS = -d 0483:df11 -a 0 -s 0x08000000:leave`)。そうすれば、書き込みの後でデバイスがリセットされます - -### STM32 コマンド - -ファームウェアを STM32 デバイスに書き込むために使用できる DFU コマンドがいくつかあります。 - -* `:dfu-util` - STM32 デバイスに書き込むためのデフォルトコマンドで、STM32 ブートローダデバイスが見つかるまで待機します。 -* `:dfu-util-split-left` - デフォルトのオプション (`:dfu-util`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「左側の」 EEPROM の設定も行われます。 -* `:dfu-util-split-right` - デフォルトのオプション (`:dfu-util`) と同様に、通常のファームウェアが書き込まれます。ただし、分割キーボードの「右側の」 EEPROM の設定も行われます。 -* `:st-link-cli` - dfu-util ではなく、ST-LINK の CLI ユーティリティを介してファームウェアを書き込めます。 -* `:st-flash` - dfu-util ではなく、[STLink Tools](https://github.com/stlink-org/stlink) の `st-flash` ユーティリティを介してファームウェアを書き込めます。 diff --git a/docs/ja/flashing_bootloadhid.md b/docs/ja/flashing_bootloadhid.md deleted file mode 100644 index 5c67bd5f293d..000000000000 --- a/docs/ja/flashing_bootloadhid.md +++ /dev/null @@ -1,75 +0,0 @@ -# BootloadHID の書き込み手順とブートローダの情報 - - - -ps2avr(GB) キーボードは ATmega32A マイクロコントローラを使い、異なるブートローダを使います。それは通常の QMK の方法を使って書き込むことができません。 - -一般的な書き込みシーケンス: - -1. 以下のいずれかの方法を使ってブートローダに入ります: - * `QK_BOOT` キーコードをタップします (全てのデバイスでは動作しないかもしれません) - * ソルトキーを押し続けながらキーボードを接続します (通常はキーボードの readme に書かれています) -2. OS がデバイスを検知するのを待ちます。 -3. .hex ファイルを書き込みます -4. デバイスをアプリケーションモードにリセットします(自動的に実行されるかもしれません) - -## bootloadHID の書き込みターゲット - -?> [こちら](ja/newbs_getting_started.md)で詳しく説明されている QMK インストールスクリプトを使うと、必要な bootloadHID ツールが自動的にインストールされます。 - -コマンドライン経由で書き込むには、以下のコマンドを実行してターゲット `:bootloadHID` を使います: - - make ::bootloadHID - -## GUI 書き込み - -### Windows -1. [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) をダウンロードします。 -2. キーボードをリセットします。 -3. 設定された VendorID が `16c0` で、ProductID が `05df` であることを確認します -4. `Find Device` ボタンを押し、キーボードが見つかることを確認します。 -5. `Open .hex File` ボタンを押し、作成した `.hex` ファイルを見つけます。 -6. `Flash Device` ボタンを押し、処理が完了するまで待ちます。 - -## コマンドライン書き込み - -1. キーボードをリセットします。 -2. `bootloadHID -r` に続けて `.hex` ファイルへのパスを入力し、キーボードに書き込みます。 - -### Windows 手動インストール -MSYS2の場合: -1. https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz から BootloadHID ファームウェアパッケージをダウンロードします。 -2. 互換性のあるツール、例えば 7-Zip を使って内容を抽出します。 -3. 解凍された書庫から MSYS2 インストール先、通常 `C:\msys64\usr\bin` に `commandline/bootloadHID.exe` をコピーして、MSYS パスに追加します。 - -ネイティブの Windows 書き込みの場合、MSYS2 環境の外部で `bootloadHID.exe` を使うことができます。 - -### Linux 手動インストール -1. libusb development の依存関係をインストールします: - ```bash - # これは OS に依存します - Debian については以下で動作します -sudo apt-get install libusb-dev - ``` -2. BootloadHID ファームウェアパッケージをダウンロードします: - ``` - wget https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -O - | tar -xz -C /tmp - ``` -3. bootloadHID 実行可能ファイルをビルドします: - ``` - cd /tmp/bootloadHID.2012-12-08/commandline/ -make -sudo cp bootloadHID /usr/local/bin - ``` - -### MacOS 手動インストール -1. 以下を入力して Homebrew をインストールします: - ``` - /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - ``` -2. 以下のパッケージをインストールします: - ``` - brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb - ``` diff --git a/docs/ja/getting_started_docker.md b/docs/ja/getting_started_docker.md deleted file mode 100644 index ceaebb01792b..000000000000 --- a/docs/ja/getting_started_docker.md +++ /dev/null @@ -1,60 +0,0 @@ -# Docker クイックスタート - - - -このプロジェクトは、プライマリオペレーティングシステムに大きな変更を加えることなくキーボードの新しいファームウェアを非常に簡単に構築することができる Docker ワークフローを含みます。これは、あなたがプロジェクトをクローンしビルドを実行した時に、他の人とまったく同じ環境と QMK ビルド基盤を持つことも保証します。これにより、人々はあなたが遭遇した問題の解決をより簡単に行えるようになります。 - -## 必要事項 - -主な前提条件は動作する `docker` または `podman` がインストールされていることです。 -* [Docker CE](https://docs.docker.com/install/#supported-platforms) -* [Podman](https://podman.io/getting-started/installation) - -## 使い方 - -(サブモジュールを含む) QMK のレポジトリのローカルコピーを取得する: - -```bash -git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git -cd qmk_firmware -``` - -キーマップをビルドするために以下のコマンドを実行します: -```bash -util/docker_build.sh : -# 例えば: util/docker_build.sh planck/rev6:default -``` - -これは目的のキーボード/キーマップをコンパイルし、結果として書き込み用に `.hex` あるいは `.bin` ファイルを QMK ディレクトリの中に残します。`:keymap` が省略された場合は全てのキーマップが使われます。パラメータの形式は、`make` を使ってビルドする時と同じであることに注意してください。 - -`target` を指定して Docker から直接キーボードをビルドし、_かつ_ 書き込むためのサポートもあります。 - -```bash -util/docker_build.sh keyboard:keymap:target -# 例えば: util/docker_build.sh planck/rev6:default:flash -``` - -スクリプトをパラメータ無しで開始することもできます。この場合、1つずつビルドパラメータを入力するように求められます。これが使いやすいと思うかもしれません: - -```bash -util/docker_build.sh -# パラメータを入力として読み込みます (空白にすると全てのキーボード/キーマップ) -``` - -`RUNTIME` 環境変数にコンテナランタイム名やパスを設定することで、使用したいコンテナランタイムを手動で設定できます。 -デフォルトでは docker や podman は自動的に検出され、podman より docker が優先されます。 - -```bash -RUNTIME="podman" util/docker_build.sh keyboard:keymap:target -``` - -## FAQ - -### なぜ Windows/macOS 上で書き込めないのですか? - -Windows と macOS では、実行するために [Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/) が必要です。これはセットアップが面倒なので、お勧めではありません: 代わりに [QMK Toolbox](https://github.com/qmk/qmk_toolbox) を使ってください。 - -!> Docker for Windows は [Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v) を有効にする必要があります。これは、Windows 7、Windows 8 および **Windows 10 Home** のような Hyper-V を搭載していない Windows のバージョンでは機能しないことを意味します。 diff --git a/docs/ja/getting_started_github.md b/docs/ja/getting_started_github.md deleted file mode 100644 index 640701148869..000000000000 --- a/docs/ja/getting_started_github.md +++ /dev/null @@ -1,69 +0,0 @@ -# QMK で GitHub を使う方法 - - - -GitHub は慣れていない人には少し注意が必要です - このガイドは、QMK におけるフォーク、クローン、プルリクエストのサブミットの各ステップについて説明します。 - -?> このガイドでは、あなたがコマンドラインでの実行にある程度慣れており、システムに git がインストールされていることを前提にしています。 - -[QMK GitHub ページ](https://github.com/qmk/qmk_firmware)を開くと、右上に "Fork" というボタンが見えます: - -![GitHub でのフォーク](https://i.imgur.com/8Toomz4.jpg) - -あなたが組織の一員である場合は、どのアカウントにフォークするかを選択する必要があります。ほとんどの場合、あなたの個人のアカウントにフォークしたいでしょう。フォークが完了したら(しばらく時間が掛かる場合があります)、"Clone or Download" ボタンをクリックします: - -![GitHub からダウンロード](https://i.imgur.com/N1NYcSz.jpg) - -必ず "HTTPS" を選択し、リンクを選択してコピーします: - -![HTTPS リンク](https://i.imgur.com/eGO0ohO.jpg) - -ここから、`git clone --recurse-submodules ` をコマンドラインに入力し、リンクを貼り付けます: - -``` -user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git -Cloning into 'qmk_firmware'... -remote: Enumerating objects: 9, done. -remote: Counting objects: 100% (9/9), done. -remote: Compressing objects: 100% (5/5), done. -remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 -Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. -Resolving deltas: 100% (119972/119972), done. -... -Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' -Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' -Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' -Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' -``` - -ローカルマシンに QMK のフォークができるので、キーマップの追加、コンパイル、キーボードへの書き込みができます。変更に満足したら、以下のようにそれらをフォークへ追加、コミットおよびプッシュすることができます: - -``` -user@computer:~$ git add . -user@computer:~$ git commit -m "adding my keymap" -[master cccb1608] adding my keymap - 1 file changed, 1 insertion(+) - create mode 100644 keyboards/planck/keymaps/mine/keymap.c -user@computer:~$ git push -Counting objects: 1, done. -Delta compression using up to 4 threads. -Compressing objects: 100% (1/1), done. -Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. -Total 1 (delta 1), reused 0 (delta 0) -remote: Resolving deltas: 100% (1/1), completed with 1 local objects. -To https://github.com/whoeveryouare/qmk_firmware.git - + 20043e64...7da94ac5 master -> master -``` - -あなたの変更は今では GitHub 上のフォークにあります - フォーク (`https://github.com//qmk_firmware`)に戻ると、"New Pull Request" ボタンをクリックすることで新しいプルリクエストを作成することができます: - -![New Pull Request](https://i.imgur.com/DxMHpJ8.jpg) - -ここでは、コミットした内容を正確に確認することができます - 全て良いように見える場合は、"Create Pull Request" をクリックすることで最終的に承認することができます: - -![Create Pull Request](https://i.imgur.com/Ojydlaj.jpg) - -サブミットの後で、私たちはあなたの変更について話し、変更を依頼し、最終的にそれを受け入れるでしょう!QMK に貢献してくれてありがとう :) diff --git a/docs/ja/getting_started_introduction.md b/docs/ja/getting_started_introduction.md deleted file mode 100644 index a55391e0a1c0..000000000000 --- a/docs/ja/getting_started_introduction.md +++ /dev/null @@ -1,65 +0,0 @@ -# はじめに - - - -このページでは、QMK プロジェクトで作業するために知っておくべき基本的な情報について説明しようと思います。Unix シェルの操作に精通していることを前提としていますが、C について、または make を使ったコンパイルについて精通しているとは想定していません。 - -## 基本的な QMK の構造 - -QMK は [Jun Wako](https://github.com/tmk) の [tmk_keyboard](https://github.com/tmk/tmk_keyboard) プロジェクトのフォークです。変更された元の TMK コードは、`tmk_core` フォルダで見つけることができます。プロジェクトへの QMK の追加は、`quantum` フォルダで見つけることができます。キーボードプロジェクトは `handwired` および `keyboard` フォルダで見つけることができます。 - -### ユーザスペースの構造 - -`users` フォルダ内は各ユーザのためのディレクトリです。これはユーザがキーボード間で使うかもしれないコードを置くためのフォルダです。詳細は[ユーザスペース機能](ja/feature_userspace.md) のドキュメントを見てください。 - -### キーボードプロジェクトの構造 - -`keyboards` フォルダ、そのサブフォルダ `handwired`、ベンダと製品のサブディレクトリ (例えば、`clueboard`) の中には、各キーボードプロジェクトのためのディレクトリ (例えば `qmk_firmware/keyboards/clueboard/2x1800`) があります。その中には、以下の構造があります: - -* `keymaps/`: ビルドできる様々なキーマップ -* `rules.mk`: デフォルトの "make" オプションを設定するファイル。このファイルを直接編集しないでください。代わりにキーマップ固有の `rules.mk` を使ってください。 -* `config.h`: デフォルトのコンパイル時のオプションを設定するファイル。このファイルを直接編集しないでください。代わりにキーマップ固有の `config.h` を使ってください。 -* `info.json`: QMK Configurator のためのレイアウトの設定に使われるファイル。詳細は [Configurator サポート](ja/reference_configurator_support.md)を見てください。 -* `readme.md`: キーボードの簡単な概要 -* `.h`: このファイルは、キーボードのスイッチマトリックスに対してキーボードレイアウトが定義されるファイルです。 -* `.c`: このファイルには、キーボードのためのカスタムコードがあります。 - -プロジェクトの構造についての詳細は、[QMK キーボードガイドライン](ja/hardware_keyboard_guidelines.md)を見てください。 - -### キーマップ構造 - -全てのキーマップフォルダには、以下のファイルがあります。`keymap.c` だけが必須で、残りのファイルが見つからない場合は、デフォルトのオプションが選択されます。 - -* `config.h`: キーマップを設定するためのオプション -* `keymap.c`: 全てのキーマップコード。必須 -* `rules.mk`: 有効になっている QMK の機能 -* `readme.md`: キーマップの説明。他の人が使う方法および機能の説明。imgur のようなサービスに画像をアップロードしてください。 - -# `config.h` ファイル - -3つの `config.h` の場所が考えられます: - -* キーボード (`/keyboards//config.h`) -* ユーザスペース (`/users//config.h`) -* キーマップ (`/keyboards//keymaps//config.h`) - -ビルドシステムは自動的に上の順に config ファイルを取得します。前の `config.h` で設定された設定を上書きしたい場合は、変更したい設定の準備のために最初に定型コードを置く必要があります。 - -``` -#pragma once -``` - -次に、前の `config.h` ファイルの設定を上書きするために、設定を `#undef` し再び `#define` する必要があります。 - -定型コードと設定は、以下のようになります: - -``` -#pragma once - -// ここに上書きします! -#undef MY_SETTING -#define MY_SETTING 4 -``` diff --git a/docs/ja/getting_started_make_guide.md b/docs/ja/getting_started_make_guide.md deleted file mode 100644 index 07d7f0597a47..000000000000 --- a/docs/ja/getting_started_make_guide.md +++ /dev/null @@ -1,161 +0,0 @@ -# より詳細な `make` 手順 - - - -`make` コマンドの完全な構文は `::` です: - -* `` はキーボードのパスです。例えば、`planck` - * 全てのキーボードをコンパイルするには `all` を使います。 - * リビジョンを選択してコンパイルするためのパスを指定します。例えば `planck/rev4` あるいは `planck/rev3` - * キーボードにフォルダが無い場合は、省略することができます - * デフォルトのフォルダをコンパイルする場合は、省略することができます -* `` はキーマップの名前です。例えば、`algernon` - * 全てのキーマップをコンパイルするには `all` を使います。 -* `` の詳細は以下で説明します。 - -`` は以下を意味します -* target が指定されない場合は、以下の `all` と同じです -* `all` は指定されたキーボード/リビジョン/キーマップの可能な全ての組み合わせのコンパイルを行います。例えば、`make planck/rev4:default` は1つの .hex を生成しますが、`make planck/rev4:all` は planck で利用可能な全てのキーマップについて hex を生成します。 -* `flash`、`dfu`、`teensy`、`avrdude`、`dfu-util`、`bootloadHID` はファームウェアをコンパイルし、キーボードにアップロードします。コンパイルが失敗すると、何もアップロードされません。使用するプログラマはキーボードに依存します。ほとんどのキーボードでは `dfu` ですが、ChibiOS キーボードについては `dfu-util` 、標準的な Teensy については `teensy` を使います。キーボードに使うコマンドを見つけるには、キーボード固有の readme をチェックしてください。 - 利用可能なブートローダの詳細は[ファームウェアの書き込み](ja/flashing.md)ガイドを参照してください。 - * **Note**: 一部のオペレーティングシステムでは、これらのコマンドが機能するためには特権アクセスが必要です。これは、root アクセスなしでこれらにアクセスするために [`udev ルール`](ja/faq_build.md#linux-udev-rules) を設定するか、あるいは root アクセスでコマンドを実行する (`sudo make planck/rev4:default:flash`) 必要があるかもしれないことを意味します。 -* `clean` は、全てをゼロからビルドするためにビルド出力フォルダを掃除します。説明できない問題がある場合は、通常のコンパイルの前にこれを実行してください。 -* `distclean` は、.hex ファイルと .bin ファイルを削除します。 - -次のターゲットは開発者向けです: - -* `show_path` ソースとオブジェクトファイルのパスを表示します。 -* `dump_vars` makefile 変数をダンプします。 -* `objs-size` 個々のオブジェクトファイルのサイズを表示します。 -* `show_build_options` 'rules.mk' のオプションセットを表示します。 -* `check-md5` 生成されたバイナリファイルの md5 チェックサムを表示します。 - -make コマンドの最後、つまり target の後に追加のオプションを追加することもできます - -* `make COLOR=false` - カラー出力をオフ -* `make SILENT=true` - エラー/警告以外の出力をオフ -* `make VERBOSE=true` - 全ての gcc のものを出力 (デバッグする必要が無い限り面白くありません) -* `make VERBOSE_LD_CMD=yes` - -v オプションを指定して ld コマンドを実行します。 -* `make VERBOSE_AS_CMD=yes` - -v オプションを指定して as コマンドを実行します。 -* `make VERBOSE_C_CMD=` - 指定された C ソースファイルをコンパイルするときに -v オプションを追加します。 -* `make DUMP_C_MACROS=` - 指定された C ソースファイルをコンパイルするときにプリプロセッサマクロをダンプします。 -* `make DUMP_C_MACROS= > ` - 指定された C ソースファイルをコンパイルするときにプリプロセッサマクロを `` にダンプします。 -* `make VERBOSE_C_INCLUDE=` - 指定された C ソースファイルをコンパイルするときにインクルードされるファイル名をダンプします。 -* `make VERBOSE_C_INCLUDE= 2> ` - 指定された C ソースファイルをコンパイルするときにインクルードされるファイル名を `` にダンプします。 - -make コマンド自体にもいくつかの追加オプションがあります。詳細は `make --help` を入力してください。最も有用なのはおそらく `-jx` です。これは複数の CPU を使ってコンパイルしたいことを指定し、`x` は使用したい CPU の数を表します。設定すると、特に多くのキーボード/キーマップをコンパイルしている場合は、コンパイル時間を大幅に短縮することができます。通常は、コンパイル中に他の作業を行うための余裕をもたせるために、持っている CPU の数より1つ少ない値に設定します。全てのオペレーティングシステムと make バージョンがオプションをサポートしているわけではないことに注意してください。 - -コマンドの例を幾つか示します - -* `make all:all` は、全てをビルドします (全てのキーボードフォルダ、全てのキーマップ)。`root` から単に `make` を実行すると、これを実行します。 -* `make ergodox_infinity:algernon:clean` は、Ergodox Infinity キーボードのビルド出力を掃除します。 -* `make planck/rev4:default:flash COLOR=false` カラー出力なしでキーマップをビルドしアップロードします。 - -## `rules.mk` オプション - -無効にするにはこれらの変数を `no` に設定します。有効にするには `yes` に設定します。 - -`BOOTMAGIC_ENABLE` - -これにより、1つのキーとソルトキー(デフォルトではスペース)を押し続けることで、電力が失われても持続する様々な EEPROM 設定へアクセスできます。誤って設定が変更されることが多く、デバッグするのが難しい混乱した結果を生成するため、これを無効にしておくことをお勧めします。ヘルプセッションで発生する、より一般的な問題の1つです。 - -`MOUSEKEY_ENABLE` - -これにより、キーコード/カスタム関数を介して、カーソルの動きとクリックを制御することができます。 - -`EXTRAKEY_ENABLE` - -これにより、システムとオーディオ制御キーコードを使うことができます。 - -`CONSOLE_ENABLE` - -これにより、[`hid_listen`](https://www.pjrc.com/teensy/hid_listen.html) を使って読むことができるメッセージを出力することができます。 - -デフォルトで、全てのデバッグ( *dprint* ) 出力 ( *print*、*xprintf* )、およびユーザ出力 ( *uprint* ) メッセージが有効になります。これにより、フラッシュメモリの大部分が消費され、キーボードの .hex ファイルが大きすぎてプログラムできなくなるかもしれません。 - -デバッグメッセージ( *dprint* ) を無効にし、.hex ファイルのサイズを小さくするには、`config.h` に `#define NO_DEBUG` を含めます。 - -出力メッセージ( *print*、*xprintf* )とユーザ出力( *uprint* ) を無効にし、.hex のファイルサイズを小さくするには、`config.h` に `#define NO_PRINT` を含めます。 - -出力メッセージ ( *print*、*xprintf* ) を無効にし、ユーザメッセージ ( *uprint* )を**そのままにする**には、`config.h` に `#define USER_PRINT` を含めます(この場合は、`#define NO_PRINT` も含めないでください)。 - -テキストを見るには、`hid_listen` を開き、出力メッセージを見るのを楽しんでください。 - -**注意:** キーマップコード以外の *uprint* メッセージを含めないでください。QMK システムフレームワーク内で使うべきではありません。さもないと、他の人の .hex ファイルが肥大化します。 - -`COMMAND_ENABLE` - -これはマジックコマンドを有効にし、通常はデフォルトのマジックキーの組み合わせ `LSHIFT+RSHIFT+KEY` で起動されます。マジックコマンドは、デバッグメッセージ (`MAGIC+D`) の有効化や NKRO の一時的な切り替え (`MAGIC+N`) を含みます。 - -`SLEEP_LED_ENABLE` - -コンピュータがスリープの間に LED がブレスできるようにします。ここでは Timer1 が使われます。この機能は大部分が未使用でテストされておらず、更新もしくは抽象化が必要です。 - -`NKRO_ENABLE` - -これにより、キーボードはホスト OS に最大 248 個のキーが同時に押されていることを伝えることができます (NKRO 無しのデフォルトは 6 です)。NKRO は、`NKRO_ENABLE` が設定されていたとしても、デフォルトではオフです。config.h に `#define FORCE_NKRO` を追加するか、`MAGIC_TOGGLE_NKRO` をキーにバインドしてキーを押すことで、NKRO を強制することができます。 - -`BACKLIGHT_ENABLE` - -これはスイッチ内の LED のバックライトを有効にします。`config.h` 内に以下を入れることでバックライトピンを指定することができます: - - #define BACKLIGHT_PIN B7 - -`MIDI_ENABLE` - -キーボードで MIDI の送受信を有効にします。MIDI 送信モードに入るためにキーコード `MI_ON` を使うことができ、オフにするために `MI_OFF` を使うことができます。これはほとんどテストされていない機能ですが、詳細については `quantum/quantum.c` ファイルで見つけることができます。 - -`UNICODE_ENABLE` - -これによりキーマップで `UC()` を使って Unicode 文字を送信することができます。`0x7FFF` までのコードポイントがサポートされます。これはほとんどの現代言語の文字と記号を対象にしますが、絵文字は対象外です。 - -`UNICODEMAP_ENABLE` - -これによりキーマップで `X()` を使って Unicode 文字を送信することができます。キーマップファイル内にマッピングテーブルを保持する必要があります。可能な全てのコードポイント( `0x10FFFF` まで)がサポートされます。 - -`UCIS_ENABLE` - -これにより、送信したい文字に対応するニーモニックを入力することで Unicode 文字を送信することができます。キーマップファイル内にマッピングテーブルを保持する必要があります。可能な全てのコードポイント( `0x10FFFF` まで)がサポートされます。 - -詳細と制限については、[Unicode ページ](ja/feature_unicode.md)を見てください。 - -`AUDIO_ENABLE` - -C6 ピン(抽象化が必要)でオーディオ出力できます。詳細は[オーディオページ](ja/feature_audio.md)を見てください。 - -`VARIABLE_TRACE` - -これを使って変数の値の変更をデバッグします。詳細についてはユニットテストのページの[変数のトレース](ja/unit_testing.md#tracing-variables)のセクションを見てください。 - -`API_SYSEX_ENABLE` - -これにより Quantum SYSEX API を使って文字列を(どこかに?)送信することができます - -`KEY_LOCK_ENABLE` - -これは[キーロック](ja/feature_key_lock.md)を有効にします。 - -`SPLIT_KEYBOARD` - -分割キーボード (let's split や bakingpy's boards のようなデュアル MCU) のサポートを有効にし、quantum/split_common にある全ての必要なファイルをインクルードします - -`SPLIT_TRANSPORT` - -ARM ベースの分割キーボード用の標準分割通信ドライバはまだ無いため、これらのために `SPLIT_TRANSPORT = custom` を使わなければなりません。カスタムの実装が使われるようにすることで、標準の分割キーボード通信コード(AVR 固有)が含まれないようにします。 - -`CUSTOM_MATRIX` - -デフォルトのマトリックス走査ルーチンを独自のコードで置き換えます。詳細については、[カスタムマトリックスページ](ja/custom_matrix.md)を見てください。 - -`DEBOUNCE_TYPE` - -デフォルトのキーデバウンスルーチンを別のものに置き換えます。`custom` の場合、独自の実装を提供する必要があります。 - -## キーマップごとに Makefile オプションをカスタマイズ - -あなたのキーマップディレクトリに `rules.mk` というファイルがある場合、そのファイルで設定した全てのオプションは、あなたのキーボードの他の `rules.mk` オプションよりも優先されます。 - -あなたのキーボードの `rules.mk` に `BACKLIGHT_ENABLE = yes` があるとします。あなたの特定のキーボードでバックライトが無いようにするには、`rules.mk` というファイルを作成し、`BACKLIGHT_ENABLE = no` を指定します。 diff --git a/docs/ja/gpio_control.md b/docs/ja/gpio_control.md deleted file mode 100644 index 7bece3e0c7ca..000000000000 --- a/docs/ja/gpio_control.md +++ /dev/null @@ -1,47 +0,0 @@ -# GPIO 制御 :id=gpio-control - - - -QMK には、マイクロコントローラに依存しない GPIO 制御抽象レイヤーがあります。これは異なるプラットフォーム間でピン制御に簡単にアクセスできるようにするためのものです。 - -## 関数 :id=functions - -以下の関数は GPIO の基本的な制御を提供し、`quantum/quantum.h` にあります。 - -| 関数 | 説明 | 古い AVR の例 | 古い ChibiOS/ARM の例 | -|------------------------|--------------------------------------------------|-------------------------------------------------|-------------------------------------------------| -| `setPinInput(pin)` | ピンを高インピーダンス(High-Z)の入力として設定 | `DDRB &= ~(1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT)` | -| `setPinInputHigh(pin)` | ピンを組み込みのプルアップ抵抗付きの入力として設定 | `DDRB &= ~(1<<2); PORTB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_INPUT_PULLUP)` | -| `setPinInputLow(pin)` | ピンを組み込みのプルダウン抵抗付きの入力として設定 | N/A (AVR ではサポートされません) | `palSetLineMode(pin, PAL_MODE_INPUT_PULLDOWN)` | -| `setPinOutput(pin)` | ピンを出力として設定 | `DDRB \|= (1<<2)` | `palSetLineMode(pin, PAL_MODE_OUTPUT_PUSHPULL)` | -| `writePinHigh(pin)` | ピンレベルを high に設定 (ピンを出力として設定してあると仮定) | `PORTB \|= (1<<2)` | `palSetLine(pin)` | -| `writePinLow(pin)` | ピンレベルを low に設定 (ピンを出力として設定してあると仮定) | `PORTB &= ~(1<<2)` | `palClearLine(pin)` | -| `writePin(pin, level)` | ピンレベルを設定 (ピンを出力として設定してあると仮定) | `(level) ? PORTB \|= (1<<2) : PORTB &= ~(1<<2)` | `(level) ? palSetLine(pin) : palClearLine(pin)` | -| `readPin(pin)` | ピンのレベルを返す | `_SFR_IO8(pin >> 4) & _BV(pin & 0xF)` | `palReadLine(pin)` | -| `togglePin(pin)` | ピンレベルを反転 (ピンを出力として設定してあると仮定) | `PORTB ^= (1<<2)` | `palToggleLine(pin)` | - -## 高度な設定 :id=advanced-settings - -各マイクロコントローラは GPIO に関して複数の高度な設定を持つことができます。この抽象レイヤーは、アーキテクチャー固有の機能の使用法を制限しません。上級ユーザは、目的のデバイスのデータシートを参照し、必要なライブラリを含めてください。AVR については、標準 avr/io.h ライブラリが使われます; STM32 については ChibiOS [PAL ライブラリ](https://chibios.sourceforge.net/docs3/hal/group___p_a_l.html)が使われます。 - -## アトミック操作 :id=atomic-operation - -上記の関数は、必ずしもアトミックに動作することが保証されているわけではありません。そのため、上記の関数を複数組み合わせて使用する際に、操作の途中での割り込みを防ぎたい場合は、以下の `ATOMIC_BLOCK_FORCEON` マクロを使用してください。 - -例: -```c -void some_function() { - // 通常の処理 - ATOMIC_BLOCK_FORCEON { - // アトミックであることが必要な処理 - } - // 通常の処理 -} -``` - -`ATOMIC_BLOCK_FORCEON` は、ブロックが実行される前に、割り込みが有効か無効かに関わらず、強制的に割り込みを無効にします。そして、ブロックが実行された後に、割り込みを有効にします。 - -したがって、`ATOMIC_BLOCK_FORCEON`は、ブロックの実行前に割り込みが有効になっていることがわかっている場合や、ブロックの完了時に割り込みを有効にしても問題ないことがわかっている場合のみ使用できることに注意してください。 diff --git a/docs/ja/hardware_avr.md b/docs/ja/hardware_avr.md deleted file mode 100644 index cdc5f8cb8662..000000000000 --- a/docs/ja/hardware_avr.md +++ /dev/null @@ -1,190 +0,0 @@ -# AVR マイコンを使ったキーボード - - - -このページでは QMK における AVR マイコンのサポートについて説明します。AVR マイコンには、Atmel 社製の atmega32u4、atmega32u2、at90usb1286 やその他のマイコンを含みます。AVR マイコンは、簡単に動かせるよう設計された8ビットの MCU です。キーボードでよく使用される AVR マイコンには USB 機能や大きなキーボードマトリックスのためのたくさんの GPIO を搭載しています。これらは、現在、キーボードで使われる最も一般的な MCU です。 - -まだ読んでない場合は、[キーボードガイドライン](ja/hardware_keyboard_guidelines.md) を読んで、キーボードを QMK にどのように適合させるかを把握する必要があります。 - -## AVR を使用したキーボードを QMK に追加する - -QMK には AVR を使ったキーボードでの作業を簡略化するための機能が多数あります。大体のキーボードでは1行もコードを書く必要がありません。まずはじめに、`qmk new-keyboard` を実行します。 - -``` -$ qmk new-keyboard -Ψ Generating a new QMK keyboard directory - -Keyboard Name: mycoolkeeb -Keyboard Type: - 1. avr - 2. ps2avrgb -Please enter your choice: [1] -Your Name: [John Smith] -Ψ Copying base template files... -Ψ Copying avr template files... -Ψ Renaming keyboard.[ch] to mycoolkeeb.[ch]... -Ψ Replacing %YEAR% with 2021... -Ψ Replacing %KEYBOARD% with mycoolkeeb... -Ψ Replacing %YOUR_NAME% with John Smith... - -Ψ Created a new keyboard called mycoolkeeb. -Ψ To start working on things, `cd` into keyboards/mycoolkeeb, -Ψ or open the directory in your preferred text editor. -``` - -これにより、新しいキーボードをサポートするために必要なすべてのファイルが作成され、デフォルト値で設定が入力されます。あとはあなたのキーボード用にカスタマイズするだけです。 - -## `readme.md` - -このファイルではキーボードに関する説明を記述します。[キーボード Readme テンプレート](ja/documentation_templates.md#keyboard-readmemd-template)に従って `readme.md` を記入して下さい。`readme.md` の上部に画像を配置することをお勧めします。画像は [Imgur](https://imgur.com) のような外部サービスを利用してください。 - -## `.c` - -このファイルではキーボード上で実行される全てのカスタマイズされたロジックを記述します。多くのキーボードの場合、何も書く必要はありません。 -[機能のカスタマイズ](ja/custom_quantum_functions.md)で、カスタマイズされたロジックの記述方法を詳しく学ぶことが出来ます。 - -## `.h` - -このファイルでは、[レイアウト](ja/feature_layouts.md)を定義します。最低限、以下のような `#define LAYOUT` を記述する必要があります。 - -```c -#define LAYOUT( \ - k00, k01, k02, \ - k10, k11 \ -) { \ - { k00, k01, k02 }, \ - { k10, KC_NO, k11 }, \ -} -``` - -`LAYOUT` マクロの前半部ではキーの物理的な配置を定義します。後半部ではスイッチが接続されるマトリックスを定義します。これによってマトリックス配線の順とは異なるキーを物理的に配置できます。 - -それぞれの `k__` 変数はユニークでなければいけません。通常は `k` というフォーマットに従って記述されます。 - -物理マトリックス(後半部)では、`MATRIX_ROWS` に等しい行数が必要であり、各行には正確に `MATRIX_COLS` と等しい数の要素が含まれていなければいけません。物理キーが存在しない場合は、`KC_NO` を使用して空白を埋める事ができます。 - -## `config.h` - -`config.h` ファイルには、ハードウェアや機能の設定を記述します。このファイルで設定できるオプションは列挙しきれないほどたくさんあります。利用できるオプションの概要は[設定オプション](ja/config_options.md)を参照して下さい。 - -### ハードウェアの設定 - -`config.h` の先頭には USB に関する設定があります。これらはキーボードが OS からどのように見えるかを制御しています。変更する理由がない場合は、`VENDOR_ID` を `0xFEED` のままにしておく必要があります。`PRODUCT_ID` にはまだ使用されていない番号を選ばなければいけません。 - -`MANUFACTURER`、 `PRODUCT` をキーボードにあった設定に変更します。 - -```c -#define VENDOR_ID 0xFEED -#define PRODUCT_ID 0x6060 -#define DEVICE_VER 0x0001 -#define MANUFACTURER You -#define PRODUCT my_awesome_keyboard -``` - -?> Windows や macOS では、`MANUFACTURER` と `PRODUCT` が USBデバイスのリストに表示されます。Linux 上の `lsusb` では、代わりに [USB ID Repository](http://www.linux-usb.org/usb-ids.html) によって維持されているリストの値を優先します。デフォルトでは、リストに `VENDOR_ID` / `PRODUCT_ID` を含まない場合にのみ、`MANUFACTURER` と `PRODUCT` を使います。`sudo lsusb -v` を使用するとデバイスから示された値を表示します。また、接続したときのカーネルログにも表示されます。 - -### キーボードマトリックスの設定 - -`config.h` ファイルの次のセクションではキーボードのマトリックスを扱います。最初に設定するのはマトリックスのサイズです。これは通常、常にではありませんが、物理キー配置と同じ数の行・列になります。 - -```c -#define MATRIX_ROWS 2 -#define MATRIX_COLS 3 -``` - -マトリックスのサイズを定義したら、MCU のどのピンを行と列に接続するかを定義します。そのためにはピンの名前を指定するだけです。 - -```c -#define MATRIX_ROW_PINS { D0, D5 } -#define MATRIX_COL_PINS { F1, F0, B0 } -#define UNUSED_PINS -``` - - -`MATRIX_ROW_PINS` の要素の数は `MATRIX_ROWS` に定義した数と同じでなければいけません。同様に `MATRIX_COL_PINS` の要素の数も `MATRIX_COLS` と等しい必要があります。`UNUSED_PINS` は定義しなくても問題ありませんがどのピンが空いているのか記録しておきたい場合は定義できます。 - -最後にダイオードの方向を定義します。これには `COL2ROW` か `ROW2COL` を設定します。 - -```c -#define DIODE_DIRECTION COL2ROW -``` - -#### ダイレクトピンマトリックス - -各スイッチが、列と行のピンを共有する代わりに、それぞれ個別のピンとグランドに接続されているキーボードを定義するには、`DIRECT_PINS` を使用します。マッピング定義では、列と行の各スイッチのピンを左から右の順に定義します。`MATRIX_ROWS` と `MATRIX_COLS` 内のサイズに準拠する必要があり、空白を埋めるには `NO_PIN` を使用します。これによって `DIODE_DIRECTION`、`MATRIX_ROW_PINS`、`MATRIX_COL_PINS` の動作を上書きします。 - -```c -// #define MATRIX_ROW_PINS { D0, D5 } -// #define MATRIX_COL_PINS { F1, F0, B0 } -#define DIRECT_PINS { \ - { F1, E6, B0, B2, B3 }, \ - { F5, F0, B1, B7, D2 }, \ - { F6, F7, C7, D5, D3 }, \ - { B5, C6, B6, NO_PIN, NO_PIN } \ -} -#define UNUSED_PINS - -/* COL2ROW, ROW2COL */ -//#define DIODE_DIRECTION -``` - -### バックライトの設定 - -QMK では GPIO ピンでのバックライト制御をサポートしています。これらの設定を選択して MCU から制御できます。詳しくは[バックライト](ja/feature_backlight.md)を参照して下さい。 - -```c -#define BACKLIGHT_PIN B7 -#define BACKLIGHT_LEVELS 3 -#define BACKLIGHT_BREATHING -#define BREATHING_PERIOD 6 -``` - -### その他の設定オプション - -`config.h` で設定・調整できる機能はたくさんあります。詳しくは[設定オプション](ja/config_options.md)を参照して下さい。 - -## `rules.mk` - -`rules.mk` ファイルを使用して、ビルドするファイルや有効にする機能をQMKへ指示します。atmega32u4 を使っている場合、これらのオプションはデフォルトのままにしておくことが出来ます。他の MCU を使用している場合はいくつかのパラメータを調整する必要があります。 - -### MCU オプション - -このオプションではビルドする CPU をビルドシステムに指示します。これらの設定を変更する場合は非常に注意して下さい。キーボードを操作不能にしてしまう可能性があります。 - -```make -MCU = atmega32u4 -F_CPU = 16000000 -ARCH = AVR8 -F_USB = $(F_CPU) -OPT_DEFS += -DINTERRUPT_CONTROL_ENDPOINT -``` - -### ブートローダー - -ブートローダーは MCU に保存されているプログラムをアップグレードするための特別なセクションです。キーボードのレスキューパーティションのようなものだと考えて下さい。 - -#### Teensy Bootloader の例 - -```make -BOOTLOADER = halfkay -``` - -#### Atmel DFU Loader の例 - -```make -BOOTLOADER = atmel-dfu -``` - -#### Pro Micro Bootloader の例 - -```make -BOOTLOADER = caterina -``` - -### ビルドオプション - -`rules.mk` にはオン・オフできるたくさんの機能があります。詳細なリストと説明は[設定オプション](ja/config_options.md#feature-options)を参照して下さい。 diff --git a/docs/ja/hardware_drivers.md b/docs/ja/hardware_drivers.md deleted file mode 100644 index e0061cb32802..000000000000 --- a/docs/ja/hardware_drivers.md +++ /dev/null @@ -1,41 +0,0 @@ -# QMK ハードウェアドライバー - - - -QMK はたくさんの異なるハードウェアで使われています。最も一般的な MCU とマトリックス構成をサポートしていますが、キーボードへ他のハードウェアを追加し制御するためのドライバーもいくつか用意されています。例えば、マウスやポインティングデバイス、分割キーボード用の IO エキスパンダ、Bluetooth モジュール、LCD、OLED、TFT 液晶などがあります。 - - - -# 使用できるドライバー - -## ProMicro (AVR のみ) - -ProMicro のピンを AVR の名前ではなく、Arduino の名前で指定できます。この部分はより詳しく文書化される必要があります。もしこれを使用したい場合にコードを読んでも分からない場合、[issue を開く](https://github.com/qmk/qmk_firmware/issues/new)を通して助けることができるかもしれません。 - -## SSD1306 OLED ドライバー - -SSD1306 ベースの OLED ディスプレイのサポート。詳しくは[OLED ドライバ](ja/feature_oled_driver.md)を参照して下さい。 - -## WS2812 - -WS2811/WS2812{a,b,c} LED のサポート。 詳しくは [RGB ライト](ja/feature_rgblight.md)を参照して下さい。 - -## IS31FL3731 - -最大2つの LED ドライバーのサポート。各ドライバーは、I2C を使って個別に LED を制御する2つのチャーリープレクスマトリックスを実装しています。最大144個の単色 LED か32個の RGB LED を使用できます。ドライバーの設定方法の詳細は[RGB マトリックス](ja/feature_rgb_matrix.md)を参照して下さい。 - -## IS31FL3733 - -拡張の余地がある最大1つの LED ドライバーのサポート。各ドライバーは192個の単色 LED か64個の RGB LED を制御できます。ドライバーの設定方法の詳細は [RGB マトリックス](ja/feature_rgb_matrix.md)を参照して下さい。 - -## 24xx シリーズ 外部 I2C EEPROM - -オンチップ EEPROM の代わりに使用する I2C ベースの外部 EEPROM のサポート。ドライバーの設定方法の詳細は [EEPROM ドライバー](ja/eeprom_driver.md)を参照して下さい。 diff --git a/docs/ja/hardware_keyboard_guidelines.md b/docs/ja/hardware_keyboard_guidelines.md deleted file mode 100644 index ef5f6df2b901..000000000000 --- a/docs/ja/hardware_keyboard_guidelines.md +++ /dev/null @@ -1,239 +0,0 @@ -# QMK キーボードガイドライン - - - -QMK は開始以来、コミュニティにおけるキーボードの作成や保守に貢献しているあなたのような人たちのおかげで飛躍的に成長しました。私たちが成長するにつれて、うまくやるためのいくつかのパターンを発見しました。他の人たちがあなたの苦労の恩恵を受けやすくするため、それにあわせてもらえるようお願いします。 - -## QMK Lint を使う - -キーボードの問題をチェックできるツール、`qmk lint` を提供しています。キーボードとキーマップで作業をしている間は、頻繁に使うことをお勧めします。 - -チェックに合格した例: - -``` -$ qmk lint -kb rominronin/katana60/rev2 -Ψ Lint check passed! -``` - -チェックに失敗した例: - -``` -$ qmk lint -kb clueboard/66/rev3 -☒ Missing keyboards/clueboard/66/rev3/readme.md -☒ Lint check failed! -``` - -## あなたのキーボード/プロジェクトの名前を決める - -キーボードの名前は全て小文字で、アルファベット、数字、アンダースコア(`_`)のみで構成されています。アンダースコア(`_`)で始めてはいけません。スラッシュ(`/`)はサブフォルダの区切り文字として使用されます。 - -`test`、`keyboard`、`all` はmakeコマンド用に予約されており、キーボードまたはサブフォルダ名として使用することは出来ません。 - -正しい例: - -* `412_64` -* `chimera_ortho` -* `clueboard/66/rev3` -* `planck` -* `v60_type_r` - -## サブフォルダ - -QMK では、まとめるためや同じキーボードのリビジョン間でコードを共有するためにサブフォルダを使用します。フォルダは最大4階層までネストできます。 - - qmk_firmware/keyboards/top_folder/sub_1/sub_2/sub_3/sub_4 - -サブフォルダ内に `rules.mk` ファイルが存在するとコンパイル可能なキーボードとして見なされます。QMK Configurator から使用できるようになり、`make all` でテストされます。同じメーカーのキーボードをまとめるためにフォルダを使用している場合は `rules.mk` ファイルを置いてはいけません。 - -例: - -Clueboard は、サブフォルダをまとめるためとキーボードのリビジョン管理の両方のために使用しています。 - -* [`qmk_firmware`](https://github.com/qmk/qmk_firmware/tree/master) - * [`keyboards`](https://github.com/qmk/qmk_firmware/tree/master/keyboards) - * [`clueboard`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard) ← これはまとめるためのフォルダです。 `rules.mk` ファイルはありません。 - * [`60`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/60) ← これはコンパイルできるキーボードです。`rules.mk` が存在します。 - * [`66`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66) ← これもコンパイルできるキーボードです。 デフォルトのリビジョンとして `DEFAULT_FOLDER` に `rev3` を指定しています。 - * [`rev1`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev1) ← コンパイル可能: `make clueboard/66/rev1` - * [`rev2`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev2) ← コンパイル可能: `make clueboard/66/rev2` - * [`rev3`](https://github.com/qmk/qmk_firmware/tree/master/keyboards/clueboard/66/rev3) ← コンパイル可能: `make clueboard/66/rev3` もしくは `make clueboard/66` - -## キーボードのフォルダ構成 - -キーボードは `qmk_firmware/keyboards/` 内にあり、前のセクションで説明したようにフォルダ名はキーボードの名前にする必要があります。このフォルダ内にはいくつかのファイルがあります。 - -* `readme.md` -* `info.json` -* `config.h` -* `rules.mk` -* `.c` -* `.h` - -### `readme.md` - -全てのプロジェクトにはどのようなキーボードなのか、誰が設計したか、どこで入手できるかを説明する `readme.md` ファイルが必要です。もしあれば、メーカーの Web サイトなどの詳しい情報へのリンクも含める必要があります。[キーボード readme テンプレート](ja/documentation_templates.md#keyboard-readmemd-template)を参考にして下さい。 - -### `info.json` - -このファイルは [QMK API](https://github.com/qmk/qmk_api) から使用されます。[QMK Configurator](https://config.qmk.fm/) が必要とするキーボードの情報が含まれています。ここでメタデータを設定することもできます。詳しくは [info.json 形式](ja/reference_info_json.md) を参照して下さい。 - -### `config.h` - -全てのプロジェクトには、マトリックスサイズ、製品名、USB VID/PID、説明、その他の設定などが含まれた `config.h` ファイルが必要です。一般に、このファイルを使用して常に機能するキーボードの重要な情報やデフォルトを設定します。 - -また、`config.h` ファイルはサブフォルダにも置くことができ、その読み込み順は以下の通りです。 - -* `keyboards/top_folder/config.h` - * `keyboards/top_folder/sub_1/config.h` - * `keyboards/top_folder/sub_1/sub_2/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/config.h` - * `users/a_user_folder/config.h` - * `keyboards/top_folder/keymaps/a_keymap/config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/post_config.h` - * `keyboards/top_folder/sub_1/sub_2/sub_3/post_config.h` - * `keyboards/top_folder/sub_1/sub_2/post_config.h` - * `keyboards/top_folder/sub_1/post_config.h` -* `keyboards/top_folder/post_config.h` - -`post_config.h` ファイルは、`config.h` ファイルで指定された内容に応じて、追加の後処理を行うために使用することができます。 -例えば、キーマップレベルの `config.h` ファイルで `IOS_DEVICE_ENABLE` マクロを以下のように定義すると、`post_config.h` ファイルでより詳細な設定を行うことができます。 - -* `keyboards/top_folder/keymaps/a_keymap/config.h` - ```c - #define IOS_DEVICE_ENABLE - ``` -* `keyboards/top_folder/post_config.h` - ```c - #ifndef IOS_DEVICE_ENABLE - // USB_MAX_POWER_CONSUMPTION value for this keyboard - #define USB_MAX_POWER_CONSUMPTION 400 - #else - // fix iPhone and iPad power adapter issue - // iOS device need lessthan 100 - #define USB_MAX_POWER_CONSUMPTION 100 - #endif - - #ifdef RGBLIGHT_ENABLE - #ifndef IOS_DEVICE_ENABLE - #define RGBLIGHT_LIMIT_VAL 200 - #define RGBLIGHT_VAL_STEP 17 - #else - #define RGBLIGHT_LIMIT_VAL 35 - #define RGBLIGHT_VAL_STEP 4 - #endif - #ifndef RGBLIGHT_HUE_STEP - #define RGBLIGHT_HUE_STEP 10 - #endif - #ifndef RGBLIGHT_SAT_STEP - #define RGBLIGHT_SAT_STEP 17 - #endif - #endif - ``` - -?> 上記の例のように `post_config.h` でオプションを定義する場合、キーボードやユーザレベルの `config.h` で同じオプションを定義してはいけません。 - -### `rules.mk` - -このファイルが存在するということは、フォルダがキーボードであり、`make` コマンドで使用できることを意味します。ここでキーボードのビルド環境を構築し、デフォルトの機能を設定します。 - -`rules.mk` ファイルはサブフォルダにも置くことができ、その読み込み順は以下の通りです。 - -* `keyboards/top_folder/rules.mk` - * `keyboards/top_folder/sub_1/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/rules.mk` - * `keyboards/top_folder/sub_1/sub_2/sub_3/sub_4/rules.mk` - * `keyboards/top_folder/keymaps/a_keymap/rules.mk` - * `users/a_user_folder/rules.mk` -* `common_features.mk` - -`rules.mk` ファイルに書かれた多くの設定は `common_features.mk` によって解釈され、必要なソースファイルやコンパイラのオプションが設定されます。 - -?> 詳しくは `build_keyboard.mk` と `common_features.mk` を見てください。 - -### `` - -ここではキーボードのカスタマイズされたコードを記述します。通常、初期化してキーボードのハードウェアを制御するコードを記述します。キーボードが LED やスピーカー、その他付属ハードウェアのないキーマトリックスのみで構成されている場合は空にできます。 - -通常、以下の関数がこのファイルで定義されます。 - -* `void matrix_init_kb(void)` -* `void matrix_scan_kb(void)` -* `bool process_record_kb(uint16_t keycode, keyrecord_t *record)` -* `bool led_update_kb(led_t led_state)` - -### `` - -このファイルはキーボードのマトリックスを定義するために使用されます。配列をキーボードの物理的なスイッチマトリックスに変換する C マクロを最低限1つ定義する必要があります。複数のレイアウトでキーボードを構築出来る場合は、追加のマクロを定義しなければいけません。 - -レイアウトが1つしかない場合は、このマクロは `LAYOUT` とします。 - -複数のレイアウトを定義する場合、物理的に構成することが出来なくとも、マトリックス上で全てのスイッチ位置をサポートする `LAYOUT_all` という名前の基本となるレイアウトが必要です。これは `default` キーマップで使用すべきマクロです。次に、他のレイアウトマクロを使用する `default_` といった追加のキーマップを用意します。これによって、他の人が定義されたレイアウトを使いやすくなります。 - -レイアウトマクロの名前は全て小文字で、先頭の `LAYOUT` だけ大文字です。 - -例として、ANSI と ISO をサポートする 60% PCB がある場合、以下のようにレイアウトとキーマップを定義出来ます。 - -| レイアウト名 | キーマップ名 | 説明 | -|-------------|-------------|-------------| -| LAYOUT_all | default | ISO と ANSI のどちらもサポートしたレイアウト | -| LAYOUT_ansi | default_ansi | ANSI レイアウト | -| LAYOUT_iso | default_iso | ISO レイアウト | - -## 画像/ハードウェアのファイル - -リポジトリのサイズを小さく保つために、いくつかの例外を除いて、どの形式のバイナリファイルも受け入れないようになりました。外部の場所(など)でホストして、`readme.md` でリンクすることをおすすめします。 - -ハードウェアのファイル(プレートやケース、PCB など)は [qmk.fm リポジトリ](https://github.com/qmk/qmk.fm)に提供でき、[qmk.fm](https://qmk.fm) で利用可能になります。ダウンロード出来るファイルは `//`(名前は上記と同じ形式)に保存され、`https://qmk.fm//` で提供されます。ページは `/_pages//` から生成されて、同じ場所で提供されます( .mdファイルはJekyllを通して .htmlファイル変換されます)。`lets_split` ファイルを参照して下さい。 - -## キーボードのデフォルト設定 - -QMK が提供する機能の量を考えれば、新しいユーザーが混乱するのは当たり前です。キーボードのデフォルトファームウェアをまとめるなら、有効にする機能とオプションをハードウェアのサポートに必要な最低限のセットにすることをおすすめします。特定の機能に関するおすすめは以下の通りです。 - -### ブートマジックとコマンド - -[ブートマジック](ja/feature_bootmagic.md) と[コマンド](ja/feature_command.md)は、ユーザーがキーボードを明白でない方法で制御出来るようにする2つの関連機能です。いずれかの機能を有効にする場合、この機能をどのように提供するかについて、よく考えることをおすすめします。この機能が必要なユーザーは、あなたのキーボードを最初のプログラムできるキーボードとして使用している初心者に影響を与えることなく、個人的なキーマップ内で有効に出来ることを覚えておきましょう。 - -新規ユーザーが遭遇する最も多い問題は、キーボードを接続している間に間違えてブートマジックをトリガーしてしまうことです。キーボードの下を持っているとき、知らない間に Alt とスペースバーを押して、これらのキーが交換されてしまったことに気づきます。デフォルトではこの機能を無効にすることをおすすめしますが、有効にする場合は、キーボードを接続している間に押し間違えないキーへ `BOOTMAGIC_KEY_SALT` を設定することを検討して下さい。 - -キーボードに2つの Shift キーがない場合は、`COMMAND_ENABLE = no` を指定していても `IS_COMMAND` が動作するデフォルトを設定しておくべきです。ユーザーがコマンドを有効化したときに使用するデフォルトが与えられます。 - -## カスタムキーボードプログラミング - -[機能のカスタマイズ](ja/custom_quantum_functions.md)にあるようにキーボードのカスタム関数を定義できます。ユーザーも同様にその動作をカスタマイズしたいかもしれないということと、ユーザーにそれを可能にすることを忘れないで下さい。 `process_record_kb()`のようなカスタム関数を提供している場合、関数がその関数の `_user()` 版を呼び出すことを確認して下さい。また、その関数の`_user()` 版の戻り値を確認して、user が `true` を返した場合のみカスタムコードを実行しなければいけません。 - -## 生産しない/手配線 プロジェクト - -プロトタイプや手配線によるものなど QMK を使用するどんなプロジェクトも受け入れますが、`/keyboards/` フォルダが乱雑になるのを防ぐために、`/keyboards/handwired/` を用意しています。いつかプロトタイプのプロジェクトが製品のプロジェクトになった時点でメインの `/keyboards/` フォルダへ移動します! - -## エラーとしての警告 - -キーボードを開発するときは、全ての警告がエラーとして扱われることに注意して下さい。小さな警告が蓄積されて、将来大きなエラーを引き起こす可能性があります。(そして、警告を放っておくのは良くない習慣です) - -## 著作権表示 - -別のプロジェクトを元にしてキーボードの設定をするものの同じコードを使用しない場合は、ファイル上部にある著作権表示を次の形式に従って自分の名前を表示するよう、更新して下さい。 - - Copyright 2017 Your Name - - -他の人のコードを修正し、その変更が些細な部分のみであれば、著作権表示の名前をそのままにしておかないといけません。ファイルに対して重要な作業を行った場合、以下のようにあなたの名前を追加します。 - - Copyright 2017 Their Name Your Name - -年はファイルが作成された最初の年にします。後年にそのファイルに対して作業が行われた場合、次のように2つ目の年を追加して反映することが出来ます。 - - Copyright 2015-2017 Your Name - -## ライセンス - -QMK のコア部分は [GNU General Public License](https://www.gnu.org/licenses/licenses.en.html) でライセンスされます。AVR マイコン用のバイナリを提供する場合は、[GPLv2](https://www.gnu.org/licenses/old-licenses/gpl-2.0.html) か、[GPLv3](https://www.gnu.org/licenses/gpl.html) のどちらかから選択出来ます。ARM マイコン用のバイナリを提供する場合は、 [ChibiOS](https://www.chibios.org) の GPLv3 ライセンスに準拠するため、[GPL Version 3](https://www.gnu.org/licenses/gpl.html) を選択しなければいけません。 - -## 技術的な詳細 - -キーボードを QMK で動作させるための詳細は[ハードウェア](ja/hardware.md)を参照して下さい! diff --git a/docs/ja/how_a_matrix_works.md b/docs/ja/how_a_matrix_works.md deleted file mode 100644 index e5dfc9f07d8a..000000000000 --- a/docs/ja/how_a_matrix_works.md +++ /dev/null @@ -1,104 +0,0 @@ -# キーボードマトリックスの仕組み - - - -キーボードスイッチのマトリックスは行と列に配置されます。マトリックス回路がなければ、各スイッチはコントローラに直接配線する必要があります。 - -回路が行と列に配置されている場合、キーが押されると、列ワイヤが行ワイヤと接触し、回路が完成します。キーボードコントローラはこの閉回路を検知し、キー押下として登録します。 - -マイクロコントローラはファームウェアを介してセットアップされ、論理1を一度に1つずつ列に送信し、行から一度に全てを読み取ります - このプロセスはマトリックススキャンと呼ばれます。マトリックスはデフォルトでは電流の通過を許可しないたくさんの開いたスイッチです - ファームウェアはキーが押されていないものとしてこれを読み取ります。1つのキーを押すとすぐに、キースイッチが接続されている列から来ていた論理1がスイッチを通過して対応する行に渡されます - 以下の 2x2 の例を確認してください: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - row0 ---(key0)---(key1) row0 ---(key0)---(key1) - | | | | - row1 ---(key2)---(key3) row1 ---(key2)---(key3) - -`x` は関連付けられた列と行の値が1であるか、HIGH であることを表します。ここでは、キーが押されていないことが分かります。そのため `x` を取得する行はありません。1つのキースイッチの二つの接点はそのスイッチのある行と列にそれぞれ接続されていることに注意してください。 - -`key0` を押すと、`col0` は `row0` に接続されるため、ファームウェアがその行に対して受け取る値は `0b01` です (ここで `0b` はこれがビット値であることを意味します。つまり次の数字は全てビット(0または1)であり、その列のキーを表します)。この表記を使用して、キースイッチが押されたことを示し、列と行が接続されていることを示します: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - x row0 ---(-+-0)---(key1) row0 ---(-+-0)---(key1) - | | | | - row1 ---(key2)---(key3) row1 ---(key2)---(key3) - -`row0` には `x` があるため、値が1であることがわかります。全体として、`key0` が押された時にファームウェアが受信するデータは、 - - col0: 0b01 - col1: 0b00 - │└row0 - └row1 - -一度に複数のキーを押し始めると問題が発生します。マトリックスをもう一度見ると、かなり明白になっているはずです: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - | | | | - x row0 ---(-+-0)---(-+-1) x row0 ---(-+-0)---(-+-1) - | | | | - x row1 ---(key2)---(-+-3) x row1 ---(key2)---(-+-3) - - Remember that this ^ is still connected to row1 - -これから取得されるデータは以下の通りです: - - col0: 0b11 - col1: 0b11 - │└row0 - └row1 - -4つ全てではなく、3つのキーしか押されていないため、これは正確ではありません。この挙動はゴーストと呼ばれ、このような奇妙なシナリオでのみ発生しますが、より大きなキーボードではより一般的です。これを回避する方法は、キースイッチの後に、行に接続する前にダイオードを配置することです。ダイオードは、電流が一方向にのみ流れるようにします。これにより、前の例で他の列と行がアクティブにならないようにします。ダイオードマトリックスをこのように表します; - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - │ │ | │ - (key0) (key1) (key0) (key1) - ! │ ! │ ! | ! │ - row0 ─────┴────────┘ │ row0 ─────┴────────┘ │ - │ │ | │ - (key2) (key3) (key2) (key3) - ! ! ! ! - row1 ─────┴────────┘ row1 ─────┴────────┘ - -実際の用途では、ダイオードの黒い線が行に面するように、キースイッチから離れるように配置されます - この場合の `!` はダイオードで、隙間は黒い線を表します。これを覚える良い方法は、以下のシンボルを考えることです: `>|` - -次に、3つのキーを押して、ゴーストシナリオとなるものを実施します: - - Column 0 being scanned Column 1 being scanned - x x - col0 col1 col0 col1 - │ │ │ │ - (┌─┤0) (┌─┤1) (┌─┤0) (┌─┤1) - ! │ ! │ ! │ ! │ - x row0 ─────┴────────┘ │ x row0 ─────┴────────┘ │ - │ │ │ │ - (key2) (┌─┘3) (key2) (┌─┘3) - ! ! ! ! - row1 ─────┴────────┘ x row1 ─────┴────────┘ - -全てが期待通りに動きます!これにより、以下のデータが取得されます: - - col0: 0b01 - col1: 0b11 - │└row0 - └row1 - -ファームウェアはこの正しいデータを使って、何をすべきかを、最終的には OS に送信する必要のある信号を検出できます。 - -参考文献: -- [Wikipedia の記事](https://en.wikipedia.org/wiki/Keyboard_matrix_circuit) -- [Deskthority の記事](https://deskthority.net/wiki/Keyboard_matrix) -- [Dave Dribin による Keyboard Matrix Help (2000)](https://www.dribin.org/dave/keyboard/one_html/) -- [PCBheaven による How Key Matrices Works](https://pcbheaven.com/wikipages/How_Key_Matrices_Works/) (アニメーションの例) -- [キーボードの仕組み - QMK ドキュメント](ja/how_keyboards_work.md) diff --git a/docs/ja/how_keyboards_work.md b/docs/ja/how_keyboards_work.md deleted file mode 100644 index 5c54e5ff73cd..000000000000 --- a/docs/ja/how_keyboards_work.md +++ /dev/null @@ -1,74 +0,0 @@ -# キーが登録され、コンピュータで解釈される仕組み - - - -このファイルでは、USB を介してキーボードがどのように動作するかの概念を学習できます。ファームウェアを直接変更することで何が期待できるかをより良く理解することができます。 - -## 概略図 - -特定のキーを1つ入力するたびに、このような一連のアクションが発生します: - -```text -+------+ +-----+ +----------+ +----------+ +----+ -| User |-------->| Key |------>| Firmware |----->| USB wire |---->| OS | -+------+ +-----+ +----------+ +----------+ +----+ -``` - -この図は何が起こっているかを非常に単純に示したものです。詳細については次のセクションで説明します。 - -## 1. キーを押す - -キーを押すたびに、キーボードのファームウェアはこのイベントを登録することができます。 -キーが押され、保持され、放された時に登録することができます。 - -これは通常キー押下の定期的な走査で発生します。多くの場合、キーの機械的な応答時間、キー押下情報を転送するプロトコル(ここでは USB HID)、あるいは使用されるソフトウェアによって、この速度は制限されます。 - -## 2. ファームウェアが送信するもの - -[HID 仕様](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf)では、適切に認識されるためにキーボードが USB 経由で実際に送信できるものを規定しています。これには、`0x00` から `0xE7` までの単純な数字であるスキャンコードの定義済リストが含まれます。ファームウェアはスキャンコードをキーボードのそれぞれのキーに割り当てます。 - -ファームウェアは実際の文字を送信せず、スキャンコードだけを送信します。 -従って、ファームウェアを変更することで、特定のキーにたいして USB を介してどのスキャンコードが送信されるかだけを変更することができます。 - -## 3. イベント入力やカーネルが行うこと - -*スキャンコード*は、[マスターブランチの 60-keyboard.hwdb](https://github.com/systemd/systemd/blob/master/hwdb.d/60-keyboard.hwdb) キーボードに依存する*キーコード*にマップされます。このマッピングが無いと、オペレーティングシステムは有効なキーコードを受信せず、キー押下で何も有用なことができません。 - -## 4. オペレーティングシステムがすること - -キーコードがオペレーティングシステムに到達すると、ソフトウェアの一部はキーボードのレイアウトによって、実際の文字と照合しなければなりません。例えば、レイアウトが QWERTY に設定されている場合、照合テーブルの例は以下の通りです: - -| キーコード | 文字 | -|---------|-----------| -| 0x04 | a/A | -| 0x05 | b/B | -| 0x06 | c/C | -| ... | ... | -| 0x1C | y/Y | -| 0x1D | z/Z | -| ... | ... | - -## 説明をファームウェアに戻して - -(独自のものを作成していない限り)レイアウトは一般的に固定されているため、ファームウェアは実際には作業を簡単するためレイアウト名で直接キーコードを記述できます。これが、`KC_A` が実際に QWERTY で `0x04` を表す場合に行われることです。完全なリストは[キーコード](ja/keycodes.md)にあります。 - -## 送信できる文字のリスト - -ショートカットを別として、限られたキーコードのセットが限られたレイアウトにマップされていることは、**指定されたキーに割り当てることができる文字のリストは、レイアウト内に存在するものだけである**ことを意味します。 - -例えば、QWERTY US レイアウトがあり、1つのキーを `€` (ユーロ通貨記号)を生成するように割り当てたい場合、そうすることができないことを意味します。なぜなら、QWERTY US レイアウトはそのようなマッピングを持たないためです。QWERTY UK レイアウト、あるいは QWERTY US International を使うことでそれを修正することができます。 - -全ての Unicode を含むキーボードレイアウトがなぜ考案されていないのか疑問に思うかもしれません。USB を介して利用可能なキーコードの数の制限により、このようなことは許可されません。 - -## (おそらく) Unicode 文字を入力する方法 - -ファームウェアに *一連のキー* を送信させて、目的のオペレーティングシステムの[ソフトウェア Unicode インプットメソッド](https://en.wikipedia.org/wiki/Unicode_input#Hexadecimal_input)を使うことができます。このようにして、OS で定義されたレイアウトとは無関係に文字を効率的に入力することができます。 - -ただし、以下のような複数の欠点があります: - -- 一度に、一つの特定の OS に縛られます (OS を変更する時に再コンパイルする必要があります); -- 特定の OS では、全てのソフトウェアが動作するわけではありません; -- 一部のシステムでは Unicode のサブセットに制限されます。 diff --git a/docs/ja/i2c_driver.md b/docs/ja/i2c_driver.md deleted file mode 100644 index 1d8f70e1636e..000000000000 --- a/docs/ja/i2c_driver.md +++ /dev/null @@ -1,135 +0,0 @@ -# I2C マスタドライバ :id=i2c-master-driver - - - -QMK で使われる I2C マスタドライバには、MCU 間のポータビリティを提供するための一連の関数が用意されています。 - -## I2C アドレスについての重要なメモ :id=note-on-i2c-addresses - -このドライバが期待する全てのアドレスは、アドレスバイトの上位7ビットにプッシュする必要があります。最下位ビットの設定(読み込み/書き込みを示す)は、それぞれの関数によって行われます。データシートやインターネットで列挙されているほとんど全ての I2C アドレスは、下位7ビットを占める7ビットとして表され、1ビット左(より上位)にシフトする必要があります。これは、ビット単位のシフト演算子 `<< 1` を使用して簡単に実行できます。 - -これは、呼び出しごとに以下の関数を実行するか、アドレスの定義で1度だけ実行するかどちらかで行うことができます。例えば、デバイスのアドレスが `0x18` の場合: - -`#define MY_I2C_ADDRESS (0x18 << 1)` - -I2C アドレスと他の技術詳細について、さらなる情報を得るためには https://www.robot-electronics.co.uk/i2c-tutorial を見てください。 - -## 使用できる関数 :id=available-functions - -| 関数 | 説明 | -|-------------------------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `void i2c_init(void);` | I2C ドライバを初期化します。他のあらゆるトランザクションを開始する前に、この関数を一度だけ呼ぶ必要があります。 | -| `i2c_status_t i2c_start(uint8_t address, uint16_t timeout);` | I2C トランザクションを開始します。アドレスは方向ビットのない7ビットスレーブアドレスです。 | -| `i2c_status_t i2c_transmit(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを送信します。アドレスは方向ビットのない7ビットスレーブアドレスです。トランザクションのステータスを返します。 | -| `i2c_status_t i2c_receive(uint8_t address, uint8_t* data, uint16_t length, uint16_t timeout);` | I2C 経由でデータを受信します。アドレスは方向ビットのない7ビットスレーブアドレスです。 `length` で指定した長さのバイト列を `data` に保存し、トランザクションのステータスを返します。 | -| `i2c_status_t i2c_writeReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_transmit` と同様ですが、 `regaddr` でスレーブのデータ書き込み先のレジスタを指定します。 | -| `i2c_status_t i2c_readReg(uint8_t devaddr, uint8_t regaddr, uint8_t* data, uint16_t length, uint16_t timeout);` | `i2c_receive` と同様ですが、 `regaddr` でスレーブのデータ読み込み先のレジスタを指定します。 | -| `i2c_status_t i2c_stop(void);` | I2C トランザクションを終了します。 | - -### 関数の戻り値 :id=function-return - -`void i2c_init(void)` を除く上にあるすべての関数は、次の真理値表にある値を返します。 - -|戻り値の定数 |値 |説明 | -|--------------------|---|----------------------------| -|`I2C_STATUS_SUCCESS`|0 |処理が正常に実行されました。| -|`I2C_STATUS_ERROR` |-1 |処理に失敗しました。 | -|`I2C_STATUS_TIMEOUT`|-2 |処理がタイムアウトしました。| - -## AVR :id=avr - -### 設定 :id=avr-configuration - -I2Cマスタドライバを設定するために、次の定義が使えます。 - -| 変数 | 説明 | 既定値 | -|---------|---------------------|--------| -| `F_SCL` | クロック周波数 (Hz) | 400KHz | - - -AVR は通常 I2C ピンとして使う GPIO が設定されているので、これ以上の設定は必要ありません。 - -## ARM :id=arm - -ARM の場合は、内部に ChibiOS I2C HAL ドライバがあります。この節では STM32 MCU を使用していると仮定します。 - -### 設定 :id=arm-configuration - -ARM MCU 用の設定はしばしば非常に複雑です。これは、多くの場合複数の I2C ドライバをさまざまなポートに対して割り当てられるためです。 - -最初に、必要なハードウェアドライバを有効にするために `mcuconf.h` ファイルをセットアップします。 - -| 変数 | 説明 | 既定値 | -|-------------------------------|------------------------------------------------------------------------------------------------|--------| -| `#STM32_I2C_USE_XXX` | ハードウェアドライバ XXX の有効化/無効化(すべてのドライバを明示的にリストアップする必要あり) | FALSE | -| `#STM32_I2C_BUSY_TIMEOUT` | レスポンスの受信がない場合に I2C コマンドを中断するまでの時間 (ms) | 50 | -| `#STM32_I2C_XXX_IRQ_PRIORITY` | ハードウェアドライバ XXX の割り込み優先度(上級者向けの設定) | 10 | -| `#STM32_I2C_USE_DMA` | MCU がデータ送信を DMA ユニットにオフロードする機能の有効化/無効化 | TRUE | -| `#STM32_I2C_XXX_DMA_PRIORITY` | ハードウェアドライバ XXX に使用する DMA ユニットの優先度(上級者向けの設定) | 1 | - -次に `halconf.h` ファイル内で `#define HAL_USE_I2C` を `TRUE` にします。これにより ChibiOS が I2C ドライバを読み込みます。 - -最後に、使用したい I2C ハードウェアドライバに応じて正しい GPIO ピンを割り当てます。 - -標準では I2C1 ハードウェアドライバが使われます。もし他のハードウェアドライバを使う場合、 `config.h` ファイルに `#define I2C_DRIVER I2CDX` を追加します( X は使用するハードウェアドライバの番号です)。例えば I2C3 を有効化する場合、`config.h` ファイルに `#define I2C_DRIVER I2CD3` と定義します。これにより QMK I2C ドライバと ChibiOS I2C driver が同期されます。 - -STM32 MCU では、使用するハードウェアドライバにより、さまざまなピンを I2C ピンとして設定できます。標準では `B6`, `B7` ピンが I2C 用のピンです。 I2C 用のピンを設定するために次の定義が使えます: - -| 変数 | 説明 | 既定値 | -|-----------------------|-------------------------------------------------------------------------------------------|---------| -| `I2C1_SCL_PIN` | SCL のピン番号 | `B6` | -| `I2C1_SDA_PIN` | SDA のピン番号 | `B7` | - -ChibiOS I2C ドライバの設定項目は STM32 MCU の種類に依存します。 - - STM32F1xx, STM32F2xx, STM32F4xx, STM32L0xx, STM32L1xx では I2Cv1 が使われます。 - STM32F0xx, STM32F3xx, STM32F7xx, STM32L4xx では I2Cv2 が使われます。 - -#### I2Cv1 :id=i2cv1 - -STM32 MCU の I2Cv1 では、クロック周波数とデューティ比を次の変数で変更できます。詳しくは を参照してください。 - -| 変数 | 既定値 | -|--------------------|------------------| -| `I2C1_OPMODE` | `OPMODE_I2C` | -| `I2C1_CLOCK_SPEED` | `100000` | -| `I2C1_DUTY_CYCLE` | `STD_DUTY_CYCLE` | - -#### I2Cv2 :id=i2cv2 - -STM32 MCU の I2Cv2 では、信号のタイミングパラメータを次の変数で変更できます。詳しくは を参照してください。 - -| 変数 | 既定値 | -|-----------------------|--------| -| `I2C1_TIMINGR_PRESC` | `15U` | -| `I2C1_TIMINGR_SCLDEL` | `4U` | -| `I2C1_TIMINGR_SDADEL` | `2U` | -| `I2C1_TIMINGR_SCLH` | `15U` | -| `I2C1_TIMINGR_SCLL` | `21U` | - -STM32 MCU では GPIO ピンを設定するとき、別の「代替機能」モードを使うことができます。これは I2Cv2 モードで使われるピンを変更するために必要です。適切な設定値は、使用している MCU のデータシートを参照してください。 - -| 変数 | 既定値 | -|---------------------|--------| -| `I2C1_SCL_PAL_MODE` | `4` | -| `I2C1_SDA_PAL_MODE` | `4` | - -#### その他 :id=other - -`void i2c_init(void)` 関数は `weak` 属性が付いており、オーバーロードすることができます。この場合、上記で設定した変数は使用されません。可能な GPIO の設定については、 MCU のデータシートを参照してください。次に示すのは初期化関数の例です: - -```c -void i2c_init(void) -{ - setPinInput(B6); // Try releasing special pins for a short time - setPinInput(B7); - wait_ms(10); // Wait for the release to happen - - palSetPadMode(GPIOB, 6, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B6 to I2C function - palSetPadMode(GPIOB, 7, PAL_MODE_ALTERNATE(4) | PAL_STM32_OTYPE_OPENDRAIN | PAL_STM32_PUPDR_PULLUP); // Set B7 to I2C function -} -``` diff --git a/docs/ja/isp_flashing_guide.md b/docs/ja/isp_flashing_guide.md deleted file mode 100644 index d629b964b2db..000000000000 --- a/docs/ja/isp_flashing_guide.md +++ /dev/null @@ -1,294 +0,0 @@ -# ISP 書き込みガイド - - - -ISP 書き込み(ICSP 書き込みと呼ぶ場合もあります)とは、マイクロコントローラーを直接プログラミングするプロセスです。 -これにより、ブートローダを交換したり、コントローラの「ヒューズ」を変更することができ、コントローラの速度や起動方法、その他のオプションなど、多くのハードウェアおよびソフトウェア関連の機能を制御します。 - -QMK の ISP 書き込みの主な用途は、AVRベースのコントローラ(Pro Micro、または V-USB チップ)のブートローダの書き込みまたは交換です。 - -?> これは Pro Micro や他の ATmega コントローラなどの AVR ベースのボードをプログラミングするためだけのものです。 Proton C などの Arm コントローラには使用できません。 - -## 破損したブートローダーの取り扱い - -ボードの書き込み/消去で問題が発生し、DFU ベースのコントローラで次のような不可解なエラーメッセージが表示される場合: - - libusb: warning [darwin_transfer_status] transfer error: timed out - dfu.c:844: -ETIMEDOUT: Transfer timed out, NAK 0xffffffc4 (-60) - atmel.c:1627: atmel_flash: flash data dfu_download failed. - atmel.c:1629: Expected message length of 1072, got -60. - atmel.c:1434: Error flashing the block: err -2. - ERROR - Memory write error, use debug for more info. - commands.c:360: Error writing memory data. (err -4) - - dfu.c:844: -EPIPE: a) Babble detect or b) Endpoint stalled 0xffffffe0 (-32) - Device is write protected. - dfu.c:252: dfu_clear_status( 0x7fff4fc2ea80 ) - atmel.c:1434: Error flashing the block: err -2. - ERROR - Memory write error, use debug for more info. - commands.c:360: Error writing memory data. (err -4) - -または、Pro Micro ベースのコントローラに対して次のようなメッセージが表示された場合: - - avrdude: butterfly_recv(): programmer is not responding - avrdude: butterfly_recv(): programmer is not responding - avrdude: verification error, first mismatch at byte 0x002a - 0x2b != 0x75 - avrdude: verification error; content mismatch - avrdude: verification error; content mismatch - - -あなたのボード/デバイスを再び動作させるには、ISP 書き込みが必要になるかもしれません。 - -## 必要なハードウェア - -実際に ISP の書き込みを行うには、以下のいずれか(その後に使用するプロトコルが続きます)が必要になります。 - -* [SparkFun PocketAVR](https://www.sparkfun.com/products/9825) - (USB Tiny) -* [USBtinyISP AVR Programmer Kit](https://www.adafruit.com/product/46) - (USB Tiny) -* [USBasp](https://www.fischl.de/usbasp/) - (usbasp) -* [Teensy 2.0](https://www.pjrc.com/store/teensy.html) - (avrisp) -* [Pro Micro](https://www.sparkfun.com/products/12640) - (avrisp) -* [Bus Pirate](https://www.adafruit.com/product/237) - (buspirate) - -ISP 書き込みに使用できるデバイスは他にもありますが、これらが主なものです。 -また、すべての製品リンクは公式バージョンへのものです。他の場所で入手することもできます。 - -また、「ISP プログラマ」をプログラミングするデバイスに配線するためのものも必要になります。 -PCB の中には直接使用できる ISP ヘッダがあるものもありますが、そうではない場合が多いので、コントローラ自体にハンダ付けするか、別のスイッチや他のコンポーネントにハンダ付けする必要があるでしょう。 - -### ISP ファームウェア - -Teensy と Pro Micro のコントローラを ISP プログラマとして使用するには、コントローラに ISP ファームウェアを書き込む必要があります。 -それ以外のハードウェアは、あらかじめプログラムされているはずです。 -そのため、これらのコントローラの場合は、正しい hex ファイルをダウンロードしてから書き込んでください。 - -* Teensy 2.0: [`util/teensy_2.0_ISP_B0.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/teensy_2.0_ISP_B0.hex) (`B0`) -* Pro Micro: [`util/pro_micro_ISP_B6_10.hex`](https://github.com/qmk/qmk_firmware/blob/master/util/pro_micro_ISP_B6_10.hex) (`10/B6`) - -コントローラに書き込んだら、この hex ファイルはもう必要ありません。 - -## 必要なソフトウェア - -QMK ツールボックスは、このほとんど(すべて)に使用することができます。 - -ただし、Teensy 2.0 ボードを使っている場合は、[Teensy Loader](https://www.pjrc.com/teensy/loader.html) を使えば、Teensy 2.0 ボードに書き込むことができます。 -あるいは、`avrdude` (`qmk_install.sh` の一部としてインストールされています) や、[AVRDUDESS](https://blog.zakkemble.net/avrdudess-a-gui-for-avrdude/) (Windows 用) を使って、Pro Micro に書き込んだり、ISP を書き込んだりすることができます。 - -## 配線 - -これは非常に簡単です。次のようにして、相互に対応するものを接続します。 - -### SparkFun Pocket AVR - - PocketAVR RST <-> Keyboard RESET - PocketAVR SCLK <-> Keyboard B1 (SCLK) - PocketAVR MOSI <-> Keyboard B2 (MOSI) - PocketAVR MISO <-> Keyboard B3 (MISO) - PocketAVR VCC <-> Keyboard VCC - PocketAVR GND <-> Keyboard GND - -### USBasp - - USBasp RST <-> Keyboard RESET - USBasp SCLK <-> Keyboard B1 (SCLK) - USBasp MOSI <-> Keyboard B2 (MOSI) - USBasp MISO <-> Keyboard B3 (MISO) - USBasp VCC <-> Keyboard VCC - USBasp GND <-> Keyboard GND - -### Teensy 2.0 - - Teensy B0 <-> Keyboard RESET - Teensy B1 <-> Keyboard B1 (SCLK) - Teensy B2 <-> Keyboard B2 (MOSI) - Teensy B3 <-> Keyboard B3 (MISO) - Teensy VCC <-> Keyboard VCC - Teensy GND <-> Keyboard GND - -!> Teensy の B0 ピンはキーボードのコントローラの RESET/RST ピンと配線されています。 Teensy の RESET ピンをキーボードの RESET に配線しないでください。 - -### Pro Micro - - Pro Micro 10 (B6) <-> Keyboard RESET - Pro Micro 15 (B1) <-> Keyboard B1 (SCLK) - Pro Micro 16 (B2) <-> Keyboard B2 (MOSI) - Pro Micro 14 (B3) <-> Keyboard B3 (MISO) - Pro Micro VCC <-> Keyboard VCC - Pro Micro GND <-> Keyboard GND - -!> Pro Micro の 10/B6 ピンはキーボードのコントローラの RESET/RST ピンに配線されています。 Pro Micro の RESET ピンをキーボードの RESET に配線 ***しないでください***。 - -## キーボードへの書き込み - -ISP プログラマをセットアップして、キーボードに接続したら、キーボードに書き込みをします。 - -### ブートローダファイル - -普通の状態に戻す一番簡単で手っ取り早い方法は、キーボードにブートローダだけ書き込むことです。 -これが終れば、普通にキーボードを接続して、普通にキーボードに書き込みできるようになります。 - -標準のブートローダは[`util/` フォルダー](https://github.com/qmk/qmk_firmware/tree/master/util) にあります。 -チップの正しいブートローダを書き込んでください: - -* **Atmel DFU** - * [ATmega16U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega16u4_1.0.1.hex) - * [ATmega32U4](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_atmega32u4_1.0.0.hex) - * [AT90USB64](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb64_1.0.0.hex) - * [AT90USB128](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_at90usb128_1.0.1.hex) -* **Caterina** - * [Pro Micro (5V/16MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro16.hex) - * [Pro Micro (3.3V/8MHz)](https://github.com/sparkfun/Arduino_Boards/blob/master/sparkfun/avr/bootloaders/caterina/Caterina-promicro8.hex) -* **BootloadHID (PS2AVRGB)** - * [ATmega32A](https://github.com/qmk/qmk_firmware/blob/master/util/bootloader_ps2avrgb_bootloadhid_1.0.1.hex) - -お使いのボードが何を使っているかわからない場合は、QMK のキーボード用の `rules.mk` ファイルを見てください。 -`MCU` と `BOOTLOADER` の行には必要な値が書かれています。これはボードのバージョンによって異なるかもしれません。 - -### 製造手法 - -ブートローダと通常のファームウェアを同時に書き込みたい場合、2つの方法があります。 -手動で行うか、コンパイル時に `:production` ターゲットを使って行うかです。 - -手動で行うには: - -1. オリジナルのファームウェアの .hex ファイルをテキストエディタで開きます -2. 最後の行を削除してください。(`:00000001FF`になっているはずです - これは EOF メッセージです) -3. ブートローダの内容全体を新しい行にコピーして(行間に空行を入れないように)、元のファイルの最後に貼り付けてください。 -4. これを新しいファイルとして `__production.hex` という名前で保存します。 - -?> ここでは他のブートローダも同じように使うことができますが、__ブートローダが必要で__、そうしないとまた ISP を使ってキーボードに新しいファームウェアを書き込まなければならなくなります。 - -#### QMK DFU ブートローダとプロダクションイメージの作成 - -コンパイル時に `:production` ターゲットを使用して、ボード用のファームウェア、QMK DFU ブートローダ、プロダクションファームウェアイメージを作成することができます。 -これが完了すると、3つのファイルが表示されます: - -* `_.hex` -* `__bootloader.hex` -* `__production.hex` - -QMK DFU ブートローダは `atmega32u4` コントローラ (AVR ベースの Planck ボードや Pro Micro など) でしかテストされておらず、他のコントローラではテストされていません。 -しかし、`atmega32a` や `atmega328p` のような V-USB コントローラでは間違いなく動作しません。 - -ブートローダかプロダクションファームウェアファイルのどちらかを書き込むことができます。 -プロダクションファームウェアファイルの方が、より多くのデータを書き込むので、書き込みに時間がかかります。 - -?> 注意:同じブートローダを使用しつづけるべきです。すでに DFU を使用している場合は、QMK DFU に切り替えても問題ありません。しかし、例えば Pro Micro に QMK DFU を書き込むには、追加の手順が必要になります。 - -## ブートローダ/プロダクションファイルの書き込み - -キーボードがどのデバイスにも接続されていないことを確認し、ISP プログラマを接続してください。 - -ブートローダの種類を変更したい場合は、コマンドラインを使用する必要があります。 - -### QMK Toolbox - -1. `AVRISP device connected` または `USB Tiny device connected` が黄色で表示されます。 -2. `Open` ダイアログで正しいブートローダー/プロダクションの .hex ファイルを選択します(パスにスペースを含めることはできません) -3. 書きこもうとしているキーボード(ISP プログラマではなく)のための正しい `Microcontroller` オプションが選択されていることを確認してください。 -4. `Flash` を押します -5. 特にプロダクションファイルの場合、しばらくは何も出力されませんが、待ちましょう。 - -検証とヒューズのチェックに問題がなければ、完了です。 -ボードが自動的に再起動する場合があります。 -それ以外の場合は、Teensy のプラグを抜いて、キーボードを接続します。 -テスト中は、Teensy をキーボードに接続したままにすることができますが、すべてが正常に機能することを確認したら、はんだを外すか、配線を外すことをお勧めします。 - -### コマンドライン - -ターミナル(Windows の場合は `cmd`)を開いて、修正した .hex ファイルがある場所に移動します。 -ここでは、このファイルを `main.hex` と呼び、Teensy 2.0 が `COM3` ポートに接続されていると仮定します。 -よくわからない場合は、デバイスマネージャを開いて、`Ports > USB Serial Device` を探してください。ここにある COM ポートを使ってください。 -あなたはそれが正しいポートであることを確認することができます: - - avrdude -c avrisp -P COM3 -p atmega32u4 - -次のような出力が得られるはずです: - - avrdude: AVR device initialized and ready to accept instructions - - Reading | ################################################## | 100% 0.02s - - avrdude: Device signature = 0x1e9587 - - avrdude: safemode: Fuses OK - - avrdude done. Thank you. - -私たちのキーボードは `atmega32u4`(共通)を使用しているので、これが指定するチップです。 -以下が完全なコマンドです: - - avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i - -ボードが `atmega32a`(jj40 など)を使用している場合、コマンドは次のとおりです(最後の追加コードによりヒューズが正しく設定されます)。 - - avrdude -c avrisp -P COM3 -p atmega32 -U flash:w:main.hex:i -U hfuse:w:0xD0:m -U lfuse:w:0x0F:m - -プログレスバーが表示されてから、以下が表示されるはずです。 - - avrdude: verifying ... - avrdude: 32768 bytes of flash verified - - avrdude: safemode: Fuses OK - - avrdude done. Thank you. - -これは全てうまく動作したことを示しています。 -ボードが自動的に再起動する場合もありますが、そうでない場合は、Teensy のプラグを抜いてキーボードを接続してください。 -テスト中は、Teensy をキーボードに接続したままにすることができますが、すべてが正常に機能することを確認したら、はんだを外すか、配線を外すことをお勧めします。 - -SparkFun PocketAVR Programmer や、他の USB Tiny ベースの ISP プログラマを使用している場合は、次のようなものを使用すると良いでしょう。 - - avrdude -c usbtiny -P usb -p atmega32u4 - -#### 上級者向け: ヒューズの変更 - -Pro Micro に QMK DFU を書き込むなど、ブートローダを切り替える場合は、ブートローダの hex ファイルの書き込みに加えて、ヒューズを変更する必要があります。 -これは、`caterina` (Pro Micro ブートローダ) と `dfu` では起動ルーチンの扱いが異なり、その動作はヒューズによって制御されるからです。 - -!> これは、ヒューズを変更することは、永久にあなたのコントローラをレンガ化(訳注:日本では文鎮化と呼ぶことが多い、コントローラがまったく無反応になる状態)することができる方法の1つであるため、それは非常に注意が必要な1つの領域です。 - -以下は、`atmega32u4`の 5V 16MHz 版(5V Pro Micro など)を想定しています。 - -`atmega32u4`の DFU の場合、必要なヒューズ設定は次のとおりです: - -| ヒューズ | 設定 | -|----------|------------------| -| Low | `0x5E` | -| High | `0xD9` or `0x99` | -| Extended | `0xC3` | - -High ヒューズは 0xD9 か 0x99 のどちらかになります。 -違いは、0xD9 は QMK Firmware がソフトウェアでも無効化している JTAG を無効化しているのに対し、0x99 は JTAG を無効化していないことです。 - -これを設定するには、`-U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m` をコマンドに追加します。 -そうすると、最終的なコマンドは次のようになります。 - - avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0x5E:m -U hfuse:w:0xD9:m -U efuse:w:0xC3:m - -`atmega32u4`の Caterina では、以下があなたに必要なヒューズの設定です。 - -| ヒューズ | 設定 | -|----------|--------| -| Low | `0xFF` | -| High | `0xD8` | -| Extended | `0xCB` | - -これを設定するには、コマンドに `-U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m` を追加します。 -これで、最終的なコマンドは次のようになるはずです。 - - avrdude -c avrisp -P COM3 -p atmega32u4 -U flash:w:main.hex:i -U lfuse:w:0xFF:m -U hfuse:w:0xD8:m -U efuse:w:0xCB:m - - -別のコントローラーを使用している場合や、別の設定を希望する場合は、この[AVR ヒューズ計算機](https://www.engbedded.com/fusecalc/)を使用して、より適切な値を見つけることができます。 - -## ヘルプ - -ご質問・ご不明な点がありましたら、お気軽に[issue を開いてください](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/docs/ja/ja_doc_status.sh b/docs/ja/ja_doc_status.sh deleted file mode 100644 index 3dfbbd2bc6f6..000000000000 --- a/docs/ja/ja_doc_status.sh +++ /dev/null @@ -1,34 +0,0 @@ -#! /bin/sh -# -# Script to display the Japanese translation status of documents -# -if [ ! -d docs/ja ]; then - echo "'docs/ja' not found." - echo "do:" - echo " cd \$(QMK_TOP)" - echo " ./docs/ja/ja_doc_status.sh" - exit 1 -fi - -en_docs=`cd docs;ls -1 [a-z]*.md` -ja_docs=`cd docs/ja;ls -1 [a-z]*.md` -en_count=`echo $en_docs | wc -w` -ja_count=`echo $ja_docs | wc -w` -echo "English documents $en_count files." -echo "Japanese documents $ja_count files." - -echo "Files that have not been translated yet:" -for docfile in $en_docs -do - if [ ! -f docs/ja/$docfile ]; then - wc docs/$docfile - fi -done | sort -echo "Files that have not been updated yet:" -grep --no-filename "^[ ]*git diff" docs/ja/*.md | while read cmd -do - cline=`echo $cmd | sh | wc -l` - if [ $cline -gt 0 ]; then - echo "$cline $cmd" - fi -done | sort diff --git a/docs/ja/keycodes.md b/docs/ja/keycodes.md deleted file mode 100644 index 2e339af35bf1..000000000000 --- a/docs/ja/keycodes.md +++ /dev/null @@ -1,574 +0,0 @@ -# キーコードの概要 - - - -[キーマップ](ja/keymap.md) を定義するときは、それぞれのキーに有効な定義が必要です。このページは、QMK で使えるキーコードに相当するシンボルについて記述しています。 - -このページは参照のみです。それぞれのキーの種類毎のリンク先のページに、それぞれのキーの機能についてもっと詳細に記載しています。 - -## 基本的なキーコード :id=basic-keycodes - -[基本的なキーコード](ja/keycodes_basic.md) も見てください。 - -?> 訳注: 以下の説明は、OS のキーボード配列の設定が「US」の場合のものです。OS のキーボード配列の設定が「JIS」の場合、一部のキーは下の表と異なる文字が入力されます。例えば、`KC_LBRC` は、OS のキーボード配列の設定が US であれば「`[` または `{`」が入力されますが、JIS の場合「`@` または `」が入力されます。 -?> これは、OS がキーボードから送信されたキーコードを解釈する際に、キーボード配列の設定によって対応する文字を変えるためです。もし、OS のキーボード配列の設定を JIS にする場合、`#include "keymap_jp.h"` を `keymap.c` に追加すると`JP_AT` のような JIS キーボードのキーキャップに対応したキーを指定できます。 - -|キー |エイリアス |説明 |Windows |macOS |Linux1| -|-----------------------|------------------------------|-----------------------------------------|-------------|-------------|-----------------| -|`KC_NO` |`XXXXXXX` |このキーを無視します (何もしません) 。 |*N/A* |*N/A* |*N/A* | -|`KC_TRANSPARENT` |`KC_TRNS`, `_______` | 次に低いレイヤーの非透過キーを使う |*N/A* |*N/A* |*N/A* | -|`KC_A` | |`a` と `A` |✔ |✔ |✔ | -|`KC_B` | |`b` と `B` |✔ |✔ |✔ | -|`KC_C` | |`c` と `C` |✔ |✔ |✔ | -|`KC_D` | |`d` と `D` |✔ |✔ |✔ | -|`KC_E` | |`e` と `E` |✔ |✔ |✔ | -|`KC_F` | |`f` と `F` |✔ |✔ |✔ | -|`KC_G` | |`g` と `G` |✔ |✔ |✔ | -|`KC_H` | |`h` と `H` |✔ |✔ |✔ | -|`KC_I` | |`i` と `I` |✔ |✔ |✔ | -|`KC_J` | |`j` と `J` |✔ |✔ |✔ | -|`KC_K` | |`k` と `K` |✔ |✔ |✔ | -|`KC_L` | |`l` と `L` |✔ |✔ |✔ | -|`KC_M` | |`m` と `M` |✔ |✔ |✔ | -|`KC_N` | |`n` と `N` |✔ |✔ |✔ | -|`KC_O` | |`o` と `O` |✔ |✔ |✔ | -|`KC_P` | |`p` と `P` |✔ |✔ |✔ | -|`KC_Q` | |`q` と `Q` |✔ |✔ |✔ | -|`KC_R` | |`r` と `R` |✔ |✔ |✔ | -|`KC_S` | |`s` と `S` |✔ |✔ |✔ | -|`KC_T` | |`t` と `T` |✔ |✔ |✔ | -|`KC_U` | |`u` と `U` |✔ |✔ |✔ | -|`KC_V` | |`v` と `V` |✔ |✔ |✔ | -|`KC_W` | |`w` と `W` |✔ |✔ |✔ | -|`KC_X` | |`x` と `X` |✔ |✔ |✔ | -|`KC_Y` | |`y` と `Y` |✔ |✔ |✔ | -|`KC_Z` | |`z` と `Z` |✔ |✔ |✔ | -|`KC_1` | |`1` と `!` |✔ |✔ |✔ | -|`KC_2` | |`2` と `@` |✔ |✔ |✔ | -|`KC_3` | |`3` と `#` |✔ |✔ |✔ | -|`KC_4` | |`4` と `$` |✔ |✔ |✔ | -|`KC_5` | |`5` と `%` |✔ |✔ |✔ | -|`KC_6` | |`6` と `^` |✔ |✔ |✔ | -|`KC_7` | |`7` と `&` |✔ |✔ |✔ | -|`KC_8` | |`8` と `*` |✔ |✔ |✔ | -|`KC_9` | |`9` と `(` |✔ |✔ |✔ | -|`KC_0` | |`0` と `)` |✔ |✔ |✔ | -|`KC_ENTER` |`KC_ENT` |Return (Enter) |✔ |✔ |✔ | -|`KC_ESCAPE` |`KC_ESC` |Escape |✔ |✔ |✔ | -|`KC_BSPACE` |`KC_BSPC` |Delete (Backspace) |✔ |✔ |✔ | -|`KC_TAB` | |Tab |✔ |✔ |✔ | -|`KC_SPACE` |`KC_SPC` |Spacebar |✔ |✔ |✔ | -|`KC_MINUS` |`KC_MINS` |`-` と `_` |✔ |✔ |✔ | -|`KC_EQUAL` |`KC_EQL` |`=` と `+` |✔ |✔ |✔ | -|`KC_LBRACKET` |`KC_LBRC` |`[` と `{` |✔ |✔ |✔ | -|`KC_RBRACKET` |`KC_RBRC` |`]` と `}` |✔ |✔ |✔ | -|`KC_BSLASH` |`KC_BSLS` |`\` と `\|` |✔ |✔ |✔ | -|`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` と `~` |✔ |✔ |✔ | -|`KC_SCOLON` |`KC_SCLN` |`;` と `:` |✔ |✔ |✔ | -|`KC_QUOTE` |`KC_QUOT` |`'` と `"` |✔ |✔ |✔ | -|`KC_GRAVE` |`KC_GRV`, `KC_ZKHK` |` と `~`, JIS 全角/半角 |✔ |✔ |✔ | -|`KC_COMMA` |`KC_COMM` |`,` と `<` |✔ |✔ |✔ | -|`KC_DOT` | |`.` と `>` |✔ |✔ |✔ | -|`KC_SLASH` |`KC_SLSH` |`/` と `?` |✔ |✔ |✔ | -|`KC_CAPSLOCK` |`KC_CLCK`, `KC_CAPS` |Caps Lock |✔ |✔ |✔ | -|`KC_F1` | |F1 |✔ |✔ |✔ | -|`KC_F2` | |F2 |✔ |✔ |✔ | -|`KC_F3` | |F3 |✔ |✔ |✔ | -|`KC_F4` | |F4 |✔ |✔ |✔ | -|`KC_F5` | |F5 |✔ |✔ |✔ | -|`KC_F6` | |F6 |✔ |✔ |✔ | -|`KC_F7` | |F7 |✔ |✔ |✔ | -|`KC_F8` | |F8 |✔ |✔ |✔ | -|`KC_F9` | |F9 |✔ |✔ |✔ | -|`KC_F10` | |F10 |✔ |✔ |✔ | -|`KC_F11` | |F11 |✔ |✔ |✔ | -|`KC_F12` | |F12 |✔ |✔ |✔ | -|`KC_PSCREEN` |`KC_PSCR` |Print Screen |✔ |✔2|✔ | -|`KC_SCROLLLOCK` |`KC_SCRL`, `KC_BRMD` |Scroll Lock, 画面の明るさダウン (macOS) |✔ |✔2|✔ | -|`KC_PAUSE` |`KC_PAUS`, `KC_BRK`, `KC_BRMU`|Pause, 画面の明るさアップ (macOS) |✔ |✔2|✔ | -|`KC_INSERT` |`KC_INS` |Insert |✔ | |✔ | -|`KC_HOME` | |Home |✔ |✔ |✔ | -|`KC_PGUP` | |Page Up |✔ |✔ |✔ | -|`KC_DELETE` |`KC_DEL` |Forward Delete |✔ |✔ |✔ | -|`KC_END` | |End |✔ |✔ |✔ | -|`KC_PGDOWN` |`KC_PGDN` |Page Down |✔ |✔ |✔ | -|`KC_RIGHT` |`KC_RGHT` |右矢印 |✔ |✔ |✔ | -|`KC_LEFT` | |左矢印 |✔ |✔ |✔ | -|`KC_DOWN` | |下矢印 |✔ |✔ |✔ | -|`KC_UP` | |上矢印 |✔ |✔ |✔ | -|`KC_NUMLOCK` |`KC_NUM` |テンキー Num Lock と Clear |✔ |✔ |✔ | -|`KC_KP_SLASH` |`KC_PSLS` |テンキー `/` |✔ |✔ |✔ | -|`KC_KP_ASTERISK` |`KC_PAST` |テンキー `*` |✔ |✔ |✔ | -|`KC_KP_MINUS` |`KC_PMNS` |テンキー `-` |✔ |✔ |✔ | -|`KC_KP_PLUS` |`KC_PPLS` |テンキー `+` |✔ |✔ |✔ | -|`KC_KP_ENTER` |`KC_PENT` |テンキー Enter |✔ |✔ |✔ | -|`KC_KP_1` |`KC_P1` |テンキー `1` と End |✔ |✔ |✔ | -|`KC_KP_2` |`KC_P2` |テンキー `2` と下矢印 |✔ |✔ |✔ | -|`KC_KP_3` |`KC_P3` |テンキー `3` と Page Down |✔ |✔ |✔ | -|`KC_KP_4` |`KC_P4` |テンキー `4` と左矢印 |✔ |✔ |✔ | -|`KC_KP_5` |`KC_P5` |テンキー `5` |✔ |✔ |✔ | -|`KC_KP_6` |`KC_P6` |テンキー `6` と右矢印 |✔ |✔ |✔ | -|`KC_KP_7` |`KC_P7` |テンキー `7` と Home |✔ |✔ |✔ | -|`KC_KP_8` |`KC_P8` |テンキー `8` と上矢印 |✔ |✔ |✔ | -|`KC_KP_9` |`KC_P9` |テンキー `9` と Page Up |✔ |✔ |✔ | -|`KC_KP_0` |`KC_P0` |テンキー `0` と Insert |✔ |✔ |✔ | -|`KC_KP_DOT` |`KC_PDOT` |テンキー `.` と Delete |✔ |✔ |✔ | -|`KC_NONUS_BSLASH` |`KC_NUBS` |Non-US `\` と `\|` |✔ |✔ |✔ | -|`KC_APPLICATION` |`KC_APP` |アプリケーションキー (Windows コンテキストメニューキー) |✔ | |✔ | -|`KC_POWER` | |システム電源 | |✔3|✔ | -|`KC_KP_EQUAL` |`KC_PEQL` |テンキー `=` |✔ |✔ |✔ | -|`KC_F13` | |F13 |✔ |✔ |✔ | -|`KC_F14` | |F14 |✔ |✔ |✔ | -|`KC_F15` | |F15 |✔ |✔ |✔ | -|`KC_F16` | |F16 |✔ |✔ |✔ | -|`KC_F17` | |F17 |✔ |✔ |✔ | -|`KC_F18` | |F18 |✔ |✔ |✔ | -|`KC_F19` | |F19 |✔ |✔ |✔ | -|`KC_F20` | |F20 |✔ | |✔ | -|`KC_F21` | |F21 |✔ | |✔ | -|`KC_F22` | |F22 |✔ | |✔ | -|`KC_F23` | |F23 |✔ | |✔ | -|`KC_F24` | |F24 |✔ | |✔ | -|`KC_EXECUTE` |`KC_EXEC` |Execute | | |✔ | -|`KC_HELP` | |Help | | |✔ | -|`KC_MENU` | |Menu | | |✔ | -|`KC_SELECT` |`KC_SLCT` |Select | | |✔ | -|`KC_STOP` | |Stop | | |✔ | -|`KC_AGAIN` |`KC_AGIN` |Again | | |✔ | -|`KC_UNDO` | |アンドゥ | | |✔ | -|`KC_CUT` | |カット | | |✔ | -|`KC_COPY` | |コピー | | |✔ | -|`KC_PASTE` |`KC_PSTE` |ペースト | | |✔ | -|`KC_FIND` | |検索 | | |✔ | -|`KC__MUTE` | |ミュート | |✔ |✔ | -|`KC__VOLUP` | |音量アップ | |✔ |✔ | -|`KC__VOLDOWN` | |音量ダウン | |✔ |✔ | -|`KC_LOCKING_CAPS` |`KC_LCAP` |Caps Lock のロック |✔ |✔ | | -|`KC_LOCKING_NUM` |`KC_LNUM` |Num Lock のロック |✔ |✔ | | -|`KC_LOCKING_SCROLL` |`KC_LSCR` |Scroll Lock のロック |✔ |✔ | | -|`KC_KP_COMMA` |`KC_PCMM` |テンキー `,` | | |✔ | -|`KC_KP_EQUAL_AS400` | |AS/400 キーボードのテンキー `=` | | | | -|`KC_INT1` |`KC_RO` |JIS `\` と `_` |✔ | |✔ | -|`KC_INT2` |`KC_KANA` |JIS カタカナ/ひらがな |✔ | |✔ | -|`KC_INT3` |`KC_JYEN` |JIS `¥` と `\|` |✔ | |✔ | -|`KC_INT4` |`KC_HENK` |JIS 変換 |✔ | |✔ | -|`KC_INT5` |`KC_MHEN` |JIS 無変換 |✔ | |✔ | -|`KC_INT6` | |JIS テンキー `,` | | |✔ | -|`KC_INT7` | |International 7 | | | | -|`KC_INT8` | |International 8 | | | | -|`KC_INT9` | |International 9 | | | | -|`KC_LANG1` |`KC_HAEN` |ハングル/英語 | | |✔ | -|`KC_LANG2` |`KC_HANJ` |韓文漢字 | | |✔ | -|`KC_LANG3` | |JIS カタカナ | | |✔ | -|`KC_LANG4` | |JIS ひらがな | | |✔ | -|`KC_LANG5` | |JIS 全角/半角 | | |✔ | -|`KC_LANG6` | |Language 6 | | | | -|`KC_LANG7` | |Language 7 | | | | -|`KC_LANG8` | |Language 8 | | | | -|`KC_LANG9` | |Language 9 | | | | -|`KC_ALT_ERASE` |`KC_ERAS` |Alternate Erase | | | | -|`KC_SYSREQ` | |SysReq/Attention | | | | -|`KC_CANCEL` | |Cancel | | | | -|`KC_CLEAR` |`KC_CLR` |Clear | | |✔ | -|`KC_PRIOR` | |Prior | | | | -|`KC_RETURN` | |Return | | | | -|`KC_SEPARATOR` | |Separator | | | | -|`KC_OUT` | |Out | | | | -|`KC_OPER` | |Oper | | | | -|`KC_CLEAR_AGAIN` | |Clear/Again | | | | -|`KC_CRSEL` | |CrSel/Props | | | | -|`KC_EXSEL` | |ExSel | | | | -|`KC_LCTRL` |`KC_LCTL` |左 Control |✔ |✔ |✔ | -|`KC_LSHIFT` |`KC_LSFT` |左 Shift |✔ |✔ |✔ | -|`KC_LALT` |`KC_LOPT` |左 Alt (Option) |✔ |✔ |✔ | -|`KC_LGUI` |`KC_LCMD`, `KC_LWIN` |左 GUI (Windows/Command/Meta key) |✔ |✔ |✔ | -|`KC_RCTRL` |`KC_RCTL` |右 Control |✔ |✔ |✔ | -|`KC_RSHIFT` |`KC_RSFT` |右 Shift |✔ |✔ |✔ | -|`KC_RALT` |`KC_ROPT`, `KC_ALGR` |右 Alt (Option/AltGr) |✔ |✔ |✔ | -|`KC_RGUI` |`KC_RCMD`, `KC_RWIN` |右 GUI (Windows/Command/Meta key) |✔ |✔ |✔ | -|`KC_SYSTEM_POWER` |`KC_PWR` |システム電源オフ |✔ |✔3|✔ | -|`KC_SYSTEM_SLEEP` |`KC_SLEP` |システムスリープ |✔ |✔3|✔ | -|`KC_SYSTEM_WAKE` |`KC_WAKE` |システムスリープ解除 | |✔3|✔ | -|`KC_AUDIO_MUTE` |`KC_MUTE` |ミュート |✔ |✔ |✔ | -|`KC_AUDIO_VOL_UP` |`KC_VOLU` |音量アップ |✔ |✔4|✔ | -|`KC_AUDIO_VOL_DOWN` |`KC_VOLD` |音量ダウン |✔ |✔4|✔ | -|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT` |次の曲へ |✔ |✔5|✔ | -|`KC_MEDIA_PREV_TRACK` |`KC_MPRV` |前の曲へ |✔ |✔5|✔ | -|`KC_MEDIA_STOP` |`KC_MSTP` |再生停止 |✔ | |✔ | -|`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY` |再生/一時停止 |✔ |✔ |✔ | -|`KC_MEDIA_SELECT` |`KC_MSEL` |Media Player 起動 |✔ | |✔ | -|`KC_MEDIA_EJECT` |`KC_EJCT` |イジェクト | |✔ |✔ | -|`KC_MAIL` | |メール起動 |✔ | |✔ | -|`KC_CALCULATOR` |`KC_CALC` |電卓起動 |✔ | |✔ | -|`KC_MY_COMPUTER` |`KC_MYCM` |マイコンピュータを開く |✔ | |✔ | -|`KC_WWW_SEARCH` |`KC_WSCH` |ブラウザ検索 |✔ | |✔ | -|`KC_WWW_HOME` |`KC_WHOM` |ブラウザホーム画面 |✔ | |✔ | -|`KC_WWW_BACK` |`KC_WBAK` |ブラウザ戻る |✔ | |✔ | -|`KC_WWW_FORWARD` |`KC_WFWD` |ブラウザ進む |✔ | |✔ | -|`KC_WWW_STOP` |`KC_WSTP` |ブラウザ読み込み中止 |✔ | |✔ | -|`KC_WWW_REFRESH` |`KC_WREF` |ブラウザ再読み込み |✔ | |✔ | -|`KC_WWW_FAVORITES` |`KC_WFAV` |ブラウザお気に入り |✔ | |✔ | -|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD` |次の曲へ |✔ |✔5|✔ | -|`KC_MEDIA_REWIND` |`KC_MRWD` |前の曲へ |✔6|✔5|✔ | -|`KC_BRIGHTNESS_UP` |`KC_BRIU` |画面の明るさアップ |✔ |✔ |✔ | -|`KC_BRIGHTNESS_DOWN` |`KC_BRID` |画面の明るさダウン |✔ |✔ |✔ | - -1. Linux カーネル HID ドライバは [ほぼ全てのキーコード](https://github.com/torvalds/linux/blob/master/drivers/hid/hid-input.c) を識別しますが、デフォルトの関連付けは デスクトップ環境/ウィンドウマネージャによって決まります。
-2. F13-F15 として取り扱われます。
-3. 約3秒間押していると、プロンプトが表示されます。
-4. Shift と Option を押していると、ボリュームレベルの細かいコントロールが可能になります。
-5. iTunes では、タップすると1曲全体がスキップされます。押していると曲の中で早送り/巻き戻しになります。
-6. Windows Media Player は巻き戻しキーを識別しませんが、VLC では早送り/巻き戻しキーで再生速度が変更されます。 - -## Quantum キーコード :id=quantum-keycodes - -[Quantum キーコード](ja/quantum_keycodes.md#qmk-keycodes) も見てください。 - -|キー |エイリアス |説明 | -|-----------------|---------|---------------------------------------------------------| -|`QK_BOOTLOADER` |`QK_BOOT`|ファームウエア書き込みのためにキーボードをブートローダーモードにします | -|`QK_DEBUG_TOGGLE`|`DB_TOGG`|デバッグモードを切り替えます | -|`QK_CLEAR_EEPROM`|`EE_CLR` |キーボードの EEPROM (不揮発メモリ) を再初期化します | - -## オーディオキー :id=audio-keys - -[オーディオ](ja/feature_audio.md) も見てください。 - -|キー |エイリアス |説明 | -|----------------|------------|---------------------------------------| -|`AU_ON` | |オーディオモードオン | -|`AU_OFF` | |オーディオモードオフ | -|`AU_TOG` | |オーディオモードを切り替えます | -|`CLICKY_TOGGLE` |`CK_TOGG` |オーディオクリックモードを切り替えます | -|`CLICKY_UP` |`CK_UP` |クリック音の周波数を増やします | -|`CLICKY_DOWN` |`CK_DOWN` |クリック音の周波数を減らします | -|`CLICKY_RESET` |`CK_RST` |周波数をデフォルトに再設定します | -|`MU_ON` | |音楽モードをオンにします | -|`MU_OFF` | |音楽モードをオフにします | -|`MU_TOG` | |音楽モードを切り替えます | -|`MU_MOD` | |音楽モードを循環します | - -## バックライト :id=backlighting - -[バックライト](ja/feature_backlight.md) も見てください。 - -|キー |説明 | -|---------|-------------------------------------| -|`BL_TOGG`|バックライトをオンあるいはオフにする | -|`BL_STEP`|バックライトレベルを循環する | -|`BL_ON` |バックライトを最大輝度にセットする | -|`BL_OFF` |バックライトをオフにする | -|`BL_INC` |バックライトのレベルを上げる | -|`BL_DEC` |バックライトのレベルを下げる | -|`BL_BRTG`|バックライトの明滅動作を切り替える | - -## ブートマジック :id=bootmagic - -[ブートマジック](ja/feature_bootmagic.md) も見てください。 - -| キー | エイリアス| 説明 | -|------------------------------------|-----------|-------------------------------------------------------| -| `MAGIC_SWAP_CONTROL_CAPSLOCK` | `CL_SWAP` | Caps Lock と左 Control の入れ替え | -| `MAGIC_UNSWAP_CONTROL_CAPSLOCK` | `CL_NORM` | Caps Lock と左 Control の入れ替えの解除 | -| `MAGIC_CAPSLOCK_TO_CONTROL` | `CL_CTRL` | Caps Lock を Control として扱う | -| `MAGIC_UNCAPSLOCK_TO_CONTROL` | `CL_CAPS` | Caps Lock を Control として扱うことを止める | -| `MAGIC_SWAP_LCTL_LGUI` | `LCG_SWP` | 左 Control と GUI の入れ替え | -| `MAGIC_UNSWAP_LCTL_LGUI` | `LCG_NRM` | 左 Control と GUI の入れ替えを解除 | -| `MAGIC_SWAP_RCTL_RGUI` | `RCG_SWP` | 右 Control と GUI の入れ替え | -| `MAGIC_UNSWAP_RCTL_RGUI` | `RCG_NRM` | 右 Control と GUI の入れ替えを解除 | -| `MAGIC_SWAP_CTL_GUI` | `CG_SWAP` | 両側の Control と GUI の入れ替え | -| `MAGIC_UNSWAP_CTL_GUI` | `CG_NORM` | 両側の Control と GUI の入れ替えを解除 | -| `MAGIC_TOGGLE_CTL_GUI` | `CG_TOGG` | 両側の Control と GUI の入れ替えの切り替え | -| `MAGIC_SWAP_LALT_LGUI` | `LAG_SWP` | 左 Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_LALT_LGUI` | `LAG_NRM` | 左 Alt と GUI の入れ替えを解除 | -| `MAGIC_SWAP_RALT_RGUI` | `RAG_SWP` | 右 Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_RALT_RGUI` | `RAG_NRM` | 右 Alt と GUI の入れ替えを解除 | -| `MAGIC_SWAP_ALT_GUI` | `AG_SWAP` | 両側の Alt と GUI の入れ替え | -| `MAGIC_UNSWAP_ALT_GUI` | `AG_NORM` | 両側の Alt と GUI の入れ替えを解除 | -| `MAGIC_TOGGLE_ALT_GUI` | `AG_TOGG` | 両側の Alt と GUI の入れ替えの切り替え | -| `MAGIC_NO_GUI` | `GUI_OFF` | GUI キーを無効にする | -| `MAGIC_UNNO_GUI` | `GUI_ON` | GUI キーを有効にする | -| `MAGIC_SWAP_GRAVE_ESC` | `GE_SWAP` | ` とエスケープの入れ替え | -| `MAGIC_UNSWAP_GRAVE_ESC` | `GE_NORM` | ` とエスケープの入れ替えを解除 | -| `MAGIC_SWAP_BACKSLASH_BACKSPACE` | `BS_SWAP` | `\` と Backspace を入れ替え | -| `MAGIC_UNSWAP_BACKSLASH_BACKSPACE` | `BS_NORM` | `\` と Backspace の入れ替えを解除する | -| `MAGIC_HOST_NKRO` | `NK_ON` | N キーロールオーバーを有効にする | -| `MAGIC_UNHOST_NKRO` | `NK_OFF` | N キーロールオーバーを無効にする | -| `MAGIC_TOGGLE_NKRO` | `NK_TOGG` | N キーロールオーバーの有効・無効を切り替え | -| `MAGIC_EE_HANDS_LEFT` | `EH_LEFT` | 分割キーボードのマスター側を左手に設定(`EE_HANDS` 用) | -| `MAGIC_EE_HANDS_RIGHT` | `EH_RGHT` | 分割キーボードのマスター側を右手に設定(`EE_HANDS` 用) | - -## Bluetooth :id=bluetooth - -[Bluetooth](ja/feature_bluetooth.md) も見てください。 - - -|キー |説明 | -|----------|--------------------------------------| -|`OUT_AUTO`|USB と Bluetooth を自動的に切り替える | -|`OUT_USB` |USB のみ | -|`OUT_BT` |Bluetooth のみ | - -## 動的マクロ :id=dynamic-macros - -[動的マクロ](ja/feature_dynamic_macros.md) も見てください。 - -|キー |エイリアス |説明 | -|-----------------|---------|-------------------------------------| -|`DYN_REC_START1` |`DM_REC1`|マクロ 1 の記録を開始します | -|`DYN_REC_START2` |`DM_REC2`|マクロ 2 の記録を開始します | -|`DYN_MACRO_PLAY1`|`DM_PLY1`|マクロ 1 を再生します | -|`DYN_MACRO_PLAY2`|`DM_PLY2`|マクロ 2 を再生します | -|`DYN_REC_STOP` |`DM_RSTP`|現在記録中のマクロの記録を終了します | - -## グレイブエスケープ :id=grave-escape - -[グレイブエスケープ](ja/feature_grave_esc.md) も見てください。 - -|キー |エイリアス |説明 | -|-----------|---------|------------------------------------------------------------------| -|`GRAVE_ESC`|`KC_GESC`|押された場合に Escape。Shift あるいは GUI が押されたままの場合は `| - -## キーロック :id=key-lock - -[キーロック](ja/feature_key_lock.md) も見てください。 - -|キー |説明 | -|---------|--------------------------------------------------| -|`KC_LOCK`|キーが再び押されるまで次のキーを押したままにします | - -## レイヤー切り替え :id=layer-switching - -[レイヤー切り替え](ja/feature_layers.md#switching-and-toggling-layers) も見てください。 - -|キー |説明 | -|----------------|--------------------------------------------------------------------------------------------------------------------------------------| -|`DF(layer)` |指定されたレイヤーを基本 (デフォルト) レイヤーに設定する | -|`MO(layer)` |キーを押したら一時的に `layer` を切り替える。(切り替え先のレイヤーには `KC_TRNS` が必要です) | -|`OSL(layer)` |次のキーが押されるまで、一時的にレイヤーをアクティブにします。詳細は [ワンショットキー](ja/one_shot_keys.md) のとおり。 | -|`LM(layer, mod)`|`mod` がアクティブな状態で (MO のように) 一時的にレイヤーをアクティブにします。ここでは、`mod` は mods_bit のことです。Mod については [こちら](ja/mod_tap.md) で見ることができます。実装例: `LM(LAYER_1, MOD_LALT)` | -|`LT(layer, kc)` |押していると `layer` をオンにし、タップすると `kc` になります。 | -|`TG(layer)` |`layer` のオン・オフを切り替え | -|`TO(layer)` |`layer` をオンにして、デフォルトレイヤーを除く他のレイヤーをオフにします。 | -|`TT(layer)` |複数回タップしない限り `MO` のように動作し、複数回タップすると `layer` をオンにトグルします。 | - -## リーダーキー :id=leader-key - -[リーダーキー](ja/feature_leader_key.md) も見てください。 - -|キー |説明 | -|---------|-------------------------------| -|`KC_LEAD`|リーダーキーのシーケンスを開始 | - -## マウスキー :id=mouse-keys - -[マウスキー](ja/feature_mouse_keys.md) も見てください。 - -|キー |エイリアス |説明 | -|----------------|---------|-------------------------| -|`KC_MS_UP` |`KC_MS_U`|マウスカーソルを上に移動 | -|`KC_MS_DOWN` |`KC_MS_D`|マウスカーソルを下に移動 | -|`KC_MS_LEFT` |`KC_MS_L`|マウスカーソルを左に移動 | -|`KC_MS_RIGHT` |`KC_MS_R`|マウスカーソルを右に移動 | -|`KC_MS_BTN1` |`KC_BTN1`|ボタン1を押す | -|`KC_MS_BTN2` |`KC_BTN2`|ボタン2を押す | -|`KC_MS_BTN3` |`KC_BTN3`|ボタン3を押す | -|`KC_MS_BTN4` |`KC_BTN4`|ボタン4を押す | -|`KC_MS_BTN5` |`KC_BTN5`|ボタン5を押す | -|`KC_MS_WH_UP` |`KC_WH_U`|ホイールを向こう側に回転 | -|`KC_MS_WH_DOWN` |`KC_WH_D`|ホイールを手前側に回転 | -|`KC_MS_WH_LEFT` |`KC_WH_L`|ホイールを左に倒す | -|`KC_MS_WH_RIGHT`|`KC_WH_R`|ホイールを右に倒す | -|`KC_MS_ACCEL0` |`KC_ACL0`|速度を0に設定 | -|`KC_MS_ACCEL1` |`KC_ACL1`|速度を1に設定 | -|`KC_MS_ACCEL2` |`KC_ACL2`|速度を2に設定 | - -## 修飾キー :id=modifiers - -[修飾キー](ja/feature_advanced_keycodes.md#modifier-keys) も見てください。 - -| キー | エイリアス | 説明 | -|------------|---------------------------------|---------------------------------------------------------------| -| `LCTL(kc)` | `C(kc)` | 左 Control を押しながら `kc` を押します。 | -| `LSFT(kc)` | `S(kc)` | 左 Shift を押しながら `kc` を押します。 | -| `LALT(kc)` | `A(kc)`, `LOPT(kc)` | 左 Alt を押しながら `kc`を押します。 | -| `LGUI(kc)` | `G(kc)`, `LCMD(kc)`, `LWIN(kc)` | 左 GUI を押しながら `kc` を押します。 | -| `RCTL(kc)` | | 右 Control を押しながら `kc` を押します。 | -| `RSFT(kc)` | | 右 Shift を押しながら `kc` を押します。 | -| `RALT(kc)` | `ROPT(kc)`, `ALGR(kc)` | 右 Alt (AltGr) を押しながら `kc` を押します。 | -| `RGUI(kc)` | `RCMD(kc)`, `LWIN(kc)` | 右 GUI を押しながら `kc` を押します。 | -| `SGUI(kc)` | `SCMD(kc)`, `SWIN(kc)` | 左 Shift と GUI を押しながら `kc` を押します。 | -| `LCA(kc)` | | 左 Control と Alt を押しながら `kc` を押します。 | -| `LSA(kc)` | | 左 Shift と Alt を押しながら `kc` を押します。 | -| `RSA(kc)` |`SAGR(kc)` | 右 Shift と Alt (AltGr) を押しながら `kc` を押します。 | -| `RCS(kc)` | | 右 Control と Shift を押しながら `kc` を押します。 | -| `LCAG(kc)` | | 左 Control、Alt、GUI を押しながら `kc` を押します。 | -| `MEH(kc)` | | 左 Control、Shift、Alt を押しながら `kc` を押します。 | -| `HYPR(kc)` | | 左 Control、Shift、Alt、GUI を押しながら `kc` を押します。 | -| `KC_MEH` | | 左 Control、Shift、Alt | -| `KC_HYPR` | | 左 Control、Shift、Alt、GUI | - - -## モッドタップキー :id=mod-tap-keys - -[モッドタップキー](ja/mod_tap.md) も見てください。 - -|キー |エイリアス | 説明 | -|--------------|-------------------------------------------------------------------|------------------------------------------------------------------------| -| `MT(mod, kc)`| |押したままの場合は `mod` 、タップした場合は `kc` | -| `LCTL_T(kc)` | `CTL_T(kc)` | 押したままの場合は左 Control、タップした場合は `kc` | -| `LSFT_T(kc)` | `SFT_T(kc)` | 押したままの場合は左 Shift、タップした場合は `kc` | -| `LALT_T(kc)` | `LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` | 押したままの場合は左 Alt、タップした場合は `kc` | -| `LGUI_T(kc)` | `LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)` | 押したままの場合は左 GUI、タップした場合は `kc` | -| `RCTL_T(kc)` | | 押したままの場合は右 Control、タップした場合は `kc` | -| `RSFT_T(kc)` | | 押したままの場合は右 Shift、タップした場合は `kc` | -| `RALT_T(kc)` | `ROPT_T(kc)`, `ALGR_T(kc)` | 押したままの場合は右 Alt (AltGr) 、タップした場合は `kc` | -| `RGUI_T(kc)` | `RCMD_T(kc)`, `RWIN_T(kc)` | 押したままの場合は右 GUI、タップした場合は `kc` | -| `SGUI_T(kc)` | `SCMD_T(kc)`, `SWIN_T(kc)` | 押したままの場合は左 Shift と GUI、タップした場合は `kc` | -| `LCA_T(kc)` | | 押したままの場合は左 Control と Alt、タップした場合は `kc` | -| `LSA_T(kc)` | | 押したままの場合は左 Shift と Alt、タップした場合は `kc` | -| `RSA_T(kc)` |`SAGR_T(kc)` | 押したままの場合は右 Shift と Alt (AltGr) 、タップした場合は `kc` | -| `RCS_T(kc)` | | 押したままの場合は右 Control と Shift、タップした場合は `kc` | -| `LCAG_T(kc)` | | 押したままの場合は左 Control、Alt、GUI、タップした場合は `kc` | -| `RCAG_T(kc)` | | 押したままの場合は右 Control、Alt、GUI、タップした場合は `kc` | -| `C_S_T(kc)` | | 押したままの場合は左 Control と Shift、タップした場合は `kc` | -| `MEH_T(kc)` | | 押したままの場合は左 Control、Shift、Alt、タップした場合は `kc` | -| `HYPR_T(kc)` | `ALL_T(kc)` | 押したままの場合は左 Control、Shift、Alt、GUI、タップした場合は `kc` - より詳しくは[ここ](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)を見てください | - -## RGB ライト :id=rgb-lighting - -[RGB ライト](ja/feature_rgblight.md) も見てください。 - -|キー |エイリアス|説明 | -|-------------------|----------|---------------------------------------------------------------------| -|`RGB_TOG` | |RGB ライトのオン・オフを切り替え | -|`RGB_MODE_FORWARD` |`RGB_MOD` |RGB モードを順送りで変更し、Shift を押していると逆順で変更します。 | -|`RGB_MODE_REVERSE` |`RGB_RMOD`|RGB モードを逆順で変更し、Shift を押していると順送りで変更します。 | -|`RGB_HUI` | |色相 (HUE) を増加させ、Shift を押していると減少させます。 | -|`RGB_HUD` | |色相 (HUE) を減少させ、Shift を押していると増加させます。 | -|`RGB_SAI` | |彩度 (SAT) を増加させ、Shift を押していると減少させます。 | -|`RGB_SAD` | |彩度 (SAT) を減少させ、Shift を押していると増加させます。 | -|`RGB_VAI` | |明度 (VAL/brightness) を増加させ、Shift を押していると減少させます。 | -|`RGB_VAD` | |明度 (VAL/brightness) を減少させ、Shift を押していると増加させます。 | -|`RGB_MODE_PLAIN` |`RGB_M_P `|静止(動き無し) モードに固定します | -|`RGB_MODE_BREATHE` |`RGB_M_B` |明滅アニメーションモード | -|`RGB_MODE_RAINBOW` |`RGB_M_R` |レインボーアニメーションモード | -|`RGB_MODE_SWIRL` |`RGB_M_SW`|渦巻アニメーションモード | -|`RGB_MODE_SNAKE` |`RGB_M_SN`|スネークアニメーションモード | -|`RGB_MODE_KNIGHT` |`RGB_M_K` |「ナイトライダー」アニメーションモード | -|`RGB_MODE_XMAS` |`RGB_M_X` |クリスマスアニメーションモード | -|`RGB_MODE_GRADIENT`|`RGB_M_G` |固定階調アニメーションモード | -|`RGB_MODE_RGBTEST` |`RGB_M_T` |赤、緑、青のテストアニメーションモード | - -## RGB マトリックスライト :id=rgb-matrix-lighting - -[RGB マトリックスライト](ja/feature_rgb_matrix.md) も見てください。 - -|キー |エイリアス|説明 | -|-------------------|----------|--------------------------------------------------------------------------------------------------------| -|`RGB_TOG` | |RGB ライトのオン・オフを切り替え | -|`RGB_MODE_FORWARD` |`RGB_MOD` |RGB モードを順送りで変更し、Shift を押していると逆順で変更します。 | -|`RGB_MODE_REVERSE` |`RGB_RMOD`|RGB モードを逆順で変更し、Shift を押していると順送りで変更します。 | -|`RGB_HUI` | |色相 (HUE) を増加させ、Shift を押していると減少させます。 | -|`RGB_HUD` | |色相 (HUE) を減少させ、Shift を押していると増加させます。 | -|`RGB_SAI` | |彩度 (SAT) を増加させ、Shift を押していると減少させます。 | -|`RGB_SAD` | |彩度 (SAT) を減少させ、Shift を押していると増加させます。 | -|`RGB_VAI` | |明度 (VAL/brightness) を増加させ、Shift を押していると減少させます。 | -|`RGB_VAD` | |明度 (VAL/brightness) を減少させ、Shift を押していると増加させます。 | -|`RGB_SPI` | |エフェクトのスピード (EEPROM はまだサポートしていません) を増加させ、Shift を押していると減少させます。 | -|`RGB_SPD` | |エフェクトのスピード (EEPROM はまだサポートしていません) を減少させ、Shift を押していると増加させます。 | - -## 感熱式プリンタ :id=thermal-printer - -[感熱式プリンタ](ja/feature_thermal_printer.md) も見てください。 - -|キー |説明 | -|-----------|---------------------------------| -|`PRINT_ON` |ユーザが入力した全ての印刷を開始 | -|`PRINT_OFF`|ユーザが入力した全ての印刷を停止 | - -## US ANSI シフト済シンボル :id=us-ansi-shifted-symbols - -[US ANSI シフト済シンボル](ja/keycodes_us_ansi_shifted.md) も見てください。 - -|キー |エイリアス |説明| -|------------------------|-------------------|-----------| -|`KC_TILDE` |`KC_TILD` |`~` | -|`KC_EXCLAIM` |`KC_EXLM` |`!` | -|`KC_AT` | |`@` | -|`KC_HASH` | |`#` | -|`KC_DOLLAR` |`KC_DLR` |`$` | -|`KC_PERCENT` |`KC_PERC` |`%` | -|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | -|`KC_AMPERSAND` |`KC_AMPR` |`&` | -|`KC_ASTERISK` |`KC_ASTR` |`*` | -|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | -|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | -|`KC_UNDERSCORE` |`KC_UNDS` |`_` | -|`KC_PLUS` | |`+` | -|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | -|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | -|`KC_PIPE` | |`\|` | -|`KC_COLON` |`KC_COLN` |`:` | -|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | -|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | -|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | -|`KC_QUESTION` |`KC_QUES` |`?` | - -## ワンショットキー :id=one-shot-keys - -[ワンショットキー](ja/one_shot_keys.md) も見てください。 - -|キー |説明 | -|------------|--------------------------------| -|`OSM(mod)` | 次のキーが押されるまで、`mod` を押したままにします | -|`OSL(layer)`| 次のキーが押されるまで、一時的にレイヤーをアクティブにします | - -## Space Cadet :id=space-cadet - -[Space Cadet](ja/feature_space_cadet.md) も見てください。 - -|キー |説明 | -|-----------|-------------------------------------------| -|`KC_LCPO` |押したままの場合は左 Control、タップした場合は `(` | -|`KC_RCPC` |押したままの場合は右 Control、タップした場合は `)` | -|`KC_LSPO` |押したままの場合は左 Shift、タップした場合は `(`、 | -|`KC_RSPC` |押したままの場合は右 Shift、タップした場合は `)`、 | -|`KC_LAPO` |押したままの場合は左 Alt、タップした場合は `(`、 | -|`KC_RAPC` |押したままの場合は右 Alt、タップした場合は `)`、 | -|`KC_SFTENT`|押したままの場合は右 Shift、タップした場合は Enter | - -## スワップハンド :id=swap-hands - -[スワップハンド](ja/feature_swap_hands.md) も見てください。 - -|キー |説明 | -|-------------|----------------------------------------------------------------------------------| -| `SH_T(key)` | タップで `key` を送信する。押している時に一時的に入れ替え。 | -| `SH_ON` | 入れ替えをオンにして、そのままにする。 | -| `SH_OFF` | 入れ替えをオフにして、そのままにする。既知の状態に戻るのに適しています。 | -| `SH_MON` | 押すとスワップハンドし、放すと通常に戻る (一時的)。 | -| `SH_MOFF` | 一時的に入れ替えをオフする。 | -| `SH_TG` | キーを押すたびにオンとオフを切り替える。 | -| `SH_TT` | タップで切り替える。押している時に一時的に切り替える。 | -| `SH_OS` | ワンショットスワップハンド: 押している時あるいは次のキーを押すまで切り替える。 | - -## ユニコードサポート :id=unicode-support - -[ユニコードサポート](ja/feature_unicode.md) も見てください。 - -|キー |エイリアス |説明 | -|----------------------|-----------|----------------------------------------------------------------------| -|`UC(c)` | |コードポイント `c` のユニコードを送信 | -|`X(i)` | |`unicode_map` のインデックス `i` のユニコードを送信 | -|`XP(i, j)` | |Shift/Capsが有効なら、インデックス `i` または `j` のユニコードを送信 | -|`UNICODE_MODE_FORWARD`|`UC_MOD` |ユニコード入力方式を順送りで選択 | -|`UNICODE_MODE_REVERSE`|`UC_RMOD` |ユニコード入力方式を逆順で選択 | -|`UNICODE_MODE_OSX` |`UC_M_OS` |ユニコード入力方式を macOS 方式に切り替え | -|`UNICODE_MODE_LNX` |`UC_M_LN` |ユニコード入力方式を Linux 方式に切り替え | -|`UNICODE_MODE_WIN` |`UC_M_WI` |ユニコード入力方式を Windows 方式に切り替え | -|`UNICODE_MODE_BSD` |`UC_M_BS` |ユニコード入力方式を BSD 方式に切り替え (実装されていません) | -|`UNICODE_MODE_WINC` |`UC_M_WC` |ユニコード入力方式を WinCompose を使う Windows 方式に切り替え | diff --git a/docs/ja/keycodes_basic.md b/docs/ja/keycodes_basic.md deleted file mode 100644 index 2ef8e4955d74..000000000000 --- a/docs/ja/keycodes_basic.md +++ /dev/null @@ -1,261 +0,0 @@ -# 基本的なキーコード - - - -基本的なキーコードのセットは、`KC_NO`、`KC_TRNS` と `0xA5-DF` の範囲のキーコードを除いて、[HID Keyboard/Keypad Usage Page (0x07)](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) に基づいています。 - -## 文字と数字 - -|キー |説明 | -|------|----------| -|`KC_A`|`a` と `A`| -|`KC_B`|`b` と `B`| -|`KC_C`|`c` と `C`| -|`KC_D`|`d` と `D`| -|`KC_E`|`e` と `E`| -|`KC_F`|`f` と `F`| -|`KC_G`|`g` と `G`| -|`KC_H`|`h` と `H`| -|`KC_I`|`i` と `I`| -|`KC_J`|`j` と `J`| -|`KC_K`|`k` と `K`| -|`KC_L`|`l` と `L`| -|`KC_M`|`m` と `M`| -|`KC_N`|`n` と `N`| -|`KC_O`|`o` と `O`| -|`KC_P`|`p` と `P`| -|`KC_Q`|`q` と `Q`| -|`KC_R`|`r` と `R`| -|`KC_S`|`s` と `S`| -|`KC_T`|`t` と `T`| -|`KC_U`|`u` と `U`| -|`KC_V`|`v` と `V`| -|`KC_W`|`w` と `W`| -|`KC_X`|`x` と `X`| -|`KC_Y`|`y` と `Y`| -|`KC_Z`|`z` と `Z`| -|`KC_1`|`1` と `!`| -|`KC_2`|`2` と `@`| -|`KC_3`|`3` と `#`| -|`KC_4`|`4` と `$`| -|`KC_5`|`5` と `%`| -|`KC_6`|`6` と `^`| -|`KC_7`|`7` と `&`| -|`KC_8`|`8` と `*`| -|`KC_9`|`9` と `(`| -|`KC_0`|`0` と `)`| - -## ファンクションキー - -|キー |説明 | -|--------|-----| -|`KC_F1` |F1 | -|`KC_F2` |F2 | -|`KC_F3` |F3 | -|`KC_F4` |F4 | -|`KC_F5` |F5 | -|`KC_F6` |F6 | -|`KC_F7` |F7 | -|`KC_F8` |F8 | -|`KC_F9` |F9 | -|`KC_F10`|F10 | -|`KC_F11`|F11 | -|`KC_F12`|F12 | -|`KC_F13`|F13 | -|`KC_F14`|F14 | -|`KC_F15`|F15 | -|`KC_F16`|F16 | -|`KC_F17`|F17 | -|`KC_F18`|F18 | -|`KC_F19`|F19 | -|`KC_F20`|F20 | -|`KC_F21`|F21 | -|`KC_F22`|F22 | -|`KC_F23`|F23 | -|`KC_F24`|F24 | - -## パンクチュエーション - -|キー |エイリアス |説明 | -|-----------------|-------------------|----------------------------------------------| -|`KC_ENTER` |`KC_ENT` |Return (Enter) | -|`KC_ESCAPE` |`KC_ESC` |Escape | -|`KC_BSPACE` |`KC_BSPC` |Delete (Backspace) | -|`KC_TAB` | |Tab | -|`KC_SPACE` |`KC_SPC` |Spacebar | -|`KC_MINUS` |`KC_MINS` |`-` と `_` | -|`KC_EQUAL` |`KC_EQL` |`=` と `+` | -|`KC_LBRACKET` |`KC_LBRC` |`[` と `{` | -|`KC_RBRACKET` |`KC_RBRC` |`]` と `}` | -|`KC_BSLASH` |`KC_BSLS` |`\` と `\|` | -|`KC_NONUS_HASH` |`KC_NUHS` |Non-US `#` と `~` | -|`KC_SCOLON` |`KC_SCLN` |`;` と `:` | -|`KC_QUOTE` |`KC_QUOT` |`'` と `"` | -|`KC_GRAVE` |`KC_GRV`, `KC_ZKHK`|` と `~`, JIS 全角/半角 | -|`KC_COMMA` |`KC_COMM` |`,` と `<` | -|`KC_DOT` | |`.` と `>` | -|`KC_SLASH` |`KC_SLSH` |`/` と `?` | -|`KC_NONUS_BSLASH`|`KC_NUBS` |Non-US `\` と `\|` | - -## ロックキー - -|キー |エイリアス |説明 | -|-------------------|--------------------|---------------------------------------| -|`KC_CAPSLOCK` |`KC_CLCK`, `KC_CAPS`|Caps Lock | -|`KC_SCROLLLOCK` |`KC_SCRL`, `KC_BRMD`|Scroll Lock, 画面の明るさダウン (macOS)| -|`KC_NUMLOCK` |`KC_NUM` |テンキー Num Lock と Clear | -|`KC_LOCKING_CAPS` |`KC_LCAP` |Caps Lock のロック | -|`KC_LOCKING_NUM` |`KC_LNUM` |Num Lock のロック | -|`KC_LOCKING_SCROLL`|`KC_LSCR` |Scroll Lock のロック | - -## 修飾キー - -|キー |エイリアス |説明 | -|-----------|--------------------|---------------------------------| -|`KC_LCTRL` |`KC_LCTL` |左 Control | -|`KC_LSHIFT`|`KC_LSFT` |左 Shift | -|`KC_LALT` |`KC_LOPT` |左 Alt (Option) | -|`KC_LGUI` |`KC_LCMD`, `KC_LWIN`|左 GUI (Windows/Command/Meta キー)| -|`KC_RCTRL` |`KC_RCTL` |右 Control | -|`KC_RSHIFT`|`KC_RSFT` |右 Shift | -|`KC_RALT` |`KC_ROPT`, `KC_ALGR`|右 Alt (Option/AltGr) | -|`KC_RGUI` |`KC_RCMD`, `KC_RWIN`|右 GUI (Windows/Command/Meta キー)| - -## 国際化対応キー - -|キー |エイリアス|説明 | -|----------|----------|---------------------| -|`KC_INT1` |`KC_RO` |JIS `\` と ` _` | -|`KC_INT2` |`KC_KANA` |JIS カタカナ/ひらがな| -|`KC_INT3` |`KC_JYEN` |JIS `¥` と `\ |` | -|`KC_INT4` |`KC_HENK` |JIS 変換 | -|`KC_INT5` |`KC_MHEN` |JIS 無変換 | -|`KC_INT6` | |JIS テンキー `,` | -|`KC_INT7` | |International 7 | -|`KC_INT8` | |International 8 | -|`KC_INT9` | |International 9 | -|`KC_LANG1`|`KC_HAEN` |ハングル/英語 | -|`KC_LANG2`|`KC_HANJ` |韓文漢字 | -|`KC_LANG3`| |JIS カタカナ | -|`KC_LANG4`| |JIS ひらがな | -|`KC_LANG5`| |JIS 全角/半角 | -|`KC_LANG6`| |Language 6 | -|`KC_LANG7`| |Language 7 | -|`KC_LANG8`| |Language 8 | -|`KC_LANG9`| |Language 9 | - -## コマンドキー - -|キー |エイリアス |説明 | -|------------------|------------------------------|-------------------------------------------------------| -|`KC_PSCREEN` |`KC_PSCR` |Print Screen | -|`KC_PAUSE` |`KC_PAUS`, `KC_BRK`, `KC_BRMU`|Pause, 画面の明るさアップ (macOS) | -|`KC_INSERT` |`KC_INS` |Insert | -|`KC_HOME` | |Home | -|`KC_PGUP` | |Page Up | -|`KC_DELETE` |`KC_DEL` |Forward Delete | -|`KC_END` | |End | -|`KC_PGDOWN` |`KC_PGDN` |Page Down | -|`KC_RIGHT` |`KC_RGHT` |右矢印 | -|`KC_LEFT` | |左矢印 | -|`KC_DOWN` | |下矢印 | -|`KC_UP` | |上矢印 | -|`KC_APPLICATION` |`KC_APP` |アプリケーションキー (Windows コンテキストメニューキー)| -|`KC_POWER` | |システム電源 | -|`KC_EXECUTE` |`KC_EXEC` |Execute | -|`KC_HELP` | |Help | -|`KC_MENU` | |Menu | -|`KC_SELECT` |`KC_SLCT` |Select | -|`KC_STOP` | |Stop | -|`KC_AGAIN` |`KC_AGIN` |Again | -|`KC_UNDO` | |アンドゥ | -|`KC_CUT` | |カット | -|`KC_COPY` | |コピー | -|`KC_PASTE` |`KC_PSTE` |ペースト | -|`KC_FIND` | |検索 | -|`KC__MUTE` | |ミュート | -|`KC__VOLUP` | |音量アップ | -|`KC__VOLDOWN` | |音量ダウン | -|`KC_ALT_ERASE` |`KC_ERAS` |Alternate Erase | -|`KC_SYSREQ` | |SysReq/Attention | -|`KC_CANCEL` | |Cancel | -|`KC_CLEAR` |`KC_CLR` |Clear | -|`KC_PRIOR` | |Prior | -|`KC_RETURN` | |Return | -|`KC_SEPARATOR` | |Separator | -|`KC_OUT` | |Out | -|`KC_OPER` | |Oper | -|`KC_CLEAR_AGAIN` | |Clear/Again | -|`KC_CRSEL` | |CrSel/Props | -|`KC_EXSEL` | |ExSel | - -## メディアキー - -これらのキーコードは、HID Keyboard/Keypad usage ページにはありません。`SYSTEM_` キーコードは、Generic Desktop ページで見つかります。また、その他は Consumer ページにあります。 - -?> これらのキーコードのいくつかは、OS によって異なる動作をする可能性があります。例として、macOS では `KC_MEDIA_FAST_FORWARD`、`KC_MEDIA_REWIND`、`KC_MEDIA_NEXT_TRACK`、`KC_MEDIA_PREV_TRACK` は、押している間は現在の曲の中でスキップしますが、タップした時は曲全体をスキップします。 - -|キー |エイリアス |説明 | -|-----------------------|-----------|----------------------| -|`KC_SYSTEM_POWER` |`KC_PWR` |システム電源オフ | -|`KC_SYSTEM_SLEEP` |`KC_SLEP` |システムスリープ | -|`KC_SYSTEM_WAKE` |`KC_WAKE` |システムスリープ解除 | -|`KC_AUDIO_MUTE` |`KC_MUTE` |ミュート | -|`KC_AUDIO_VOL_UP` |`KC_VOLU` |音量アップ | -|`KC_AUDIO_VOL_DOWN` |`KC_VOLD` |音量ダウン | -|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT` |次の曲へ | -|`KC_MEDIA_PREV_TRACK` |`KC_MPRV` |前の曲へ | -|`KC_MEDIA_STOP` |`KC_MSTP` |再生停止 | -|`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY` |再生/一時停止 | -|`KC_MEDIA_SELECT` |`KC_MSEL` |Media Player 起動 | -|`KC_MEDIA_EJECT` |`KC_EJCT` |イジェクト | -|`KC_MAIL` | |メール起動 | -|`KC_CALCULATOR` |`KC_CALC` |電卓起動 | -|`KC_MY_COMPUTER` |`KC_MYCM` |マイコンピュータを開く| -|`KC_WWW_SEARCH` |`KC_WSCH` |ブラウザ検索 | -|`KC_WWW_HOME` |`KC_WHOM` |ブラウザホーム画面 | -|`KC_WWW_BACK` |`KC_WBAK` |ブラウザ戻る | -|`KC_WWW_FORWARD` |`KC_WFWD` |ブラウザ進む | -|`KC_WWW_STOP` |`KC_WSTP` |ブラウザ読み込み中止 | -|`KC_WWW_REFRESH` |`KC_WREF` |ブラウザ再読み込み | -|`KC_WWW_FAVORITES` |`KC_WFAV` |ブラウザお気に入り | -|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD` |次の曲へ | -|`KC_MEDIA_REWIND` |`KC_MRWD` |前の曲へ | -|`KC_BRIGHTNESS_UP` |`KC_BRIU` |画面の明るさアップ | -|`KC_BRIGHTNESS_DOWN` |`KC_BRID` |画面の明るさダウン | - -## テンキー - -|キー |エイリアス |説明 | -|-------------------|-----------|-------------------------------| -|`KC_KP_SLASH` |`KC_PSLS` |テンキー `/` | -|`KC_KP_ASTERISK` |`KC_PAST` |テンキー `*` | -|`KC_KP_MINUS` |`KC_PMNS` |テンキー `-` | -|`KC_KP_PLUS` |`KC_PPLS` |テンキー `+` | -|`KC_KP_ENTER` |`KC_PENT` |テンキー Enter | -|`KC_KP_1` |`KC_P1` |テンキー `1` と End | -|`KC_KP_2` |`KC_P2` |テンキー `2` と 下矢印 | -|`KC_KP_3` |`KC_P3` |テンキー `3` と Page Down | -|`KC_KP_4` |`KC_P4` |テンキー `4` と 左矢印 | -|`KC_KP_5` |`KC_P5` |テンキー `5` | -|`KC_KP_6` |`KC_P6` |テンキー `6` と 右矢印 | -|`KC_KP_7` |`KC_P7` |テンキー `7` と Home | -|`KC_KP_8` |`KC_P8` |テンキー `8` と 上矢印 | -|`KC_KP_9` |`KC_P9` |テンキー `9` と Page Up | -|`KC_KP_0` |`KC_P0` |テンキー `0` と Insert | -|`KC_KP_DOT` |`KC_PDOT` |テンキー `.` と Delete | -|`KC_KP_EQUAL` |`KC_PEQL` |テンキー `=` | -|`KC_KP_COMMA` |`KC_PCMM` |テンキー `,` | -|`KC_KP_EQUAL_AS400`| |AS/400 キーボードのテンキー `=`| - -## 特別なキー - -これらのキーコードに加えて、`0xA5-DF` の範囲のキーコードは、内部処理のために予約されています。 - -|キー |エイリアス |説明 | -|----------------|--------------------|-----------------------------------| -|`KC_NO` |`XXXXXXX` |このキーを無視します (NOOP) | -|`KC_TRANSPARENT`|`KC_TRNS`, `_______`|次に低いレイヤーの非透過キーを使う | diff --git a/docs/ja/keycodes_us_ansi_shifted.md b/docs/ja/keycodes_us_ansi_shifted.md deleted file mode 100644 index 3a574d0bed5c..000000000000 --- a/docs/ja/keycodes_us_ansi_shifted.md +++ /dev/null @@ -1,41 +0,0 @@ -# US ANSI シフト記号 - - -これらのキーコードは、標準の US ANSI 配列のキーボードで「シフトされる」文字に対応します。これらのキーコードは自身のキーコードを持たず、`LSFT(kc)` の単なるショートカットであり、記号自体ではなく Shift キー抜きのキーコードと左 Shift キーを送信します。 - -## 注意書き - -残念ながら、これらのキーコードは、モッドタップやレイヤータップの中で使えません。キーコードで指定されたモディファイアは無視されるからです。 - -さらに、Windows でリモートデスクトップ接続を使う場合に、問題が発生する場合があります。なぜならば、これらのコードは Shift キーを非常に速く送信するため、リモートデスクトップがコードを見落とすかもしれないからです。 - -この問題を解決するには、リモートデスクトップ接続を開いて「オプションの表示」をクリックし、「ローカル リソース」タブを開きます。キーボードセクションでドロップダウンを「このコンピュータ」に変更します。これで問題が解決され、文字が正しく機能するようになります。 - -## キーコード - -|キー |エイリアス |説明 | -|------------------------|-------------------|-----------| -|`KC_TILDE` |`KC_TILD` |`~` | -|`KC_EXCLAIM` |`KC_EXLM` |`!` | -|`KC_AT` | |`@` | -|`KC_HASH` | |`#` | -|`KC_DOLLAR` |`KC_DLR` |`$` | -|`KC_PERCENT` |`KC_PERC` |`%` | -|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | -|`KC_AMPERSAND` |`KC_AMPR` |`&` | -|`KC_ASTERISK` |`KC_ASTR` |`*` | -|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | -|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | -|`KC_UNDERSCORE` |`KC_UNDS` |`_` | -|`KC_PLUS` | |`+` | -|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | -|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | -|`KC_PIPE` | |`\|` | -|`KC_COLON` |`KC_COLN` |`:` | -|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | -|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | -|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | -|`KC_QUESTION` |`KC_QUES` |`?` | diff --git a/docs/ja/keymap.md b/docs/ja/keymap.md deleted file mode 100644 index 2863bd49b54a..000000000000 --- a/docs/ja/keymap.md +++ /dev/null @@ -1,189 +0,0 @@ -# キーマップの概要 - - - -QMK のキーマップは C のソースファイルの中で定義されます。そのデータ構造は配列の配列です。外側はレイヤーを要素とする配列で、レイヤーはキーを要素とする配列。ほとんどのキーボードは `LAYOUT()` マクロを定義して、この配列の配列を作成しやすくしています。 - - -## キーマップとレイヤー :id=keymap-and-layers -QMKでは、**`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`**は、**アクションコード**を保持している **16 bit** データの中でキーマップ情報の複数の**レイヤー**を保持します。最大で**32個のレイヤー**を定義することができます。 - -普通のキー定義の場合、**アクションコード**の上位8ビットは全て0で、下位8ビットは**キーコード**としてキーによって生成された USB HID usage コードを保持します。 - -各レイヤーは同時に有効にできます。レイヤーには 0 から 31 までのインデックスが付けられ、上位のレイヤーが優先されます。 - - Keymap: 32 Layers Layer: action code matrix - ----------------- --------------------- - stack of layers array_of_action_code[row][column] - ____________ precedence _______________________ - / / | high / ESC / F1 / F2 / F3 .... - 31 /___________// | /-----/-----/-----/----- - 30 /___________// | / TAB / Q / W / E .... - 29 /___________/ | /-----/-----/-----/----- - : _:_:_:_:_:__ | : /LCtrl/ A / S / D .... - : / : : : : : / | : / : : : : - 2 /___________// | 2 `-------------------------- - 1 /___________// | 1 `-------------------------- - 0 /___________/ V low 0 `-------------------------- - - -TMK の歴史的経緯から、キーマップに保存されたアクションコードは、一部のドキュメントではキーコードと呼ばれる場合があります。 - -### キーマップレイヤーステータス :id=keymap-layer-status - -キーマップレイヤーの状態は、2つの32ビットパラメータによって決定されます。 - -* **`default_layer_state`** は、常に有効で参照される基本キーマップレイヤー (0-31) を示します (デフォルトレイヤー)。 -* **`layer_state`** は現在の各レイヤーのオン/オフの状態をビットで持ちます。 - -キーマップレイヤー '0' は通常 `default_layer` で、他のレイヤーはファームウェアの起動後に最初はオフになっていますが、これは `config.h` で異なる設定にすることが可能です。例えば Qwerty ではなく Colemak に切り替えるなど、キーレイアウトを完全に切り替える場合、`default_layer` を変更すると便利です。 - - Initial state of Keymap Change base layout - ----------------------- ------------------ - - 31 31 - 30 30 - 29 29 - : : - : : ____________ - 2 ____________ 2 / / - 1 / / ,->1 /___________/ - ,->0 /___________/ | 0 - | | - `--- default_layer = 0 `--- default_layer = 1 - layer_state = 0x00000001 layer_state = 0x00000002 - -一方、`layer_state` を変更して、基本レイヤーをナビゲーションキー、ファンクションキー (F1-F12)、メディアキー、特別なアクションなどの機能を持つ他のレイヤーでオーバーレイすることができます。 - - Overlay feature layer - --------------------- bit|status - ____________ ---+------ - 31 / / 31 | 0 - 30 /___________// -----> 30 | 1 - 29 /___________/ -----> 29 | 1 - : : | : - : ____________ : | : - 2 / / 2 | 0 - ,->1 /___________/ -----> 1 | 1 - | 0 0 | 0 - | + - `--- default_layer = 1 | - layer_state = 0x60000002 <-' - - - -### レイヤーの優先順位と透過性 -***上位のレイヤーはレイヤーのスタックでより高い優先順位を持つ***ことに注意してください。ファームウェアは最上位のアクティブレイヤーから下に向かってキーコードを検索します。ファームウェアがアクティブなレイヤーで `KC_TRNS` (透過)以外のキーコードを見つけると、検索を停止し、下位レイヤーは参照されません。 - - ____________ - / / <--- Higher layer - / KC_TRNS // - /___________// <--- Lower layer (KC_A) - /___________/ - - 上記シナリオでは、上位レイヤーに非透過のキーが定義されているとそのキーが使われますが、`KC_TRNS` (または同等のキーコード)が定義されている場合は常に下位レベルのキーコード(`KC_A`)が使われます。 - -**メモ:** 特定のレイヤーの透過性を示す有効な方法: -* `KC_TRANSPARENT` -* `KC_TRNS` (別名) -* `_______` (別名) - -これらのキーコードは、処理する非透過のキーコードを探すときに、下位レイヤーを検索させることができます。 - -## `keymap.c` の分析 - -この例では、[デフォルトの Clueboard 66% キーマップの古いバージョン](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c)を見ていきます。そのファイルを別のブラウザウィンドウで開くとコンテキスト内のすべてを見ることができるので便利です。 - -`keymap.c` ファイルには、あなたが関心があるであろう以下の2つの主要なセクションがあります: - -* [定義](#definitions) -* [レイヤー/キーマップデータ構造](#layers-and-keymaps) - -### 定義 :id=definitions - -ファイルの上部に以下のものがあります: - - #include QMK_KEYBOARD_H - - // 便利な定義 - #define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * KC_TRNS (透過) の代わりに _______ を使うことができます * - * あるいは、KC_NO (NOOP) として XXXXXXX を使うことができます * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - // 各レイヤーは読みやすいように名前を持ちます。 - // アンダースコアは何も意味を持ちません - // STUFF あるいは他の名前のレイヤーを持つことができます。 - // レイヤー名は全て同じ長さである必要はなく、 - // また名前を完全に省略して単に数字を使うことができます。 - enum layer_names { - _BL, - _FL, - _CL, - }; - -これらはキーマップとカスタム関数を作成するときに使うことができる便利な定義です。`GRAVE_MODS` 定義は後でカスタム関数で使われ、その下の `_BL`、`_FL`、`_CL` 定義は各レイヤーを参照しやすくします。 - -注意: 古いキーマップファイルに `_______` および `XXXXXXX` の定義が含まれているかもしれません。これらはそれぞれ `KC_TRNS` および `KC_NO` の代わりに使うことができ、レイヤーがどのキーを上書きしているかを簡単に確認することができます。これらの定義はデフォルトで含まれるため、今では不要になりました。 - -### レイヤーとキーマップ :id=layers-and-keymaps - -このファイルの主要部分は `keymaps[]` 定義です。ここで、レイヤーとそれらの内容を列挙します。ファイルのこの部分は、以下の定義から始まります: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -この後で、LAYOUT() マクロのリストがあります。LAYOUT() は単一のレイヤーを定義するためのキーのリストです。通常、1つ以上の"基本レイヤー" (QWERTY、Dvorak、Colemak など)があり、その上に1つ以上の"機能"レイヤーを重ねます。レイヤーの処理方法により、"より上位"のレイヤーの上に"より下位"のレイヤーを重ねることはできません。 - -QMK の `keymaps[][MATRIX_ROWS][MATRIX_COLS]` は、16ビットのアクションコード( quantum キーコードとも呼ばれる)を保持します。一般的なキーを表すキーコードの場合、その上位バイトは0で、その下位バイトはキーボードの USB HID usage ID です。 - -> QMK のフォーク元の TMK は、代わりに `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` を使い、8ビットキーコードを保持します。一部のキーコード値は、`fn_actions[]` 配列を介して特定のアクションコードの実行を引き起こすために予約されています。 - -#### 基本レイヤー - -Clueboard の基本レイヤーの例です: - - /* Keymap _BL: Base Layer (Default Layer) - */ - [_BL] = LAYOUT( - F(0), 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_GRV, KC_BSPC, KC_PGUP, \ - 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_PGDN, \ - 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_NUHS, KC_ENT, \ - KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_RSFT, KC_UP, \ - KC_LCTL, KC_LGUI, KC_LALT, KC_MHEN, KC_SPC,KC_SPC, KC_HENK, KC_RALT, KC_RCTL, MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT), - -これについて注意すべきいくつかの興味深いこと: - -* C ソースの観点からは、これは単一の配列に過ぎませんが、物理デバイス上の各キーがどこにあるかをより簡単に可視化するために、空白が埋め込まれています。 -* 単純なキーボードスキャンコードの先頭には KC_ が付いていますが、"特別な"キーには付いていません。 -* 左上のキーはカスタム機能 0 (`F(0)`) をアクティブにします。 -* "Fn" キーは `MO(_FL)` で定義され、そのキーが押されている間は `_FL` レイヤーに移動します。 - -#### 機能オーバーレイレイヤー - -機能レイヤーはコードの観点から基本レイヤーと違いはありません。ただし概念的には、置き換えの代わりにオーバーレイとしてそのレイヤーを構築します。多くの人にとってはこの区別は重要ではありませんが、より複雑なレイヤー設定を構築するにつれて、ますます重要になります。 - - [_FL] = LAYOUT( - 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, BL_STEP, \ - _______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,KC_SCRL, KC_PAUS, _______, _______, _______, _______, \ - _______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ - _______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, \ - _______, _______, _______, _______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END), - -注意すべきいくつかの興味深いこと: - -* `_______` 定義を使って、`KC_TRNS` を `_______` に変換しました。これによりこのレイヤーで変更されたキーを簡単に見つけることができます。 -* このレイヤーで `_______` キーのいずれかを押すと、次の下位のアクティブなレイヤーのキーがアクティブになります。 - -# 核心となる詳細 - -これで独自のキーマップを作成するための基本的な概要が得られました。詳細は以下のリソースを見てください: - -* [キーコード](ja/keycodes.md) -* [キーマップ FAQ](ja/faq_keymap.md) - -これらのドキュメントの改善に積極的に取り組んでいます。それらを改善する方法について提案がある場合は、[issue を報告](https://github.com/qmk/qmk_firmware/issues/new)してください! diff --git a/docs/ja/mod_tap.md b/docs/ja/mod_tap.md deleted file mode 100644 index 1d96ed1ee865..000000000000 --- a/docs/ja/mod_tap.md +++ /dev/null @@ -1,71 +0,0 @@ -# モッドタップ - - - -モッドタップキー `MT(mod, kc)` は、押したままの時にモディファイアのように機能し、タップされた時に通常のキーのように振舞います。別の言い方をすると、タップした時に Escape を送信しますが、押したままの時に Control あるいは Shift キーとして機能するキーを持つことができます。 - -このキーコードと `OSM()` が受け付けるモディファイアは、`KC_` ではなく、`MOD_` の接頭辞が付いています: - -| モディファイア | 説明 | -|----------------|----------------------------------------------| -| `MOD_LCTL` | 左 Control | -| `MOD_LSFT` | 左 Shift | -| `MOD_LALT` | 左 Alt | -| `MOD_LGUI` | 左 GUI (Windows/Command/Meta キー) | -| `MOD_RCTL` | 右 Control | -| `MOD_RSFT` | 右 Shift | -| `MOD_RALT` | 右 Alt (AltGr) | -| `MOD_RGUI` | 右 GUI (Windows/Command/Meta キー) | -| `MOD_HYPR` | Hyper (左 Control、左 Shift、左 Alt、左 GUI) | -| `MOD_MEH` | Meh (左 Control、左 Shift、左 Alt) | - -以下のようにそれらを OR することで、これらを組み合わせることができます: - -```c -MT(MOD_LCTL | MOD_LSFT, KC_ESC) -``` - -押したままの時にこのキーは左 Control および左 Shift をアクティブにし、タップされた時に Escape を送信します。 - -便利なように、QMK はキーマップで一般的な組み合わせをよりコンパクトにするためのモッドタップショートカットを含んでいます: - -| キー | エイリアス | 説明 | -| ------------ | ----------------------------------------------------------------- | ---------------------------------------------------------------------- | -| `LCTL_T(kc)` | `CTL_T(kc)` | 押したままの場合は左 Control、タップした場合は `kc` | -| `LSFT_T(kc)` | `SFT_T(kc)` | 押したままの場合は左 Shift、タップした場合は `kc` | -| `LALT_T(kc)` | `LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` | 押したままの場合は左 Alt、タップした場合は `kc` | -| `LGUI_T(kc)` | `LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)` | 押したままの場合は左 GUI、タップした場合は `kc` | -| `RCTL_T(kc)` | | 押したままの場合は右 Control、タップした場合は `kc` | -| `RSFT_T(kc)` | | 押したままの場合は右 Shift、タップした場合は `kc` | -| `RALT_T(kc)` | `ROPT_T(kc)`, `ALGR_T(kc)` | 押したままの場合は右 Alt、タップした場合は `kc` | -| `RGUI_T(kc)` | `RCMD_T(kc)`, `RWIN_T(kc)` | 押したままの場合は右 GUI、タップした場合は `kc` | -| `LSG_T(kc)` | `SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` | 押したままの場合は左 Shift と左 GUI、タップした場合は `kc` | -| `LAG_T(kc)` | | 押したままの場合は左 Alt と左 GUI、タップした場合は `kc` | -| `RSG_T(kc)` | | 押したままの場合は右 Shift と右 GUI、タップした場合は `kc` | -| `RAG_T(kc)` | | 押したままの場合は右 Alt と右 GUI、タップした場合は `kc` | -| `LCA_T(kc)` | | 押したままの場合は左 Control と左 Alt、タップした場合は `kc` | -| `LSA_T(kc)` | | 押したままの場合は左 Shift と Alt、タップした場合は `kc` | -| `RSA_T(kc)` | `SAGR_T(kc)` | 押したままの場合は右 Shift と Alt (AltGr)、タップした場合は `kc` | -| `RCS_T(kc)` | | 押したままの場合は右 Control と Shift、タップした場合は `kc` | -| `LCAG_T(kc)` | | 押したままの場合は左 Control、左 Alt と左 GUI、タップした場合は `kc` | -| `RCAG_T(kc)` | | 押したままの場合は右 Control、右 Alt と右 GUI、タップした場合は `kc` | -| `C_S_T(kc)` | | 押したままの場合は左 Control と左 Shift、タップした場合は `kc` | -| `MEH_T(kc)` | | 押したままの場合は左 Control、左 Shift と左 Alt、タップした場合は `kc` | -| `HYPR_T(kc)` | `ALL_T(kc)` | 押したままの場合は左 Control、左 Shift、左 Alt と左 GUI、タップした場合は `kc` - より詳しくは[ここ](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)を見てください | - -## 注意事項 - -現在のところ、`MT()` の引数 `kc` は[基本的なキーコードセット](ja/keycodes_basic.md)に制限されています。つまり、`LCTL()`、`KC_TILD`、あるいは `0xFF` より大きなキーコードを使うことができません。これは、QMK が16ビットのキーコードを使うためです。3ビットは機能の識別のために使われ、1ビットは右または左の mod を選択するために使われ、4ビットはどの mod かを区別するために使われ、キーコードには8ビットしか残されていません。さらに、モッドタップで少なくとも1つの右手用のモディファイアが指定された場合、指定された全てのモディファイアが右手用になるため、2つをうまく組み合わせて一致させることはできません。例えば、左 Control と右 Shift は、右 Control と右 Shift になります。 - -これを拡張してもせいぜい複雑になるだけでしょう。32ビットキーコードに移行すると、これの多くが解決されますが、キーマップマトリックスが使用する領域が2倍になります。また、問題が起きる可能性もあります。タップしたキーコードにモディファイアを適用する必要がある場合は、[タップダンス](ja/feature_tap_dance.md#example-5)を使うことができます。 - -さらに、Windows でリモートデスクトップ接続を使う場合に、問題が発生する場合があります。なぜならば、これらのキーコードは人よりも速くキーイベントを送信するため、リモートデスクトップがキーコードを見落とすかもしれないからです。 -この問題を解決するには、リモートデスクトップ接続を開いて「オプションの表示」をクリックし、「ローカル リソース」タブを開きます。キーボードセクションで、ドロップダウンを「このコンピューター」に変更します。これで問題が解決され、文字が正しく機能するようになります。 -[`TAP_CODE_DELAY`](ja/config_options.md#behaviors-that-can-be-configured) を増やすことで緩和することもできます。 - -## 他のリソース - -モッドタップの動作を調整する追加フラグについては、[タップホールド設定オプション](ja/tap_hold.md)を参照してください。 diff --git a/docs/ja/newbs.md b/docs/ja/newbs.md deleted file mode 100644 index 5fdf40425a7e..000000000000 --- a/docs/ja/newbs.md +++ /dev/null @@ -1,40 +0,0 @@ -# QMK チュートリアル - - - -キーボードには、コンピュータ入っているものと似たようなプロセッサが入っています。 -このプロセッサでは、キーボードのボタンの押し下げの検出を担当し、キーが押されたときにコンピュータに通知するソフトウェアが動作しています。 -QMK Firmware は、そのソフトウェアの役割を果たし、ボタンの押下を検出しその情報をホストコンピュータに渡します。 -カスタムキーマップを作るということは、キーボード上で動くプログラムを作るということなのです。 - -QMK は、簡単なことは簡単に、そして、難しいことを可能なことにすることで、あなたの手にたくさんのパワーをもたらします。 -パワフルなキーマップを作るためにプログラムを作成する方法を知る必要はありません。いくつかのシンプルな文法に従うだけで OK です。 - -お使いのキーボードで QMK を実行できるかどうか不明ですか? -もし作成したキーボードがメカニカルキーボードの場合、実行できる可能性が高いです。 -QMK は[多くの趣味のキーボード](https://qmk.fm/keyboards/)をサポートしています。 -現在使用しているキーボードが QMK を実行できない場合、QMK を実行できるキーボードの選択肢はたくさんあります。 - -?> **このガイドは私のためにあるのでしょうか?**
-もし、プログラミングの考え方に抵抗があるのであれば、代わりに[私たちのオンライン GUI](ja/newbs_building_firmware_configurator.md) を見てみてください。 - -## 概要 - -このガイドは、ソースコードを使ってキーボードのファームウェアを構築したいと考えている人に適しています。 もしあなたがすでにプログラマーであれば、このプロセスはとても身近で簡単に理解できるでしょう。このガイドには3つの主要なセクションがあります: - -1. [環境設定](ja/newbs_getting_started.md) -2. [コマンドラインを使用して初めてのファームウェアを構築する](ja/newbs_building_firmware.md) -3. [ファームウェアを書きこむ](ja/newbs_flashing.md) - -このガイドは、これまでソフトウェアをコンパイルしたことがない人を支援することに特化しています。 -その観点から選択と推奨を行います。 -これらの手順の多くには代替方法があり、これらの代替方法のほとんどをサポートしています。 -タスクを達成する方法について疑問がある場合は、[案内を求めることができます](ja/getting_started_getting_help.md)。 - -## 追加のリソース - -このガイドの他にも、QMK の学習に役立つリソースがいくつかあります。[シラバス](ja/syllabus.md)と[学習リソース](ja/newbs_learn_more_resources.md)のページにまとめました。 diff --git a/docs/ja/newbs_building_firmware.md b/docs/ja/newbs_building_firmware.md deleted file mode 100644 index 563efa71633d..000000000000 --- a/docs/ja/newbs_building_firmware.md +++ /dev/null @@ -1,81 +0,0 @@ -# 初めてのファームウェアを構築する(コマンドライン版) - - - -ビルド環境をセットアップしたので、カスタムファームウェアのビルドを開始する準備ができました。 -ガイドのこのセクションでは、ファイルマネージャ、テキストエディタ、ターミナルウィンドウの3つのプログラム間を行き来します。 -キーボードファームウェアが完成して満足するまで、この3つすべてを開いたままにします。 - -## 新しいキーマップを作成する - -独自のキーマップを作成するには、`default` キーマップのコピーを作成する必要があります。最後のステップでビルド環境を設定した場合は、QMK CLI を使って簡単に行うことができます: - - qmk new-keymap - -もし環境が設定されていない場合や、複数のキーボードを所持している場合は、キーボード名を指定することができます: - - qmk new-keymap -kb - -そのコマンドの出力を見ると、次のようになっているはずです: - - Ψ keymap directory created in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/ - -これがあなたの新しい `keymap.c` ファイルの場所です。 - -## あなたの好みのテキストエディタで `keymap.c` を開く - -テキストエディタで `keymap.c` ファイルを開きます。 -このファイル内には、キーボードの動作を制御する構造があります。 -`keymap.c`の上部には、キーマップを読みやすくする定義と列挙型があります。 -さらに下には、次のような行があります: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -この行はレイヤーのリストの開始を表わしています。 -その下には、`LAYOUT` を含む行があり、これらの行はレイヤーの開始を表わしています。 -その行の下には、そのレイヤーを構成するキーのリストがあります。 - -!> キーマップファイルを編集するときは、カンマを追加したり削除したりしないように注意してください。そうするとファームウェアのコンパイルができなくなり、余分であったり欠落していたりするカンマがどこにあるのかを容易に把握できない場合があります。 - -## 好みに合わせてレイアウトをカスタマイズ - -納得のいくまでこのステップを繰り返します。 -気になる点をひとつづつ変更して試すのもよし、全部作りなおすのもよし。 -あるレイヤー全体が必要ない場合はレイヤーを削除することもでき、必要があれば、合計 32 個までレイヤーを追加することもできます。 -QMK にはたくさんの機能があり、完全なリストは左側のサイドバーの「QMK を使う」の下を調べてください。ここから始めるために、簡単に使える機能をいくつか紹介します: - -* [基本的なキーコード](ja/keycodes_basic.md) -* [Quantum キーコード](ja/quantum_keycodes.md) -* [グレイブ エスケープ](ja/feature_grave_esc.md) -* [マウスキー](ja/feature_mouse_keys.md) - -?> キーマップがどのように機能するかを感じながら、各変更を小さくしてください。大きな変更は、発生する問題のデバッグを困難にします。 - -## ファームウェアをビルドする :id=build-your-firmware - -キーマップの変更が完了したら、ファームウェアをビルドする必要があります。これを行うには、ターミナルウィンドウに戻り、コンパイルコマンドを実行します: - - qmk compile - -もし環境が設定されていない場合や、複数のキーボードを所持している場合は、キーボードやキーマップを指定することができます: - - qmk compile -kb -km - -これがコンパイルされる間、どのファイルがコンパイルされているかを知らせる多くの出力が画面に表示されます。 -次のような出力で終わるはずです: - -``` -Linking: .build/planck_rev5_default.elf [OK] -Creating load file for flashing: .build/planck_rev5_default.hex [OK] -Copying planck_rev5_default.hex to qmk_firmware folder [OK] -Checking file size of planck_rev5_default.hex [OK] - * The firmware size is fine - 27312/28672 (95%, 1360 bytes free) -``` - -## ファームウェアを書きこむ - -[「ファームウェアを書きこむ」](ja/newbs_flashing.md) に移動して、キーボードに新しいファームウェアを書き込む方法を学習します。 diff --git a/docs/ja/newbs_building_firmware_configurator.md b/docs/ja/newbs_building_firmware_configurator.md deleted file mode 100644 index 6b48e79de864..000000000000 --- a/docs/ja/newbs_building_firmware_configurator.md +++ /dev/null @@ -1,20 +0,0 @@ -# QMK Configurator - - - -[![QMK Configurator Screenshot](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/) - -[QMK Configurator](https://config.qmk.fm) は、QMKファームウェアの `.hex` や `.bin` ファイルを生成するオンライングラフィカルユーザーインターフェイスです。 - -[ビデオチュートリアル](https://www.youtube.com/watch?v=-imgglzDMdY) を見てください。 -多くの人は、それが自分のキーボードのプログラミングを始めるのに十分な情報であることに気づくでしょう。 - -QMK Configurator は Chrome/Firefox で最適に動作します。 - -!> **注意: Keyboard Layout Editor (KLE) や kbfirmware などの他のツールのファイルは、QMK Configurator と互換性がありません。それらをロードしたり、インポートしたりしないでください。QMK Configurator は異なるツールです。** - -[QMK Configurator: ステップ・バイ・ステップ](ja/configurator_step_by_step.md)を参照してください。 diff --git a/docs/ja/newbs_flashing.md b/docs/ja/newbs_flashing.md deleted file mode 100644 index 39f5da88a85d..000000000000 --- a/docs/ja/newbs_flashing.md +++ /dev/null @@ -1,133 +0,0 @@ -# ファームウェアを書き込む - - - -カスタムファームウェアは出来たので、いよいよキーボードへの書き込み(フラッシュ)です。 - -## キーボードを DFU (Bootloader) モードにする - -カスタムファームウェアを書き込むには、最初にキーボードを普段とは違う特別な状態、フラッシュモードにする必要があります。 -このモードでは、キーボードはキーボードとしての機能を果たしません。 -ファームウェアの書き込み中にキーボードのケーブルを抜いたり、書き込みプロセスを中断したりしないことが非常に重要です。 - -キーボードによって、この特別なモードに入る方法は異なります。 -PCB が現在 QMK、TMK、PS2AVRGB (Bootmapper Client) を実行しており、キーボードメーカーから具体的な指示が与えられていない場合は、次を順番に試してください。 - -* 両方のシフトキーを押しながら、`Pause` キーを押す -* 両方のシフトキーを押しながら、`B` キーを押す -* キーボードのケーブルを抜いて、スペースバーと `B` を同時に押しながら、キーボードを再び接続し、1秒待ってからキーを放す -* キーボードのケーブルを抜いて、左上か左下のキー(通常は Escape か左 Control)を押しながらキーボードを接続する -* 通常、PCB の裏側に付けられている物理的な `RESET` ボタンを押す -* PCB 上の `RESET` か `GND` のラベルの付いたヘッダピンを探し、PCB 接続中にそれらを互いにショートする - -上記を全て試してもうまくいかず、基板のメインチップに `STM32` と表示されている場合、これは少し複雑になる可能性があります。通常、最善の方法は [Discord](https://discord.gg/Uq7gcHh) で助けを求めることです。おそらく基板の写真をいくつか求められるでしょう。あらかじめそれらを準備することができれば物事を進めるのに役立ちます! - -それ以外の場合は、QMK Toolbox で次のような黄色のメッセージが表示されます: - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -``` - -そして、このブートローダデバイスはデバイスマネージャーやシステム情報.app、`lsusb` にも表示されます。 - -## QMK Toolbox を使ってキーボードに書き込む - -キーボードに書き込む最も簡単な方法は [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases) を使うことです。 - -ただし、QMK Toolbox は、現在は Windows と macOS でしか使えません。 -Linux を使用している場合(および、コマンドラインでファームウェアを書き込みたい場合)は、[コマンドラインからキーボードを書き込む](#flash-your-keyboard-from-the-command-line)節まで進んでください。 - -### QMK Toolbox にファイルをロードする - -まず QMK Toolbox アプリケーションを起動します。 -Finder またはエクスプローラーでファームウェアのファイルを探します。 -キーボードのファームウェアは `.hex` または `.bin` のどちらかの形式です。 -ビルド時に QMK は、キーボードに適した形式のものを `qmk_firmware` のトップフォルダにコピーしているはずです。 - -Windows か macOS を使用している場合、現在のフォルダをエクスプローラーか Finder で簡単に開くためのコマンドがあります。 - - - -#### ** Windows ** - -``` -start . -``` - -#### ** macOS ** - -``` -open . -``` - - - -ファームウェアファイルは常に以下の命名形式に従っています: - -``` -_.{bin,hex} -``` - -例えば、`plank/rev5` の `default` キーマップのファイル名は以下のようになります: - -``` -planck_rev5_default.hex -``` - -ファームウェアファイルを見つけたら、QMK Toolbox の "Local file" ボックスにドラッグするか、"Open" をクリックしてファームウェアファイルが格納されている場所を指定します。 - -### キーボードへの書き込み - -QMK Toolbox の `Flash` ボタンをクリックします。次のような出力が表示されます。 - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -*** Attempting to flash, please don't remove device ->>> dfu-programmer.exe atmega32u4 erase --force - Erasing flash... Success - Checking memory from 0x0 to 0x6FFF... Empty. ->>> dfu-programmer.exe atmega32u4 flash "D:\Git\qmk_firmware\gh60_satan_default.hex" - Checking memory from 0x0 to 0x3F7F... Empty. - 0% 100% Programming 0x3F80 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - 0% 100% Reading 0x7000 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - Validating... Success - 0x3F80 bytes written into 0x7000 bytes memory (56.70%). ->>> dfu-programmer.exe atmega32u4 reset - -*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000) -``` - -## コマンドラインでファームウェアを書き込む :id=flash-your-keyboard-from-the-command-line - -これは、以前のものと比較して非常に単純になりました。 -ファームウェアをコンパイルして書き込む準備ができたら、ターミナルウィンドウを開いて書き込みコマンドを実行します: - - qmk flash - -もし CLI でキーボードやキーマップ名を設定していない場合や、複数のキーボードを持っている場合、キーボードとキーマップを指定することができます: - - qmk flash -kb -km - -これはキーボードの設定を確認し、指定されたブートローダに基づいて書き込もうとします。これはどのブートローダをキーボードが使っているか知る必要がないことを意味します。単にコマンドを実行し、コマンドに重い仕事をさせましょう。 - -ただし、これはキーボードごとに設定されているブートローダに依存します。 -もし、この情報が設定されていない場合、または、使用しているキーボードが、ファームウェア書き込みでサポートされているターゲットを持っていない場合、次のエラーが表示されます: - - WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. - -この場合、あなたは明示的にブートローダを指定する方法を使わなければなりません。詳細は、[ファームウェアのフラッシュ](ja/flashing.md)ガイドを参照してください。 - -## テストしましょう! - -おめでとうございます!カスタムファームウェアがキーボードにプログラムされ、テストする準備ができました! - -少し運が良ければ全てが完璧に機能しますが、そうでない場合は何が問題なのかを理解するのに役立つ手順があります。 -通常、キーボードのテストは非常に簡単です。全てのキーをひとつずつ押して、期待するキーが送信されることを確認します。例え QMK で動作していない場合でも、[QMK Configurator](https://config.qmk.fm/#/test/) のテストモードを使用すると、キーボードをチェックできます。 - -まだ動作しませんか?詳細については FAQ トピックを参照するか、[Discord でチャット](https://discord.gg/Uq7gcHh)してください。 diff --git a/docs/ja/newbs_getting_started.md b/docs/ja/newbs_getting_started.md deleted file mode 100644 index ece64e8d8b22..000000000000 --- a/docs/ja/newbs_getting_started.md +++ /dev/null @@ -1,210 +0,0 @@ -# QMK 環境の構築 - - - -キーマップをビルドする前に、いくつかのソフトウェアをインストールしてビルド環境を構築する必要があります。 -ファームウェアをコンパイルするキーボードの数に関わらず、この作業を一度だけ実行する必要があります。 - -## 1. 前提条件 - -始めるために必要なソフトウェアがいくつかあります。 - -* [テキストエディタ](ja/newbs_learn_more_resources.md#text-editor-resources) - * プレーンテキストファイルを編集して保存できるプログラムが必要です。多くの OS に付属するデフォルトのエディタはプレーンテキストファイルを保存しないため、選択したエディタがプレーンテキストファイルを保存することを確認する必要があります。 -* [Toolbox (オプション)](https://github.com/qmk/qmk_toolbox) - * Windows と macOS で使える GUI を備えたプログラムで、カスタムキーボードのプログラミングとデバッグの両方ができます。 - -?> もし、Linux か Unix のコマンドを使ったことがない場合、こちらで基本的な概念や各種コマンドを学んでください。[これらの教材](ja/newbs_learn_more_resources.md#command-line-resources)で QMK を使うのに必要なことを学ぶことができます。 - -## 2. ビルド環境を準備する :id=set-up-your-environment - -私たちは、QMK を可能な限り簡単に構築できるように努力しています。Linux か Unix 環境を用意するだけで、QMK に残りをインストールさせることができます。 - - - -### ** Windows ** - -QMK は、MSYS2、CLI、および必要な全ての依存関係のバンドルを保守しています。また、正しい環境で直接起動するための便利な `QMK MSYS` ターミナルショートカットも提供しています。 - -#### 前提条件 - -[QMK MSYS](https://msys.qmk.fm/) をインストールする必要があります。最新リリースは[ここ](https://github.com/qmk/qmk_distro_msys/releases/latest)から入手できます。 - -または、MSYS2 を手動でインストールしたい場合、次のセクションでプロセスを説明します。 - -
- 手動インストール - -?> `QMK MSYS` を使う場合、次のステップは無視してください。 - -#### 前提条件 - -MSYS2 と Git と Python をインストールする必要があります。https://www.msys2.org のインストール手順に従ってください。 - -MSYS2 をインストールしたら、開いている MSYS の全ターミナル画面を閉じて、新しい MinGW 64-bit ターミナル画面を開きます。 - -!> **注意:** MinGW 64-bit ターミナルは、インストールが完了した時に開く MSYS ターミナルと*同じではありません*。プロンプトには、「MSYS」ではなく、紫色のテキストで「MINGW64」と表示されます。違いについての詳細は[このページ](https://www.msys2.org/wiki/MSYS2-introduction/#subsystems)を参照してください。 - -それから、次のように実行します: - - pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip - -#### インストール - -次のコマンドを実行して、QMK CLI をインストールします: - - python3 -m pip install qmk - -
- -### ** macOS ** - -QMK は CLI と全ての必要な依存関係を自動的にインストールする Homebrew tap と formula を保守しています。 - -#### 前提条件 - -Homebrew のインストールが必要です。https://brew.sh の手順に従ってください。 - -#### インストール - -次のコマンドを実行して、QMK CLI をインストールします: - - brew install qmk/qmk/qmk - -### ** Linux/WSL ** - -?> **WSL ユーザーへの注意**: デフォルトでは、インストールプロセスは QMK リポジトリを WSL ホームディレクトリに clone しますが、手動で clone した場合、Windows ファイルシステムではなく、WSL インスタンス内にある(つまり `/mnt` 内にない)ことを確認してください。これは、現在アクセスが[非常に遅い](https://github.com/microsoft/WSL/issues/4197)ためです。 - -#### 前提条件 - -Git と Python をインストールする必要があります。両方とも既にインストールされている可能性は高いですが、そうでない場合、次のコマンドのいずれかでそれらをインストールできます: - -* Debian / Ubuntu / Devuan: `sudo apt install -y git python3-pip` -* Fedora / Red Hat / CentOS: `sudo yum -y install git python3-pip` -* Arch / Manjaro: `sudo pacman --needed --noconfirm -S git python-pip libffi` -* Void: `sudo xbps-install -y git python3-pip` -* Solus: `sudo eopkg -y install git python3` -* Sabayon: `sudo equo install dev-vcs/git dev-python/pip` -* Gentoo: `sudo emerge dev-vcs/git dev-python/pip` - -#### インストール - -次のコマンドを実行して、QMK CLI をインストールします: - - python3 -m pip install --user qmk - -#### コミュニティパッケージ - -これらのパッケージはコミュニティメンバーによって保守されているため、最新ではないか、完全には機能しない可能性があります。問題が発生した場合は、それぞれのメンテナに報告してください。 - -Arch ベースのディストリビューションでは、公式リポジトリから CLI をインストールできます(注意: 執筆時点では、このパッケージは一部の依存関係をオプションとしてマークしていますが、そうではありません): - - sudo pacman -S qmk - -AUR から `qmk-git` パッケージを試すこともできます: - - yay -S qmk-git - -### ** FreeBSD ** - -#### インストール - -次のコマンドを実行して、QMK CLI の FreeBSD パッケージをインストールします: - - pkg install -g "py*-qmk" - -注意: インストールの最後に表示された指示に従うことを忘れないでください(再度表示するには、`pkg info -Dg "py*-qmk"` を使ってください)。 - - - -## 3. QMK の設定を行う :id=set-up-qmk - - - -### ** Windows ** - -QMK のインストール後に、このコマンドで設定できます: - - qmk setup - -ほとんどの場合、全てのプロンプトに `y` と答えます。 - -### ** macOS ** - -QMK のインストール後に、このコマンドで設定できます: - - qmk setup - -ほとんどの場合、全てのプロンプトに `y` と答えます。 - -### ** Linux/WSL ** - -QMK のインストール後に、このコマンドで設定できます: - - qmk setup - -ほとんどの場合、全てのプロンプトに `y` と答えます。 - -?>**Debian、Ubuntu、それらの派生に関する注意**: -次のようなエラーが表示される可能性があります: `bash: qmk: command not found`. -これは Debian の Bash 4.4 リリースで導入された[バグ](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155)で、`$HOME/.local/bin` が PATH から削除されました。このバグは後に Debian や Ubuntu で修正されました。 -残念なことに、Ubuntu はこのバグを再導入し、[まだ修正していません](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562)。 -幸い、修正は簡単です。これをあなたのユーザで実行します: `echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc` - -### ** FreeBSD ** - -QMK のインストール後に、このコマンドで設定できます: - - qmk setup - -ほとんどの場合、全てのプロンプトに `y` と答えます。 - - - -?> qmk ホームフォルダは、セットアップ時に `qmk setup -H ` を使って指定し、[cli 構成](ja/cli_configuration.md?id=single-key-example)と変数 `user.qmk_home` を使って変更できます。利用可能な全てのオプションについては、`qmk setup --help` を実行します。 - -?> 既に GitHub の使い方を知っている場合、[これらの手順に従うことをお勧めします](ja/getting_started_github.md)。そして `qmk setup /qmk_firmware` を使って個人用の fork から clone します。この一文の意味が分からない場合、このメッセージは無視してかまいません。 - -## 4. ビルド環境の確認 - -これで QMK のビルド環境が用意できたので、キーボードのファームウェアをビルドできます。キーボードのデフォルトキーマップをビルドすることから始めます。次の形式のコマンドでビルドできるはずです: - - qmk compile -kb -km default - -例えば、Clueboard 66% のファームウェアをビルドする場合、次のようにします: - - qmk compile -kb clueboard/66/rev3 -km default - -大量の出力の最後に次のように出力されると完了です: - -``` -Linking: .build/clueboard_66_rev3_default.elf [OK] -Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] -Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] -Checking file size of clueboard_66_rev3_default.hex [OK] - * The firmware size is fine - 26356/28672 (2316 bytes free) -``` - -## 5. ビルド環境の設定(オプション) - -ビルド環境を設定してデフォルトを設定することで、QMK での作業をあまり面倒くさくないようにすることができます。今からやりましょう! - -QMK を初めて使うほとんどの人は、キーボードを1つしか持っていません。`qmk config` コマンドでこのキーボードをデフォルトとして設定できます。例えば、デフォルトのキーボードを `clueboard/66/rev4` に設定するには: - - qmk config user.keyboard=clueboard/66/rev4 - -デフォルトキーマップ名を設定することもできます。ほとんどの人はここで GitHub ユーザ名を使いますが、そうすることをお勧めします。 - - qmk config user.keymap= - -この後、これらの引数をオフにして、次のようにキーボードをコンパイルできます: - - qmk compile - -# キーマップの作成 - -これであなた専用のキーマップを作成する準備ができました!次は[初めてのファームウェアの構築](ja/newbs_building_firmware.md)で専用のキーマップを作成します。 diff --git a/docs/ja/newbs_git_best_practices.md b/docs/ja/newbs_git_best_practices.md deleted file mode 100644 index 7ba16fce7516..000000000000 --- a/docs/ja/newbs_git_best_practices.md +++ /dev/null @@ -1,24 +0,0 @@ -# QMK における Git 運用作法 :id=best-git-practices-for-working-with-qmk - - - -## または、"如何にして私は心配することをやめて Git を愛することを学んだか。" - -このセクションは、QMK への貢献をスムーズに行なう最もよい方法を初心者に教えることを目的としています。 -QMK に貢献するプロセスを順を追って説明し、この作業を簡単にするいくつかの方法を詳しく説明します。 -その後、意図的に一部を壊してみせて、それらを修正する方法を説明します。 - -このセクションは以下のことを前提としています: - -1. あなたは GitHub アカウントがあり、アカウントに [qmk_firmware リポジトリをフォーク](ja/getting_started_github.md) している。 -2. あなたは、[環境構築](ja/newbs_getting_started.md#set-up-your-environment) と [QMK の設定](ja/newbs_getting_started.md#set-up-qmk) を両方とも完了している。 - ---- - -- パート 1: [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) -- パート 2: [マージの競合の解決](ja/newbs_git_resolving_merge_conflicts.md) -- パート 3: [同期のとれていない git ブランチの再同期](ja/newbs_git_resynchronize_a_branch.md) diff --git a/docs/ja/newbs_git_resolving_merge_conflicts.md b/docs/ja/newbs_git_resolving_merge_conflicts.md deleted file mode 100644 index 532b1e30019b..000000000000 --- a/docs/ja/newbs_git_resolving_merge_conflicts.md +++ /dev/null @@ -1,94 +0,0 @@ -# マージの競合の解決 - - - -ブランチでの作業の完了に時間がかかる場合、他の人が行った変更が、プルリクエストを開いたときにブランチに加えた変更と競合することがあります。 -これは *マージの競合* と呼ばれ、複数の人が同じファイルの同じ部分を編集すると発生します。 - -?> このドキュメントは [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) で詳述されている概念に基づいています。 -その概念に慣れていない場合は、まずそれを読んでから、ここに戻ってください。 - -## 変更のリベース - -*リベース* は、コミット履歴のある時点で適用された変更を取得し、それらを元に戻し、次に同じ変更を別のポイントに適用する Git の方法です。 -マージの競合が発生した場合、ブランチをリベースして、ブランチを作成してから現在までに行われた変更を取得できます。 - -開始するには、次を実行します: - -``` -git fetch upstream -git rev-list --left-right --count HEAD...upstream/master -``` - -ここに入力された `git rev-list` コマンドは、現在のブランチと QMK の master ブランチで異なるコミットの数を返します。 -最初に `git fetch` を実行して、upstream リポジトリの現在の状態を表す refs があることを確認します。 -入力された `git rev-list` コマンドの出力は2つの数値を返します: - -``` -$ git rev-list --left-right --count HEAD...upstream/master -7 35 -``` - -最初の数字は、現在のブランチが作成されてからのコミット数を表し、2番目の数字は、現在のブランチが作成されてから `upstream/master` に対して行われたコミットの数であり、したがって、現在のブランチに記録されていない変更です。 - -現在のブランチと upstream リポジトリの両方の現在の状態がわかったので、リベース操作を開始できます: - -``` -git rebase upstream/master -``` - -これにより、Git は現在のブランチのコミットを取り消してから、QMK の master ブランチに対してコミットを再適用します。 - -``` -$ git rebase upstream/master -First, rewinding head to replay your work on top of it... -Applying: Commit #1 -Using index info to reconstruct a base tree... -M conflicting_file_1.txt -Falling back to patching base and 3-way merge... -Auto-merging conflicting_file_1.txt -CONFLICT (content): Merge conflict in conflicting_file_1.txt -error: Failed to merge in the changes. -hint: Use 'git am --show-current-patch' to see the failed patch -Patch failed at 0001 Commit #1 - -Resolve all conflicts manually, mark them as resolved with -"git add/rm ", then run "git rebase --continue". -You can instead skip this commit: run "git rebase --skip". -To abort and get back to the state before "git rebase", run "git rebase --abort". -``` - -これにより、マージの競合があることがわかり、競合のあるファイルの名前が示されます。 -テキストエディタで競合するファイルを開くと、ファイルのどこかに次のような行があります: - -``` -<<<<<<< HEAD -

For help with any issues, email us at support@webhost.us.

-======= -

Need help? Email support@webhost.us.

->>>>>>> Commit #1 -``` - -行 `<<<<<<< HEAD` はマージ競合の始まりを示し、行 `>>>>>>> commit #1` は終了を示し、競合するセクションは `=======` で区切られます。 -`HEAD` 側の部分はファイルの QMK master バージョンからのものであり、コミットメッセージでマークされた部分は現在のブランチとコミットからのものです。 - -Git はファイルの内容ではなく *ファイルへの変更* を直接追跡するため、Git がコミットの前にファイル内にあったテキストを見つけられない場合、ファイルの編集方法がわかりません。 -ファイルを再編集して、競合を解決します。 -変更を加えてから、ファイルを保存します。 - -``` -

Need help? Email support@webhost.us.

-``` - -そしてコマンド実行: - -``` -git add conflicting_file_1.txt -git rebase --continue -``` - -Git は、競合するファイルへの変更をログに記録し、ブランチのコミットが最後に達するまで適用し続けます。 diff --git a/docs/ja/newbs_git_resynchronize_a_branch.md b/docs/ja/newbs_git_resynchronize_a_branch.md deleted file mode 100644 index 567ec38bfec4..000000000000 --- a/docs/ja/newbs_git_resynchronize_a_branch.md +++ /dev/null @@ -1,88 +0,0 @@ -# 同期のとれていない git ブランチの再同期 - - - -仮にあなたの `master` ブランチにあなたのコミットを行い、そしてあなたの QMK リポジトリの更新が必要になったとします。 -(フォーク元の) QMK の `master` ブランチをあなたの `master` ブランチに `git pull` することもできますが、GitHub は、あなたのブランチが `qmk:master` より何コミットか先行していると通知します、この状態で QMK にプルリクエストを行う場合、問題が発生する可能性があります。 -(訳注:この通知は、GitHub のあなたのリポジトリの code ペインのブランチ選択メニューの下のあたりで `This branch is 3 commit ahead of qmk:master` という様な文面で表示されています。) - -?> このドキュメントは [あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと](ja/newbs_git_using_your_master_branch.md) で詳述されている概念に基づいています。その概念に慣れていない場合は、まずそれを読んでから、ここに戻ってください。 -(訳注:この文書で言う、「同期のとれていない git ブランチ」とは、master ブランチに関する、この「コミットしない」方針を逸脱して、QMK の master リポジトリに存在しないコミットがあなたのフォークの master ブランチに入っている状態を指します。) - -## あなた自身の `master` ブランチでの変更のバックアップ(オプション) - -救えるものなら自分の行った変更を失いたくはないでしょう。 -あなたの `master` ブランチに既に加えた変更を保存したい場合、最も簡単な方法は、単に「ダーティな」`master` ブランチの複製を作成することです: - -```sh -git branch old_master master -``` - -これで、 `master` ブランチの複製である `old_master` という名前のブランチができました。 - -## あなたのブランチの再同期 - -さあ、`master` ブランチを再同期します。 -この手順では、QMK のリポジトリを git のリモートリポジトリとして設定する必要があります。 -設定済みのリモートリポジトリを確認するには、`git remote -v` を実行し、次のような結果が返されなければなりません。 - -```sh -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -もし、上記のようにならずに以下のように参照されるフォークが、1つだけ表示される場合: - -```sh -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com/qmk/qmk_firmware.git (fetch) -origin https://github.com/qmk/qmk_firmware.git (push) -``` - -新しいリモートリポジトリを追加します: - -```sh -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -次に、`origin` リモートリポジトリを、あなた自身のフォークにリダイレクトします: - -```sh -git remote set-url origin https://github.com/<あなたのユーザ名>/qmk_firmware.git -``` - -両方のリモートリポジトリが設定されたので、次を実行して、QMK である `upstream` リポジトリの参照を更新する必要があります。 - -```sh -git fetch upstream -``` - -この時点で、次を実行してあなたの(訳注:master)ブランチを QMK のブランチに再同期します。 -(訳注: 今現在 `master` ブランチがチェックアウトされていなければなりません。 - そうなってなければ、`git checkout master` を先に実行しておく必要があります。) - -```sh -git reset --hard upstream/master -``` - -これらの手順により、あなたのコンピュータ上のリポジトリが更新されますが、あなたの GitHub 上のフォークはまだ同期されていません。 -GitHub 上のフォークを再同期するには、あなたのフォークにプッシュして、ローカルリポジトリに反映されていないリモート変更をオーバーライドするように Git に指示する必要があります。 -これを行うには、次を実行します: - -```sh -git push --force-with-lease -``` - -!> 他のユーザーがコミットを投稿するフォークで `git push --force-with-lease` を**実行しないでください**。これをすると、かれらのコミットが消去されてしまいます。 - -これで、あなたの GitHub フォーク、あなたのローカルファイル、および QMK のリポジトリはすべて同じになりました。 -ここから、[ブランチを使って](ja/newbs_git_using_your_master_branch.md#making-changes)さらに必要な変更を加え、通常どおりそれらを投稿できます。 diff --git a/docs/ja/newbs_git_using_your_master_branch.md b/docs/ja/newbs_git_using_your_master_branch.md deleted file mode 100644 index 308a61eded10..000000000000 --- a/docs/ja/newbs_git_using_your_master_branch.md +++ /dev/null @@ -1,101 +0,0 @@ -# あなたのフォークの master ブランチ: 更新は頻繁に、コミットはしないこと - - - -QMK の開発では、何がどこで行われているかにかかわらず、`master` ブランチを最新の状態に保つことを強くお勧めします、しかし `master` ブランチには***絶対に直接コミットしないでください***。 -代わりに、あなたのすべての変更は開発ブランチで行い、あなたが開発する時にはそのブランチからプルリクエストを発行します。 - -マージの競合 — これは 2人以上のユーザーがファイルの同じ部分をそれぞれ異なる編集をして統合できなくなった状態 — の可能性を減らすため `master` ブランチをなるべく最新の状態に保ち、新しいブランチを作成して新しい開発を開始します。 - -## あなたの master ブランチを更新する - -`master` ブランチを最新の状態に保つには、git のリモートリポジトリとして QMK ファームウェアのリポジトリ(以降、QMK リポジトリ)を追加することをお勧めします。 -これを行うには、Git コマンドラインインターフェイスを開き、次のように入力します。 - -``` -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -?> `upstream`(訳注: `upstream` は`上流`という意味です)という名前は任意ですが、一般的な慣習です。 -QMK のリモートリポジトリには、あなたにとって分かりやすい名前を付けることができます。 -Git の `remote` コマンドは、構文 `git remote add ` を使用します。 -`` はリモートリポジトリの省略形としてあなたが指定するものです。 -この名前は、`fetch`、`pull`、`push` やそれ以外の多くの Git コマンドで、対象のリモートリポジトリを指定するために使用されます。 - -リポジトリが追加されたことを確認するには、`git remote -v` を実行します。 -次のように表示されます。 - -``` -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -これが完了すると、`git fetch upstream` を実行してリポジトリの更新を確認できます。 -このコマンドは `upstream` というニックネームを持つ QMK リポジトリから、ブランチとタグ — "refs" と総称されます — を取得します。 -これで、あなたのフォーク `origin` のデータを QMK が保持するデータと比較できます。 - -あなたのフォークの `master` を更新するには、次を実行します、各行の後に Enter キーを押してください: - -``` -git checkout master -git fetch upstream -git pull upstream master -git push origin master -``` - -これにより、あなたの `master` ブランチに切り替わり、QMK リポジトリから 'refs' を取得し、現在の QMK の `master` ブランチをコンピュータにダウンロードしてから、あなたのフォークにアップロードします。 - -## 変更を行なう :id=making-changes - -変更するには、以下を入力して新しいブランチを作成します: - -``` -git checkout -b dev_branch -git push --set-upstream origin dev_branch -``` - -これにより、`dev_branch` という名前の新しいブランチが作成され、チェックアウトされ、新しいブランチがあなたのフォークに保存されます。 -`--set-upstream` 引数は、このブランチから `git push` または `git pull` を使用するたびに、あなたのフォークと `dev_branch` ブランチを使用するように git に指示します。 -この引数は最初のプッシュでのみ使用する必要があります。 -その後、残りの引数なしで `git push` または `git pull` を安全に使用できます。 - -?> `git push` では、`-set-upstream` の代わりに `-u` を使用できます、 `-u` は `--set-upstream` のエイリアスです。 - -ブランチにはほぼ任意の名前を付けることができますが、あなたが行なう変更を表す名前を付けることをお勧めします。 - -デフォルトでは、`git checkout -b`は、今チェックアウトされているブランチに基づいて新しいブランチを作成します。 -コマンド末尾に既存のブランチの名前を追加指定することにより、チェックアウトされていない既存のブランチを基にして新しいブランチを作成できます: - -``` -git checkout -b dev_branch master -``` - -これで開発ブランチができたのでテキストエディタを開き必要な変更を加えます。 -ブランチに対して多くの小さなコミットを行うことをお勧めします。 -そうすることで、問題を引き起こす変更をより簡単に特定し必要に応じて元に戻すことができます。 -変更を加えるには、更新が必要なファイルを編集して保存し、Git の *ステージングエリア* に追加してから、ブランチにコミットします: - -``` -git add path/to/updated_file -git commit -m "My commit message." -``` - -`git add`は、変更されたファイルを Git の *ステージングエリア* に追加します。 -これは、Git の「ロードゾーン」です。 -これには、`git commit` によって *コミット* される変更が含まれており、リポジトリへの変更が保存されます。 -変更内容が一目でわかるように、説明的なコミットメッセージを使用します。 - -?> 複数のファイルを変更した場合、`git add -- path/to/file1 path/to/file2 ...` を実行すれば、あなたの望むファイルを追加できます。 - -## 変更を公開する - -最後のステップは、変更をフォークにプッシュすることです。 -これを行うには、`git push`と入力します。 -Git は、 `dev_branch`の現在の状態をフォークに公開します。 diff --git a/docs/ja/newbs_learn_more_resources.md b/docs/ja/newbs_learn_more_resources.md deleted file mode 100644 index 686b92446518..000000000000 --- a/docs/ja/newbs_learn_more_resources.md +++ /dev/null @@ -1,63 +0,0 @@ -# 学習リソース - - - -これらのリソースは、QMK コミュニティの新しいメンバーに、初心者向けドキュメントで提供されている情報に対する理解を深めることを目的としています。 - -## QMK に関するリソース - -### 英語 :id=english-resources-qmk - -* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 新規ユーザーの視点から見た QMK ファームウェアの使い方の基本を網羅した、ユーザー作成のブログ。 - -### 日本語 :id=japanese-resources-qmk - -_日本語のリソース情報を募集中です。_ - -## コマンドラインに関するリソース :id=command-line-resources - -### 英語 :id=english-resources-cli - -* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line) -* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
-* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) - -### 日本語 :id=japanese-resources-cli - -_日本語のリソース情報を募集中です。_ - -## テキストエディタに関するリソース :id=text-editor-resources - -どのテキストエディタを使えば良いか分かりませんか? - -### 英語 :id=english-resources-text-editor - -* [a great introduction to the subject](https://learntocodewith.me/programming/basics/text-editors/) - -### 日本語 :id=japanese-resources-text-editor - -_日本語のリソース情報を募集中です。_ - -コーディング用に特別に作成されたエディタ: -* [Sublime Text](https://www.sublimetext.com/) -* [VS Code](https://code.visualstudio.com/) - -## Git に関するリソース - -### 英語 :id=english-resources-git - -* [Great General Tutorial](https://www.codecademy.com/learn/learn-git) -* [Flight Rules For Git](https://github.com/k88hudson/git-flight-rules) -* [Git Game To Learn From Examples](https://learngitbranching.js.org/) - -### 日本語 :id=japanese-resources-git - -_日本語のリソース情報を募集中です。_ - -* [Git Game To Learn From Examples(日本語対応有り)](https://learngitbranching.js.org/) - git のブランチの作り方、マージの仕方などがビジュアルに学べます。 -* [QMK で GitHub を使う方法](ja/getting_started_github.md) diff --git a/docs/ja/newbs_testing_debugging.md b/docs/ja/newbs_testing_debugging.md deleted file mode 100644 index d64f0f6dff84..000000000000 --- a/docs/ja/newbs_testing_debugging.md +++ /dev/null @@ -1,15 +0,0 @@ -# テストとデバッグ - - - -## テスト - -[ここに移動しました](ja/faq_misc.md#testing) - -## デバッグ :id=debugging - -[ここに移動しました](ja/faq_debug.md#debugging) diff --git a/docs/ja/one_shot_keys.md b/docs/ja/one_shot_keys.md deleted file mode 100644 index f049c2d6f70d..000000000000 --- a/docs/ja/one_shot_keys.md +++ /dev/null @@ -1,110 +0,0 @@ -# ワンショットキー - - - -ワンショットキーは次のキーが押されるまでアクティブのままになり、そのあと放されるキーです。これにより一度に1つ以上のキーを押すことなく、キーボードの組み合わせを入力することができます。これらのキーは通常「スティッキーキー」あるいは「デッドキー」と呼ばれます。 - -例えば、キーを `OSM(MOD_LSFT)` と定義する場合、最初にシフトを押して放し、続いて A を押して放すことで、大文字の A キャラクタを入力することができます。コンピュータには、シフトが押された瞬間にシフトが押し続けられ、A が放された後ですぐにシフトキーが放されるように見えます。 - -ワンショットキーは通常のモディファイアのようにも動作します。ワンショットキーを押しながら他のキーを入力すると、キーを放した直後にワンショットキーが解除されます。 - -さらに、短時間でキーを5回押すと、そのキーをロックします。これはワンショットモディファイアとワンショットレイヤーに適用され、`ONESHOT_TAP_TOGGLE` 定義によって制御されます。 - -`config.h` でこれらを定義することでワンショットキーの挙動を制御することができます: - -```c -#define ONESHOT_TAP_TOGGLE 5 /* この回数をタップすると、もう一度タップするまでキーが押されたままになります。*/ -#define ONESHOT_TIMEOUT 5000 /* ワンショットキーが解除されるまでの時間 (ms) */ -``` - -* `OSM(mod)` - *mod*を一時的に押し続けます。[モッドタップ](ja/mod_tap.md)で示したように、`KC_*` コードでは無く、`MOD_*` キーコードを使わなければなりません。 -* `OSL(layer)` - 一時的に*レイヤー*に切り替えます。 -* `OS_ON` - ワンショットキーをオンにします。 -* `OS_OFF` - ワンショットキーをオフにします。OSM は通常の mod キーのように機能し、OSL は `MO` キーのように機能します。 -* `OS_TOGG` - ワンショットキーの状態を切り替えます。 - -ワンショットキーをマクロあるいはタップダンスルーチンの一部として有効にしたい場合があります。 - -ワンショットレイヤーについては、キーを押した時に `set_oneshot_layer(LAYER, ONESHOT_START)` を呼び出し、キーを放した時に `clear_oneshot_layer_state(ONESHOT_PRESSED)` を呼び出す必要があります。ワンショットをキャンセルする場合は、`reset_oneshot_layer()` を呼び出してください。 - -ワンショットモッドについては、設定するためには `set_oneshot_mods(MOD_BIT(KC_*))` を呼び出し、キャンセルするためには `clear_oneshot_mods()` を呼び出す必要があります。 - -!> リモートデスクトップ接続で OSM 変換に問題がある場合は、設定を開いて「ローカル リソース」タブに移動し、キーボードセクションでドロップダウンを「このコンピューター」に変更することで修正することができます。これにより問題が修正され、OSM がリモートデスクトップ上で適切に動作するようになります。 - -## コールバック - -ワンショットキーを押す時にカスタムロジックを実行したい場合、実装を選択できる幾つかのコールバックがあります。例えば、LED を点滅させたり、音を鳴らしたりして、ワンショットキーの変化を示すことができます。 - -`OSM(mod)` のためのコールバックがあります。ワンショット修飾キーの状態が変更されるたびに呼び出されます: オンに切り替わる時だけでなく、オフに切り替わる時にも呼び出されます。以下のように使うことができます: - -```c -void oneshot_mods_changed_user(uint8_t mods) { - if (mods & MOD_MASK_SHIFT) { - println("Oneshot mods SHIFT"); - } - if (mods & MOD_MASK_CTRL) { - println("Oneshot mods CTRL"); - } - if (mods & MOD_MASK_ALT) { - println("Oneshot mods ALT"); - } - if (mods & MOD_MASK_GUI) { - println("Oneshot mods GUI"); - } - if (!mods) { - println("Oneshot mods off"); - } -} -``` - -`mods` 引数は変更後のアクティブな mod が含まれるため、現在の状態が反映されます。 - -(`config.h` に `#define ONESHOT_TAP_TOGGLE 2` を追加して) ワンショットタップトグルを使う場合、指定された回数だけ修飾キーを押してロックすることができます。そのためのコールバックもあります: - -```c -void oneshot_locked_mods_changed_user(uint8_t mods) { - if (mods & MOD_MASK_SHIFT) { - println("Oneshot locked mods SHIFT"); - } - if (mods & MOD_MASK_CTRL) { - println("Oneshot locked mods CTRL"); - } - if (mods & MOD_MASK_ALT) { - println("Oneshot locked mods ALT"); - } - if (mods & MOD_MASK_GUI) { - println("Oneshot locked mods GUI"); - } - if (!mods) { - println("Oneshot locked mods off"); - } -} -``` - -最後に、`OSL(layer)` ワンショットキーのためのコールバックもあります: - -```c -void oneshot_layer_changed_user(uint8_t layer) { - if (layer == 1) { - println("Oneshot layer 1 on"); - } - if (!layer) { - println("Oneshot layer off"); - } -} -``` - -いずれかのワンショットレイヤーがオフの場合、`layer` は 0 になります。ワンショットレイヤーの変更では無く、レイヤーの変更で何かを実行したい場合は、`layer_state_set_user` は使用するのに良いコールバックです。 - -独自のキーボードを作成している場合、`_kb` と同等の機能もあります: - -```c -void oneshot_locked_mods_changed_kb(uint8_t mods); -void oneshot_mods_changed_kb(uint8_t mods); -void oneshot_layer_changed_kb(uint8_t layer); -``` - -他のコールバックと同様に、更にカスタマイズを可能にするために `_user` バージョンを呼ぶようにしてください。 diff --git a/docs/ja/other_eclipse.md b/docs/ja/other_eclipse.md deleted file mode 100644 index 929016619865..000000000000 --- a/docs/ja/other_eclipse.md +++ /dev/null @@ -1,89 +0,0 @@ -# QMK 開発のための Eclipse セットアップ - - - -[Eclipse][1]は Java 開発のために広く使われているオープンソースの [統合開発環境](https://en.wikipedia.org/wiki/Integrated_development_environment) (IDE) ですが、他の言語および用途のためにカスタマイズできる拡張可能なプラグインシステムがあります。 - -Eclipse のような IDE の使用は、プレーンテキストエディタの使用よりも多くの利点をもたらします。例えば、次のような利点です。 -* インテリジェントなコード補完 -* コード内の便利なナビゲーション -* リファクタリングツール -* 自動ビルド (コマンドラインは不要) -* Git 用の GUI -* 静的なコード解析 -* デバッグ、コードフォーマット、呼び出し階層の表示などの多くのツール。 - -このページの目的は、AVR ソフトウェアの開発および QMK コードベースで作業するために、Eclipse をセットアップする方法を文章化することです。 - -このセットアップは現時点では Ubuntu 16.04 でのみテストされていることに注意してください。 - -# 前提条件 -## ビルド環境 -始める前に、チュートリアルの[セットアップ](ja/newbs_getting_started.md)のセクションに従う必要があります。特に、[`qmk compile` コマンド](ja/newbs_building_firmware.md#build-your-firmware)でファームウェアをビルドできなければなりません。 - -## Java -Eclipse は Java アプリケーションであるため、実行するには Java 8 以降をインストールする必要があります。JRE または JDK を選択できますが、Java 開発を行う場合は後者が役に立ちます。 - -# Eclipse とプラグインのインストール -Eclipse は用途に応じて[いくつかのフレーバー](https://www.eclipse.org/downloads/eclipse-packages/)で提供されます。AVR スタックを構成するパッケージは無いため、Eclipse CDT (C/C++ 開発ツール)から始め、必要なプラグインをインストールする必要があります。 - -## Eclipse CDT のダウンロードとインストール -システムに既に Eclipse CDT がある場合は、この手順をスキップできます。ただし、より良いサポートのために最新の状態に保つことをお勧めします。 - -別の Eclipse パッケージをインストールしている場合は、通常は[その上に CDT プラグインをインストール](https://eclipse.org/cdt/downloads.php)することができます。しかし、軽くして、作業中のプロジェクトに必要のないツールが乱雑にならないように、ゼロから再インストールすることをお勧めします。 - -インストールは非常に簡単です: [5 Steps to install Eclipse](https://eclipse.org/downloads/eclipse-packages/?show_instructions=TRUE) に従い、ステップ3で **Eclipse IDE for C/C++ Developers** を選択します。 - -あるいは、直接 [Eclipse IDE for C/C++ Developers をダウンロード](https://www.eclipse.org/downloads/eclipse-packages/)([現在のバージョンへの直接リンク](https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr))し、選択した場所にパッケージを解凍することもできます (これにより `eclipse` フォルダが作成されます)。 - -## 最初の起動 -インストールが完了したら、Launch ボタンをクリックします。(パッケージを手動で解凍した場合は、Eclipse をインストールしたフォルダを開き、`eclipse` 実行可能ファイルをダブルクリックします) - -Workspace 選択で入力を促された場合は、Eclipse メタデータと通常のプロジェクトを保持するディレクトリを選択します。**`qmk_firmware` ディレクトリを選択しないでください**。これはプロジェクトディレクトリになります。代わりに親フォルダを選択するか、(できれば空の)他のフォルダを選択します(まだ使用していない場合は、デフォルトで問題ありません)。 - -開始したら、右上の Workbench ボタンをクリックし、workbench ビューに切り替えます (下部に開始時のようこそ画面をスキップするためのチェックボックスもあります)。 - -## 必要なプラグインをインストール -注意: プラグインをインストールするごとに、Eclipse を再起動する必要はありません。全てのプラグインがインストールされたら単に1回再起動します。 - -### [The AVR Plugin](https://avr-eclipse.sourceforge.net/) -これは最も重要なプラグインで、Eclipse が AVR C コードを_理解_できるようになります。[更新サイトを使うための指示](https://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download#Update_Site)に従い、未署名コンテンツのセキュリティ警告に同意します。 - -### [ANSI Escape in Console](https://marketplace.eclipse.org/content/ansi-escape-console) -このプラグインは QMK makefile によって生成された色付きビルド出力を適切に表示するために必要です。 - -1. Help > Eclipse Marketplace… を開きます -2. _ANSI Escape in Console_ を検索します -3. プラグインの Install ボタンをクリックします -4. 指示に従い、未署名コンテンツのセキュリティ警告に再度同意します。 - -両方のプラグインがインストールされたら、プロンプトに従って Eclipse を再起動します。 - -# QMK 用の Eclipse の設定 -## プロジェクトのインポート -1. File > New > Makefile Project with Existing Code をクリックします -2. 次の画面で: -* _Existing Code Location_ としてリポジトリをクローンしたディレクトリを選択します。 -* (オプション) プロジェクトに別の名前を付けます¹ 例えば _QMK_ あるいは _Quantum_; -* _AVR-GCC Toolchain_ を選択します; -* 残りをそのままにして、Finish をクリックします - -![Eclipse での QMK のインポート](https://i.imgur.com/oHYR1yW.png) - -3. これでプロジェクトがロードされインデックスされます。左側の _Project Explorer_ から、簡単にファイルを参照できます。 - -¹ カスタム名でプロジェクトをインポートすると問題が発生するかもしれません。正しく動作しない場合は、デフォルトのプロジェクト名 (つまり、ディレクトリの名前、おそらく `qmk_firmware`) のままにしてみてください。 - -## キーボードのビルド - -プロジェクトのデフォルトの make 対象を `all` から私たちが取り組んでいる特定のキーボードとキーマップの組み合わせ、例えば `kinesis/kint36:stapelberg` に変更します。このようにすると、プロジェクトのクリーニングやビルドのようなプロジェクト全体のアクションは迅速に完了し、長い時間がかかったり Eclipse が完全にロックしたりすることがなくなります。 - -1. プロジェクト内の editor タブへフォーカスします -2. `Project` > `Properties` ウィンドウを開き、`C/C++ Build` リストエントリを選択して、`Behavior` タブに切り替えます。 -3. 有効な全てのビルドのデフォルトの `Make build target` テキストフィールドを、`all` から例えば `kinesis/kint41:stapelberg` に変更します。 -4. `Project` > `Clean...` を選択して、セットアップが動作することを確認します。 - -[1]: https://en.wikipedia.org/wiki/Eclipse_(software) diff --git a/docs/ja/other_vscode.md b/docs/ja/other_vscode.md deleted file mode 100644 index 2b6e27bb0af5..000000000000 --- a/docs/ja/other_vscode.md +++ /dev/null @@ -1,119 +0,0 @@ -# QMK 開発用の Visual Studio Code のセットアップ - - - -[Visual Studio Code](https://code.visualstudio.com/) (VS Code) は多くの異なるプログラミング言語をサポートするオープンソースのコードエディタです。 - -VS Code のようなフル機能のエディタの使用は、プレーンテキストエディタの使用よりも多くの利点をもたらします。例えば、次のような利点です。: -* インテリジェントなコード補完 -* コード内の便利なナビゲーション -* リファクタリングツール -* 自動ビルド (コマンドラインは不要) -* Git 用のグラフィカルなフロントエンド -* デバッグ、コードフォーマット、呼び出し階層の表示などの多くのツール - -このページの目的は、QMK ファームウェアを開発するために VS Code をセットアップする方法を文章化することです。 - -このガイドは Windows および Ubuntu 18.04 で必要な全てを構成する方法を説明します。 - -# VS Code のセットアップ -はじめに、全てのビルドツールをセットアップし、QMK ファームウェアをクローンする必要があります。まだ設定していない場合は、[セットアップ](ja/newbs_getting_started.md)に進んでください。 - -## Windows - -### 前提条件 - -* [Git for Windows](https://git-scm.com/download/win) (このリンクはインストーラを保存あるいは実行するように促します) - - 1. `Git LFS (Large File Support)` および `Check daily for Git for Windows updates` 以外の全てのオプションを無効にします。 - 2. デフォルトのエディタを `Use Visual Studio Code as Git's default editor` に設定します。 - 3. ここで使用すべきオプションなので、`Use Git from Git Bash only` オプションを選択します。 - 4. `Choosing HTTPS transport backend` については、どちらのオプションでも問題ありません。 - 5. `Checkout as-is, commit Unix-style line endings` オプションを選択します。QMK ファームウェアは Unix スタイルのコミットを使います。 - 6. 追加のオプションについては、デフォルトのオプションをそのままにします。 - - このソフトウェアは、VS Code での Git サポートに必要です。これを含めないことも可能ですが、これを使う方が簡単です。 - -* [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases) (オプション) - - このソフトウェアは、git 証明書、MFA、パーソナルアクセストークン生成のためのセキュアストレージを提供することで、Git のより良いサポートを提供します。 - - これは厳密には必要ありませんが、お勧めします。 - - -### VS Code のインストール - -1. [VS Code](https://code.visualstudio.com/) に進み、インストーラをダウンロードします -2. インストーラを実行します - -この項は非常に簡単です。ただし、正しく構成されていることを確認するために、しなければならない幾つかの設定があります。 - -### VS Code の設定 - -最初に、IntelliSense をセットアップする必要があります。これは厳密には必要ではありませんが、あなたの人生をずっと楽にします。これを行うには、QMK ファームウェアフォルダに `.vscode/c_cpp_properties.json` ファイルを作成する必要があります。これは全て手動で行うことができますが、ほとんどの作業は既に完了しています。 - -[このファイル](https://gist.github.com/drashna/48e2c49ce877be592a1650f91f8473e8) を取得して保存します。MSYS2 をデフォルトの場所にインストールしなかった、または WSL か LxSS を使っている場合、このファイルを編集する必要があります。 - -このファイルを保存したら、VS Code が既に実行中の場合はリロードする必要があります。 - -?> また、`.vscode` フォルダ に `extensions.json` および `settings.json` ファイルがあるはずです。 - - -次に、VSCode に統合ターミナルとして表示されるように、MSYS2 ウィンドウを設定します。これには多くの利点があります。ほとんどの場合で、エラー上で Ctrl + クリックするとこれらのファイルにジャンプできます。これによりデバッグがはるかに簡単になります。また、他のウィンドウへジャンプする必要が無いという点でも優れています。 - -1. ファイル > ユーザー設定 > > 設定 をクリックします。 -2. 右上の {} ボタンをクリックし、`settings.json` ファイルを開きます。 -3. ファイルの内容を以下のように設定します: - - ```json - { - "terminal.integrated.shell.windows": "C:\\msys64\\usr\\bin\\bash.exe", - "terminal.integrated.env.windows": { - "MSYSTEM": "MINGW64", - "CHERE_INVOKING": "1" - }, - "terminal.integrated.shellArgs.windows": [ - "--login" - ], - "terminal.integrated.cursorStyle": "line" - } - ``` - - ここに既に設定がある場合は、最初と最後の波括弧の間に全てを追加し、既存の設定を新しく追加された設定とカンマで区切ります。 - -?> MSYS2 を別のフォルダにインストールした場合は、`terminal.integrated.shell.windows` のパスをシステムの正しいパスに変更する必要があります。 - -4. Ctrl-` (Grave) を押して、ターミナルを起動するか、表示 > ターミナル (コマンド `workbench.action.terminal.toggleTerminal`)に進みます。まだターミナルが開いていない場合は、新しいターミナルが開きます。 - - これにより、ワークスペースフォルダ(つまり `qmk_firmware` フォルダ)でターミナルが起動し、キーボードをコンパイルすることができます。 - - -## 他の全てのオペレーティングシステム - -1. [VS Code](https://code.visualstudio.com/) に進み、インストーラをダウンロードします -2. インストーラを実行します -3. 以上です - -いいえ、本当に以上です。必要なパスはパッケージのインストール時に既に含まれています。現在のワークスペースのファイルを検出し、IntelliSense 用に解析する方がより良いです。 - -## プラグイン - -インストールした方が良い拡張が幾つかあります。 - -* [Git Extension Pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack) - -これは QMK ファームウェアで Git を簡単に使用できる Git 関連ツールを多数インスールします。 -* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - _[オプション]_ - QMK コーディング規約にコードを準拠させるのに役立ちます。 -* [GitHub Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview) - _[オプション]_ - VS Code の markdown プレビューを GithHub のようにします。 -* [VS Live Share Extension Pack](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) - _[オプション]_ - この拡張により、他の誰かがあなたのワークスペースにアクセスし(あるいは、あなたが他の誰かのワークスペースにアクセスし)、手伝うことができます。あなたが問題を抱えており、他の誰かの助けが必要な場合に便利です。 - -いずれかの拡張機能をインストールしたら、再起動します。 - -# QMK 用の VS Code の設定 -1. ファイル > フォルダーを開く をクリックします -2. GitHub からクローンした QMK ファームウェアフォルダを開きます。 -3. ファイル > 名前を付けてワークスペースを保存... をクリックします - -これで、VS Code で QMK ファームウェアをコーディングする準備ができました。 diff --git a/docs/ja/pr_checklist.md b/docs/ja/pr_checklist.md deleted file mode 100644 index caab2b4d5045..000000000000 --- a/docs/ja/pr_checklist.md +++ /dev/null @@ -1,145 +0,0 @@ -# PR チェックリスト - - - -これは、提出された PR を QMK の協力者がレビューする際に何をチェックするのかの非網羅的なチェックリストです。 - -これらの推奨事項に矛盾がある場合は、このドキュメントに対して [issue を開く](https://github.com/qmk/qmk_firmware/issues/new)か、[Discord](https://discord.gg/Uq7gcHh) の QMK コラボレータに連絡することをお勧めします。 - -## 一般的な PR - -- PRは、ソースリポジトリ上の `master` ではないブランチを使って提出する必要があります - - これは、あなたの PR にとって別のブランチをターゲットにするという意味ではなく、むしろ自分の master ブランチで作業をしていないという意味です - - もし PR の提出者が自分の `master` ブランチを使っている場合は、マージ後に ["git の使い方"](https://docs.qmk.fm/#/ja/newbs_git_using_your_master_branch) ページへのリンクが表示されます - (このドキュメントの最後にはメッセージの内容が含まれます) -- 新しく追加されたディレクトリとファイル名は小文字でなければなりません - - 上流のソースが元々大文字を使っていた場合 (ChibiOS や他のリポジトリからインポートしたファイルなど)、このルールは緩和されるかもしれません - - 十分な正当性がある場合 (既存のコアファイルとの整合性など) は、このルールを緩和することができます。 - - ボードデザイナーがキーボードの名前を大文字にした場合は、十分な正当性とはみとめられません -- すべての `*.c` および `*.h` ソースファイルの有効なライセンスヘッダ - - 一貫性のために GPL2/GPL3 が推奨されています - - 他のライセンスも許可されていますが、GPL と互換性があり、再配布が許可されていなければなりません。異なるライセンスを使うと、PR がマージされるのをほぼ確実に遅らせることになります -- QMK コードベースの「ベストプラクティス」に従う - - これは網羅的なリストではありませんし、時間が経つにつれて修正される可能性が高いです - - ヘッダファイルでは、`#ifndef` インクルードガードの代わりに `#pragma once` を使います - - 「旧式の」 GPIO/I2C/SPI 関数を使用しない - 正当な理由がない限り、QMK の抽象化を使用しなければなりません (怠惰は正当な理由にはなりません) - - タイミングの抽象化にも従う必要があります: - - `_delay_ms()` のかわりに `wait_ms()` を。(`#include ` も消します) - - `timer_read()` と `timer_read32()` など。 -- タイミング API は [timer.h](https://github.com/qmk/qmk_firmware/blob/master/platforms/timer.h) を参照してください - - 新しい抽象化が有用だと思う場合は、次のことをお勧めします: - - 機能が完成するまで自分のキーボードでプロトタイプを作成する - - Discord の QMK コラボレータと話し合う - - 個別のコア変更としてそれをリファクタリングする - - あなたのキーボードからそのコピーを削除する -- PR を開く前にリベースしてマージの競合をすべて修正します (ヘルプやアドバイスが必要な場合は、Discord で QMK コラボレータに連絡してください)。 - -## キーマップの PR - -- 特定のボードファイルをインクルードするよりも `#include QMK_KEYBOARD_H` を推奨します -- レイヤーは `#define` よりも `enum` が好まれます -- カスタムキーコードは `#define` ではなく `enum` が必要です。最初のエントリには `= SAFE_RANGE` が必要です -- LAYOUT マクロ呼び出しのパラメータの途中の改行ではバックスラッシュ(`\`)は不要です -- スペーシング(コンマまたはキーコードの最初の文字の配置など)に注意を払うと、見栄えの良いキーマップになります - -## キーボードの PR - -終了した PR(インスピレーションを得るために、以前のレビューコメントセットは、自分のレビューのピンポンをなくすのに役立ちます): -https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard - -- `info.json` - - 有効な URL - - 有効なメンテナ - - Configurator で正しく表示されること(Ctrl + Shift + I を押してローカルファイルをプレビューし、高速入力をオンにして順序を確認する) -- `readme.md` - - 標準テンプレートがあること - - 書き込みコマンドが `:flash` で終わっていること - - 有効なハードウェアの入手方法へのリンク (手配線の場合を除く) -- プライベートな共同購入は問題ありませんが、一回限りのプロトタイプは疑問視されます。オープンソースの場合は、ファイルへのリンクを提供してください - - ボードをブートローダーモードにリセットする方法を明確に説明してください - - キーボードの写真、できれば PCB の写真も添付してください -- `rules.mk` - - `MIDI_ENABLE`、`FAUXCLICKY_ENABLE`、`HD44780_ENABLE` は削除されました - - `# Enable Bluetooth with the Adafruit EZ-Key HID` は `# Enable Bluetooth` に変更されました - - 機能の有効化に関する `(-/+サイズ)` コメントはなくなりました - - ブートローダが指定されている場合は、代替ブートローダのリストを削除します - - [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/quantum/mcu_selection.mk)の同等の MCU と比較した場合、同じ値の場合、デフォルトの MCU パラメータの再定義がないこと -- キーボードの `config.h` - - `PRODUCT` 値に `MANUFACTURER` を繰り返さないでください - - `#define DESCRIPTION` は要りません - - マジックキーオプション、 MIDI オプション、HD44780 コンフィギュレーションは要りません - - ユーザー設定の設定可能な `#define` はキーマップ `config.h` に移動する必要があります - - "`DEBOUNCING_DELAY`" の代りに "`DEBOUNCE`" を使います - - キーボードが QMK で起動するために最低限必要なコードが存在する必要があります - - マトリックスと重要なデバイスの初期化コード - - (カスタムキーコードや特別なアニメーションなど)商用キーボードの既存の機能をミラーリングする場合は、`default` ではないキーマップを使って処理する必要があります - - Vial 関連のファイルまたは変更は QMK ファームウェアで使用されないため受け入れられません (Vial 固有のコアコードは提出またはマージされていません) -- `keyboard.c` - - 空の `xxxx_xxxx_kb()` または他の weak-define のデフォルト実装関数が削除されていること - - コメントアウトされた関数も削除されていること - - `matrix_init_board()` などが `keyboard_pre_init_kb()` に移行されました。[keyboard_pre_init*](https://docs.qmk.fm/#/ja/custom_quantum_functions?id=keyboard_pre_init_-function-documentation) を参照してください - - カスタムマトリックスを使用する場合は、`CUSTOM_MATRIX = lite` を選択し、標準のデバウンスを許可します。[マトリックスコードの部分置き換え](https://docs.qmk.fm/#/ja/custom_matrix?id=lite) を参照してください - - 可能な場合は、独自の `led_update_*()` 実装よりも LED インジケータの[設定オプション](https://docs.qmk.fm/#/ja/feature_led_indicators?id=configuration-options)を優先してください。 -- `keyboard.h` - - 先頭に `#include "quantum.h"` を置きます - - `LAYOUT` マクロは、該当する場合は標準の定義を使用してください - - 該当する場合はコミュニティレイアウトマクロ名を使用します (`LAYOUT`/`LAYOUT_all`よりも優先されます) -- キーマップの `config.h` - - キーボードから `rules.mk` や `config.h` が重複していないこと -- `keymaps/default/keymap.c` - - `QMKBEST`/`QMKURL` が削除されていること - - `MO(_LOWER)`および `MO(_RAISE)`キーコードまたは同等のものを使用していて、キーマップに両方のキーを押したときに adjust レイヤーがある場合 - キーマップに直接 adjust レイヤーに入るキーコードがない場合(`MO(_ADJUST)`のように)次のように記述します... - ``` - layer_state_t layer_state_set_user(layer_state_t state) { - return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); - } - ``` - ...キーマップの `process_record_user()` 内で `layer_on()`、 `update_tri_layer()` を手動で処理する代わりに。 -- default (および via) のキーマップは「素朴」でなければなりません。 - - 他のユーザーが独自のユーザー固有のキーマップを開発するための「クリーンな状態」として使用するための最低限のもの。 - - これらのキーマップでは標準のレイアウトが推奨されます(可能な場合) - - デフォルトのキーマップは VIA を有効にするべきではありません -- VIA の統合ドキュメント類には `via` という名前のキーマップが必要です。 -- PR の提出者は、同じ PR に機能を紹介する個人的な(または豪華な)キーマップを持たせることができますが、「デフォルト」のキーマップに埋め込むべきではありません -- PR の提出者はまた、既存の商用キーボードへ QMK を移植する場合、その商用製品の既存の機能を反映する「製造業者に一致する」キーマップを持つことができます -- PR に VIA の json ファイルを含めないでください。これらは QMK ファームウェアで使われないため QMK リポジトリに属しません -- それらは [VIA のキーボードリポジトリ](https://github.com/the-via/keyboards)に属します。 - - -さらに、ChibiOS に固有で: -- 既存の ChibiOS ボード定義を使用することを**強く**推奨します。 - - 多くの場合、同等の Nucleo ボードは、同じファミリの異なるフラッシュサイズまたはわずかに異なるモデルで使用できます。 - - 例:STM32L082KZ の場合、STM32L073RZ に類似しているため、rules.mkで `BOARD = ST_NUCLEO64_L073RZ` を使用できます。 - - QMK は ChibiOS のアップグレード時のメンテナンス負担が継続的に発生するため、可能な限りカスタムボード定義を持たないように移行しています。 -- ボードの定義が避けられない場合、`board.c` には標準の `__early_init()` (通常の ChibiOS ボードの定義と同じ) と空の `boardInit()` を実装しなければなりません。 - - Arm/ChibiOS [早期初期化](https:/docs.qmk.fm/#/ja/platformdev_chibios_earlyinit?id=board-init)を参照してください - - `__early_init()`は、`early_hardware_init_pre()` または `early_hardware_init_post()` で適切に置き換える必要があります - - `boardInit()` は `board_init()` に移行する必要があります - -## コアの PR - -- `develop` ブランチをターゲットにする必要があります。これは、その後、breaking change のタイムラインで `master` にマージされます。 -- その他の注意事項 TBD - - 投稿された変更の幅を考えると、コアはもっと主観的です - ---- - -## 注意事項 - -人々が自分の `master` ブランチを使用する場合、マージ後に以下を投稿します: - -``` -For future reference, we recommend against committing to your `master` branch as you've done here, because pull requests from modified `master` branches can make it more difficult to keep your QMK fork updated. It is highly recommended for QMK development – regardless of what is being done or where – to keep your master updated, but **NEVER** commit to it. Instead, do all your changes in a branch (branches are basically free in Git) and issue PRs from your branches when you're developing. - -There are instructions on how to keep your fork updated here: - -[**Best Practices: Your Fork's Master: Update Often, Commit Never**](https://docs.qmk.fm/#/newbs_git_using_your_master_branch) - -[Fixing Your Branch](https://docs.qmk.fm/#/newbs_git_resynchronize_a_branch) will walk you through fixing up your `master` branch moving forward. If you need any help with this just ask. - -Thanks for contributing! -``` - -## レビュープロセス - -一般的に、PR がマージの対象となる前に、意味のある(例えば、コードを検査した)2つ(またはそれ以上)の承認を確認したいと考えています。これらのレビューはコラボレータに限られません -- 時間を割いてくれるコミュニティメンバーは誰でも歓迎(奨励)されます。唯一の違いは、チェックマークが緑にならないことですが、それは問題ありません。 - -また、PR レビューは自由な時間に行われるものです。それは好意で行われるものなので、私たちはレビューに費やす時間に対して、報酬はうけとっていませんし埋め合わせもありません。そのため、私たちがあなたのプルリクエストに取り掛かるのには時間がかかります。家族や生活のことで PR に手が回らなくなることもあり、そして燃え尽き症候群は深刻な懸念です。QMK ファームウェアリポジトリは、毎月平均200件の PR が開かれ、200件の PR がマージされますので、しばらくお待ちください。 diff --git a/docs/ja/proton_c_conversion.md b/docs/ja/proton_c_conversion.md deleted file mode 100644 index 8f0c857cbacb..000000000000 --- a/docs/ja/proton_c_conversion.md +++ /dev/null @@ -1,98 +0,0 @@ -# キーボードを Proton C を使うように変更 - - - -Proton C は Pro Micro の差し替え可能品であるため、簡単に使用することができます。 -このページでは、キーボードを変換するための便利な自動化されたプロセスと、Pro Micro では利用できない Proton C の機能を利用したい場合の手動プロセスについて説明しています。 - -## 自動で変換 - -QMK で現在サポートされているキーボードが Pro Micro(または互換ボード)を使用しており、Proton C を使用したい場合は、以下のように make 引数に `CONVERT_TO_PROTON_C=yes` (または `CTPC=yes`) を追加することでファームウェアを生成することができます。 - - make 40percentclub/mf68:default CTPC=yes - -同じ引数をキーマップの `rules.mk` に追加しても同じことができます。 - -これは、次のように、`#ifdef` を使用してコード内で使用できる `CONVERT_TO_PROTON_C` フラグを公開します。 - -```c -#ifdef CONVERT_TO_PROTON_C - // Proton C code -#else - // Pro Micro code -#endif -``` - -`PORTB/DDRB` などが定義されていないというエラーが発生した場合は、ARM と AVR の両方で機能する [GPIO 制御](ja/gpio_control.md) を使用するようにキーボードのコードを変換する必要があります。これは AVR ビルドにまったく影響を与えません。 - -Proton C には1つのオンボード LED(C13)しかなく、デフォルトでは TXLED(D5) がそれにマップされています。代わりに RXLED(B0) をそれにマッピングしたい場合は、`config.h` に次のように追加してください。 - - #define CONVERT_TO_PROTON_C_RXLED - -## 機能の変換 - -下記は ARM ボードに実装されているものに基づいたデフォルトです。 - -| 機能 | 説明 | -|--------------------------------------|------------------------------------------------------------------------------------| -| [オーディオ](ja/feature_audio.md) | 有効 | -| [RGB ライト](ja/feature_rgblight.md) | 無効 | -| [バックライト](feature_backlight.md) | ARM が自動コンフィギュレーションを提供できるようになるまで、[タスク駆動 PWM](ja/(feature_backlight.md#software-pwm-driver))が強制されます | -| USB ホスト (例えば USB-USB コンバータ) | 未サポート (USB ホストコードは AVR 固有のもので、現在 ARM ではサポートされていません。 | -| [分割キーボード](ja/feature_split_keyboard.md) | 部分的 - 有効にする機能に大きく依存します | - -## 手動で変換 - -`CTPC = yes` を指定せずに Proton C をネイティブで使用するには、`rules.mk` の `MCU`行を変更する必要があります: - -``` -MCU = STM32F303 -BOARD = QMK_PROTON_C -``` - -次の変数が存在する場合は削除します。 - -* `BOOTLOADER` -* `EXTRA_FLAGS` - -最後に、`config.h`のすべてのピン割り当てを STM32 上の同等のものに変換します。 - -| Pro Micro 左側| Proton C 左側 | | Proton C 右側 | Pro Micro 右側 | -|--------------|--------------|-|--------------|---------------| -| `D3` | `A9` | | 5v | RAW (5v) | -| `D2` | `A10` | | GND | GND | -| GND | GND | | FLASH | RESET | -| GND | GND | | 3.3v | Vcc 1 | -| `D1` | `B7` | | `A2` | `F4` | -| `D0` | `B6` | | `A1` | `F5` | -| `D4` | `B5` | | `A0` | `F6` | -| `C6` | `B4` | | `B8` | `F7` | -| `D7` | `B3` | | `B13` | `B1` | -| `E6` | `B2` | | `B14` | `B3` | -| `B4` | `B1` | | `B15` | `B2` | -| `B5` | `B0` | | `B9` | `B6` | -| `B0` (RX LED) | `C13` 2 | | `C13` 2 | `D5` (TX LED) | - -また、Proton C の拡張部分にあるいくつかの新しいピンを利用することもできます。 - -| 左側 | | 右側 | -|------|-|-------| -| `A4`3 | | `B10` | -| `A5`4 | | `B11` | -| `A6` | | `B12` | -| `A7` | | `A14`5 (SWCLK) | -| `A8` | | `A13`5 (SWDIO) | -| `A15` | | RESET6 | - -注釈: - -1. Pro Micro の Vcc は 3.3V または 5V にすることができます。 -2. Proton C のオンボード LED は、Pro Micro のように2つはありません、1つだけです。Pro Micro には、RX LED(`D5`) と TX LED(`B0`)があります。 -3. `A4` ピンは、スピーカーと共有されています。 -4. `A5` ピンは、スピーカーと共有されています。 -5. `A13` と `A14` ピンはハードウェアデバッグ (SWD) に使用されます。GPIO にも使えますが、最後に使ってください。 -6. RESET を 3.3V とショート(プルアップ)して MCU をリブートします。これは Pro Micro のようにブートローダモードにはならず、MCU をリセットするだけです。 diff --git a/docs/ja/quantum_keycodes.md b/docs/ja/quantum_keycodes.md deleted file mode 100644 index 0795520c6e3d..000000000000 --- a/docs/ja/quantum_keycodes.md +++ /dev/null @@ -1,20 +0,0 @@ -# Quantum キーコード - - - -Quantum キーコードにより、カスタムアクションを定義することなく、基本的なものが提供するものより簡単にキーマップをカスタマイズすることができます。 - -quantum 内の全てのキーコードは `0x0000` と `0xFFFF` の間の数値です。`keymap.c` の中では、関数やその他の特別な場合があるように見えますが、最終的には C プリプロセッサによってそれらは単一の4バイト整数に変換されます。QMK は標準的なキーコードのために `0x0000` から `0x00FF` を予約しています。これらは、`KC_A`、`KC_1` および `KC_LCTL` のようなキーコードで、USB HID 仕様で定義された基本的なキーです。 - -このページでは、高度な quantum 機能を実装するために使われる `0x00FF` と `0xFFFF` の間のキーコードを説明します。独自のカスタムキーコードを定義する場合は、それらもこの範囲に配置されます。 - -## QMK キーコード :id=qmk-keycodes - -| キー | エイリアス | 説明 | -|-----------------|---------|--------------------------------------------------------| -|`QK_BOOTLOADER` |`QK_BOOT`| 書き込みのために、キーボードを bootloader モードにする | -|`QK_DEBUG_TOGGLE`|`DB_TOGG`| デバッグモードの切り替え | -|`QK_CLEAR_EEPROM`|`EE_CLR` | キーボードの EEPROM (永続化メモリ) を再初期化する | diff --git a/docs/ja/ref_functions.md b/docs/ja/ref_functions.md deleted file mode 100644 index 61e3943edd20..000000000000 --- a/docs/ja/ref_functions.md +++ /dev/null @@ -1,124 +0,0 @@ -# キーボードをより良くするための便利なコア関数のリスト - - - -QMK には、信じられないほど便利な、またはあなたが望んでいた機能を少し追加する、隠された関数がたくさんあります。特定の機能に固有の関数はそれぞれの機能のページにあるため、ここには含まれていません。 - -## (OLKB) トライレイヤー :id=olkb-tri-layers - -目的に応じて、実際に使うことができる別個の関数があります。 - -### `update_tri_layer(x, y, z)` - -最初は `update_tri_layer(x, y, z)` 関数です。この関数はレイヤー `x` と `y` の両方がオンになっているかどうかを調べます。両方ともオンの場合は、レイヤー `z` がオンになります。それ以外の場合、`x` と `y` の両方がオンではない(一方のみがオン、またはどちらもオンでない)場合は、レイヤー `z` をオフにします。 - -この関数は、この機能を持つ特定のキーを作成したいが、他のレイヤーのキーコードではそうしたくない場合に便利です。 - -#### 例 - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LOWER: - if (record->event.pressed) { - layer_on(_LOWER); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } else { - layer_off(_LOWER); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } - return false; - case RAISE: - if (record->event.pressed) { - layer_on(_RAISE); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } else { - layer_off(_RAISE); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } - return false; - } - return true; -} -``` - -### `update_tri_layer_state(state, x, y, z)` -もう1つの関数は `update_tri_layer_state(state, x, y, z)` です。この関数は [`layer_state_set_*` 関数](ja/custom_quantum_functions.md#layer-change-code)から呼び出されることを意図しています。これは、キーコードを使ってレイヤーを変更するたびに、これがチェックされることを意味します。したがって、`LT(layer, kc)` を使ってレイヤーを変更すると、同じレイヤーチェックが引き起こされます。 - -このメソッドの注意点は2つあります: -1. `x` および `y` レイヤーをオンにしないと、`z` レイヤーにアクセスできません。これは、レイヤー `z` のみをアクティブにしようとすると、このコードが実行され、使用前にレイヤー `z` がオフになるからです。 -2. レイヤーは最上位の番号から処理されるので、`z` は `x` や `y` よりも上位のレイヤーでなければなりません。そうでなければアクセスできない場合があります。 - -#### 例 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); -} -``` - -あるいは、すぐに値を「返す」必要はありません。複数のトライレイヤーを追加、あるいは追加の効果を追加する場合に便利です。 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); - state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL); - return state; -} -``` - -## 永続的なデフォルトレイヤーの設定 - -デフォルトレイヤーを設定して、キーボードを取り外しても保持されるようにしたいですか?そうであれば、これがそのための関数です。 - -これを使うには、`set_single_persistent_default_layer(layer)` を使います。レイヤーに名前が定義されている場合は、代わりにそれを使うことができます (_QWERTY、_DVORAK、_COLEMAK など)。 - -これは、デフォルトレイヤーを設定し、永続設定が更新され、もし [オーディオ](ja/feature_audio.md) がキーボードで有効でデフォルトレイヤーの音が設定されている場合は、曲を再生します。 - -デフォルトレイヤーの音を設定するには、以下のように `config.h` ファイルに定義する必要があります。 - -```c -#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ - SONG(COLEMAK_SOUND), \ - SONG(DVORAK_SOUND) \ - } -``` - - -?> [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) に使用できる多くの定義済みの曲があります。 - -## キーボードのリセット - -使用できる `RESET` quantum キーコードがあります。ただし、キーを個別に押すのではなくマクロの一部としてリセットしたい場合は、そうすることができます。 - -そのためには、`reset_keyboard()` を関数またはマクロに追加すると、ブートローダがリセットされます。 - -## EEPROM (永続ストレージ)の消去 - -オーディオ、RGB アンダーグロー、バックライト、キーの動作に問題がある場合は、EEPROM (永続的な設定のストレージ)をリセットすることができます。EEPROM を強制的にリセットするには、[`EEP_RST` キーコード](ja/quantum_keycodes.md)あるいは[ブートマジック](ja/feature_bootmagic.md)機能を使います。それらのいずれも選択肢にない場合は、カスタムマクロを使って行うことができます。 - -EEPROM を消去するには、関数またはマクロから `eeconfig_init()` を実行し、ほとんどの設定をデフォルトにリセットします。 - -## タップランダムキー - -ランダムな文字をホストコンピュータに送信する場合は、`tap_random_base64()` 関数を使うことができます。これは[疑似乱数的に](https://en.wikipedia.org/wiki/Pseudorandom_number_generator)0から63の数字を選択し、その選択に基づいてキー押下を送信します。(0–25 は `A`–`Z`、26–51 は `a`–`z`、52–61 は `0`–`9`、62 は `+`、63 は `/`)。 - -?> 言うまでもないですが、これはランダムに Base64 キーあるいはパスワードを生成する暗号的に安全な方法では _ありません_。 - -## ソフトウェアタイマー - -タイマーを開始し、時間固有のイベントの値を読み取ることができます。以下は例です: - -```c -static uint16_t key_timer; -key_timer = timer_read(); - -if (timer_elapsed(key_timer) < 100) { - // 経過時間が 100ms 未満の場合に何かを行う -} else { - // 経過時間が 100ms 以上の場合に何かを行う -} -``` diff --git a/docs/ja/reference_configurator_support.md b/docs/ja/reference_configurator_support.md deleted file mode 100644 index aefd04dd8a93..000000000000 --- a/docs/ja/reference_configurator_support.md +++ /dev/null @@ -1,200 +0,0 @@ -# QMK Configurator でのキーボードのサポート - - - -このページは [QMK Configurator](https://config.qmk.fm/) でキーボードを適切にサポートする方法について説明します。 - - -## Configurator がキーボードを理解する方法 - -Configurator がキーボードをどのように理解するかを理解するには、最初にレイアウトマクロを理解する必要があります。この演習では、17キーのテンキー PCB を想定します。これを `numpad` と呼びます。 - -``` -|---------------| -|NLk| / | * | - | -|---+---+---+---| -|7 |8 |9 | + | -|---+---+---| | -|4 |5 |6 | | -|---+---+---+---| -|1 |2 |3 |Ent| -|-------+---| | -|0 | . | | -|---------------| -``` - -?> レイアウトマクロの詳細については、[QMK の理解: マトリックススキャン](ja/understanding_qmk.md?id=matrix-scanning) と [QMK の理解: マトリックスから物理レイアウトへのマップ](ja/understanding_qmk.md?id=matrix-to-physical-layout-map) を見てください。 - -Configurator の API はキーボードの `.h` ファイルを `qmk_firmware/keyboards//.h` から読み取ります。numpad の場合、このファイルは `qmk_firmware/keyboards/numpad/numpad.h` です: - -```c -#pragma once - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, KC_NO }, \ - { k30, k31, k32, k33 }, \ - { k40, KC_NO, k42, KC_NO } \ -} -``` - -QMK は `KC_NO` を使って、スイッチマトリックス内のスイッチがない場所を指定します。デバッグが必要な場合に、このセクションを読みやすくするために、`XXX`、`___`、`____` を略記として使うこともあります。通常は `.h` ファイルの先頭近くで定義されます: - -```c -#pragma once - -#define XXX KC_NO - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, XXX }, \ - { k30, k31, k32, k33 }, \ - { k40, XXX, k42, XXX } \ -} -``` - -!> この使用方法はキーマップマクロと異なります。キーマップマクロはほとんど常に`KC_NO`については`XXXXXXX` (7つの大文字の X) を、`KC_TRNS` については `_______` (7つのアンダースコア)を使います。 - -!> ユーザの混乱を防ぐために、`KC_NO` を使うことをお勧めします。 - -レイアウトマクロは、キーボードに17個のキーがあり、4列それぞれが5行に配置されていることを Configurator に伝えます。スイッチの位置は、0から始まる `k` という名前が付けられています。キーマップからキーコードを受け取る上部セクションと、マトリックス内の各キーの位置を指定する下部セクションとが一致する限り、名前自体は実際には問題ではありません。 - -物理的なキーボードに似た形でキーボードを表示するには、それぞれのキーの物理的な位置とサイズをスイッチマトリックスに結びつけることを Configurator に伝える JSON ファイルを作成する必要があります。 - -## JSON ファイルのビルド - -JSON ファイルをビルドする最も簡単な方法は、[Keyboard Layout Editor](https://www.keyboard-layout-editor.com/) ("KLE") でレイアウトを作成することです。この Raw Data を QMK tool に入れて、Configurator が読み出して使用する JSON ファイルに変換します。KLE は numpad レイアウトをデフォルトで開くため、Getting Started の説明を削除し、残りを使います。 - -レイアウトが望み通りのものになったら、KLE の Raw Data タブに移動し、内容をコピーします: - -``` -["Num Lock","/","*","-"], -["7\nHome","8\n↑","9\nPgUp",{h:2},"+"], -["4\n←","5","6\n→"], -["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"], -[{w:2},"0\nIns",".\nDel"] -``` - -このデータを JSON に変換するには、[QMK KLE-JSON Converter](https://qmk.fm/converter/) に移動し、Raw Data を Input フィールド に貼り付け、Convert ボタンをクリックします。しばらくすると、JSON データが Output フィールドに表示されます。内容を新しいテキストドキュメントにコピーし、ドキュメントに `info.json` という名前を付け、`numpad.h` を含む同じフォルダに保存します。 - -`keyboard_name` オブジェクトを使ってキーボードの名前を設定します。説明のために、各キーのオブジェクトを各行に配置します。これはファイルを人間が読みやすいものにするためのもので、Configurator の機能には影響しません。 - -```json -{ - "keyboard_name": "Numpad", - "url": "", - "maintainer": "qmk", - "tags": { - "form_factor": "numpad" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label":"Num Lock", "x":0, "y":0}, - {"label":"/", "x":1, "y":0}, - {"label":"*", "x":2, "y":0}, - {"label":"-", "x":3, "y":0}, - {"label":"7", "x":0, "y":1}, - {"label":"8", "x":1, "y":1}, - {"label":"9", "x":2, "y":1}, - {"label":"+", "x":3, "y":1, "h":2}, - {"label":"4", "x":0, "y":2}, - {"label":"5", "x":1, "y":2}, - {"label":"6", "x":2, "y":2}, - {"label":"1", "x":0, "y":3}, - {"label":"2", "x":1, "y":3}, - {"label":"3", "x":2, "y":3}, - {"label":"Enter", "x":3, "y":3, "h":2}, - {"label":"0", "x":0, "y":4, "w":2}, - {"label":".", "x":2, "y":4} - ] - } - } -} -``` - -`layouts` オブジェクトにはキーボードの物理レイアウトを表すデータが含まれます。このオブジェクトには `LAYOUT` という名前のオブジェクトがあり、このオブジェクト名は `numpad.h` のレイアウトマクロの名前と一致する必要があります。`LAYOUT` オブジェクト自体には `layout` という名前のオブジェクトがあります。このオブジェクトにはキーボードの物理キーごとに 1つの JSON オブジェクトが以下の形式で含まれています: - -``` - キーの名前。Configurator では表示されません。 - | - | キーボードの左端からのキー単位での - | | キーの X 軸の位置。 - | | - | | キーボードの上端(奥側)からのキー単位での - | | | キーの Y 軸位置。 - ↓ ↓ ↓ -{"label":"Num Lock", "x":0, "y":0}, -``` - -一部のオブジェクトには、それぞれキーの幅と高さを表す `"w"` 属性キーと `"h"` 属性キーがあります。 - -?> `info.json` ファイルの詳細については、[`info.json` 形式](ja/reference_info_json.md) を参照してください。 - - -## Configurator がキーをプログラムする方法 - -Configurator の API は、指定されたレイアウトマクロと JSON ファイルを使って、特定のキーに関連付けられた各ビジュアルオブジェクトを順番に持つキーボードのビジュアル表現を作成します: - -| レイアウトマクロのキー | 使用される JSON オブジェクト | -:---: | :---- -| k00 | {"label":"Num Lock", "x":0, "y":0} | -| k01 | {"label":"/", "x":1, "y":0} | -| k02 | {"label":"*", "x":2, "y":0} | -| k03 | {"label":"-", "x":3, "y":0} | -| k10 | {"label":"7", "x":0, "y":1} | -| k11 | {"label":"8", "x":1, "y":1} | -| k12 | {"label":"9", "x":2, "y":1} | -| k13 | {"label":"+", "x":3, "y":1, "h":2} | -| k20 | {"label":"4", "x":0, "y":2} | -| k21 | {"label":"5", "x":1, "y":2} | -| k22 | {"label":"6", "x":2, "y":2} | -| k30 | {"label":"1", "x":0, "y":3} | -| k31 | {"label":"2", "x":1, "y":3} | -| k32 | {"label":"3", "x":2, "y":3} | -| k33 | {"label":"Enter", "x":3, "y":3, "h":2} | -| k40 | {"label":"0", "x":0, "y":4, "w":2} | -| k42 | {"label":".", "x":2, "y":4} | - -ユーザが Configurator で左上のキーを選択し、Num Lock を割り当てると、Configurator は最初のキーとして `KC_NUM` を持つキーマップを作成し、同様にキーマップが作成されます。`label` キーは使われません; それらは `info.json` ファイルをデバッグする時に特定のキーを識別するためのユーザの参照のためだけのものです。 - - -## 問題と危険 - -現在のところ、Configurator はキーの回転または ISO Enter などの長方形ではないキーをサポートしません。さらに、"行"から垂直方向にずれているキー、— 顕著な例として [TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/) のような1800レイアウト上の矢印キー — は、 `info.json` ファイルの提供者によって調整されていない場合は、KLE-to-JSON コンバータを混乱させます。 - -### 回避策 - -#### 長方形ではないキー - -ISO Enter キーについては、QMK custom は幅 1.25u、高さ 2u の長方形のキーとして表示し、右端が英数字キーブロックの右端に揃うように配置されます。 - -![](https://i.imgur.com/JKngtTw.png) -*QMK Configurator によって描画される標準 ISO レイアウトの60%キーボード。* - -#### 垂直方向にずれたキー - -垂直方向にずれたキーについては、ずれていないかのように KLE で配置し、変換された JSON ファイルで必要に応じて Y 値を編集します。 - -![](https://i.imgur.com/fmDvDzR.png) -*矢印キーに適用される垂直方向のずれのない、Keyboard Layout Editor で描画された1800レイアウトのキーボード。* - -![](https://i.imgur.com/8beYMBR.png) -*キーボードの JSON ファイルで矢印キーを垂直方向にずらすために必要な変更を示す、Unix の diff ファイル。* diff --git a/docs/ja/reference_glossary.md b/docs/ja/reference_glossary.md deleted file mode 100644 index 06c719612386..000000000000 --- a/docs/ja/reference_glossary.md +++ /dev/null @@ -1,173 +0,0 @@ -# QMK 用語集 - - - -## ARM -Atmel、Cypress、Kinetis、NXP、ST、TI など多くの企業が生産する 32 ビット MCU のライン。 - -## AVR -[Atmel](https://www.microchip.com/) が生産する 8 ビット MCU のライン。AVR は TMK がサポートしていた元のプラットフォームでした。 - -## AZERTY -標準的な Français (フランス) キーボードレイアウト。キーボードの最初の6つのキーから命名されました。 - -## バックライト -キーボードのライトの総称。バックライトが一般的ですが、それだけではなく、キーキャップあるいはスイッチを通して光る LED の配列。 - -## Bluetooth -短距離のピアツーピア無線プロトコル。キーボード用のもっとも一般的なワイヤレスプロトコル。 - -## ブートローダ -MCU の保護領域に書き込まれる特別なプログラムで、MCU が独自のファームウェアを通常は USB 経由でアップグレードできるようにします。 - -## ブートマジック -よくあるキーの交換あるいは無効化など、様々なキーボードの挙動の変更をその場で実行できる機能。 - -## C -システムコードに適した低レベルプログラミング言語。QMK のほとんどのコードは C で書かれています。 - -## Colemak -人気が出始めている代替キーボードレイアウト。 - -## コンパイル -人間が読めるコードを MCU が実行できるマシンコードに変換するプロセス。 - -## Dvorak -1930年代に Dr. August Dvorak によって開発された代替キーボードレイアウト。Dvorak Simplified Keyboard の短縮形。 - -## 動的マクロ -キーボードに記録されたマクロで、キーボードのプラグを抜くか、コンピュータを再起動すると失われます。 - -* [動的マクロドキュメント](ja/feature_dynamic_macros.md) - -## Eclipse -多くの C 開発者に人気のある IDE。 - -* [Eclipse セットアップ手順](ja/other_eclipse.md) - -## ファームウェア -MCU を制御するソフトウェア - -## git -コマンドラインで使用されるバージョン管理ソフトウェア - -## GitHub -QMK プロジェクトのほとんどをホストする Web サイト。git、課題管理、および QMK の実行に役立つその他の機能を統合して提供します。 - -## ISP -インシステムプログラミング。外部ハードウェアと JTAG ピンを使って AVR チップをプログラミングする方法。 - -## hid_listen -キーボードからデバッグメッセージを受信するためのインタフェース。[QMK Flasher](https://github.com/qmk/qmk_flasher) あるいは [PJRC の hid_listen](https://www.pjrc.com/teensy/hid_listen.html) を使ってこれらのメッセージを見ることができます。 - -## キーコード -特定のキーを表す2バイトの数値。`0x00`-`0xFF` は[基本キーコード](ja/keycodes_basic.md)に使われ、`0x100`-`0xFFFF` は [Quantum キーコード](ja/quantum_keycodes.md) に使われます。 - -## キーダウン -キーが押された時に発生し、キーが放される前に完了するイベント。 - -## キーアップ -キーが放された時に発生するイベント。 - -## キーマップ -物理的なキーボードレイアウトにマップされたキーコードの配列。キーの押下およびリリース時に処理されます。 - -## レイヤー -1つのキーが複数の目的を果たすために使われる抽象化。最上位のアクティブなレイヤーが優先されます。 - -## リーダーキー -リーダーキーに続けて1, 2 あるいは3つのキーをタップすることで、キーの押下あるいは他の quantum 機能をアクティブにする機能。 - -* [リーダーキードキュメント](ja/feature_leader_key.md) - -## LED -発光ダイオード。キーボードの表示に使われる最も一般的なデバイス。 - -## Make -全てのソースファイルをコンパイルするために使われるソフトウェアパッケージ。キーボードファームウェアをコンパイルするために、様々なオプションを指定して `make` を実行します。 - -## マトリックス -MCU がより少ないピン数でキー押下を検出できるようにする列と行の配線パターン。マトリックスには多くの場合、NKRO を可能にするためのダイオードが組み込まれています。 - -## マクロ -単一のキーのみを押した後で、複数のキー押下イベント (HID レポート) を送信できる機能。 - -* [マクロドキュメント](ja/feature_macros.md) - -## MCU -マイクロコントロールユニット。キーボードを動かすプロセッサ。 - -## モディファイア -別のキーを入力する間押したままにして、そのキーのアクションを変更するキー。例として、Ctrl、Alt および Shift があります。 -(訳注:モディファイヤ、モディファイヤキー、修飾キーなど、訳語が統一されていませんが同じものです) - -## マウスキー -キーボードからマウスカーソルを制御し、クリックできる機能。 - -* [マウスキードキュメント](ja/feature_mouse_keys.md) - -## N キーロールオーバー (NKRO) -一度に任意の数のキーの押下を送信できるキーボードに当てはまる用語。 - -## ワンショットモディファイア -別のキーが放されるまで押されているかのように機能するモディファイア。キーを押している間に mod を押し続けるのではなく、mod を押してからキーを押すことができます。スティッキーキーまたはデッドキーとも呼びます。 - -## ProMicro -低コストの AVR 開発ボード。このデバイスのクローンは ebay で非常に安価(5ドル未満)に見つかることがありますが、多くの場合 pro micro の書き込みに苦労します。 - -## プルリクエスト -QMK にコードを送信するリクエスト。全てのユーザが個人のキーマップのプルリクエストを送信することを推奨します。 - -## QWERTY -標準の英語キーボードレイアウト。多くの場合、他の言語の標準レイアウトへのショートカット。キーボードの最初の6文字から命名されました。 - -## QWERTZ -標準的な Deutsche (ドイツ語) キーボードレイアウト。キーボードの最初の6文字から命名されました。 - -## ロールオーバー -キーが既に押されている間にキーを押すことを指す用語。似たものに 2KRO、6KRO、NKRO が含まれます。 - -## スキャンコード -単一のキーを表す USB 経由の HID レポートの一部として送信される1バイトの数値。これらの値は、[USB-IF](https://www.usb.org/) が発行する [HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) に記載されています。 - -## スペースカデットシフト -左または右 shift を1回以上タップすることで、様々なタイプの括弧を入力できる特別な shift キーのセット。 - -* [スペースカデットシフトドキュメント](ja/feature_space_cadet_shift.md) - -## タップ -キーを押して放す。状況によってはキーダウンイベントとキーアップイベントを区別する必要がありますが、タップは常に両方を一度に指します。 - -## タップダンス -押す回数に基づいて、同じキーに複数のキーコードを割り当てることができる機能。 - -* [タップダンスドキュメント](ja/feature_tap_dance.md) - -## Teensy -手配線での組み立てによく用いられる低コストの AVR 開発ボード。halfkay ブートローダによって書き込みが非常に簡単になるために、数ドル高いにもかかわらず teensy がしばしば選択されます。 - -## アンダーライト -キーボードの下側を照らす LED の総称。これらの LED は通常 PCB の底面からキーボードが置かれている表面に向けて照らします。 - -## ユニコード -大規模なコンピュータの世界では、ユニコードは任意の言語で文字を表現するためのエンコード方式のセットです。QMK に関しては、様々な OS スキームを使ってスキャンコードの代わりにユニコードコードポイントを送信することを意味します。 - -* [ユニコードドキュメント](ja/feature_unicode.md) - -## 単体テスト -QMK に対して自動テストを実行するためのフレームワーク。単体テストは、変更が何も壊さないことを確信するのに役立ちます。 - -* [単体テストドキュメント](ja/unit_testing.md) - -## USB -ユニバーサルシリアルバス。キーボード用の最も一般的な有線インタフェース。 - -## USB ホスト (あるいは単にホスト) -USB ホストは、あなたのコンピュータ、またはキーボードが差し込まれているデバイスのことです。 - -# 探している用語が見つかりませんでしたか? - -質問についての [issue を開いて](https://github.com/qmk/qmk_firmware/issues) 、質問した用語についてここに追加することができます。さらに良いのは、定義についてのプルリクエストを開くことです。:) diff --git a/docs/ja/reference_info_json.md b/docs/ja/reference_info_json.md deleted file mode 100644 index e6a71adc9df2..000000000000 --- a/docs/ja/reference_info_json.md +++ /dev/null @@ -1,68 +0,0 @@ -# `info.json` - - - -このファイルは [QMK API](https://github.com/qmk/qmk_api) によって使われます。このファイルは [QMK Configurator](https://config.qmk.fm/) がキーボードの画像を表示するために必要な情報を含んでいます。ここにメタデータを設定することもできます。 - -このメタデータを指定するために、`qmk_firmware/keyboards/` の下の全てのレベルで `info.json` を作成することができます。これらのファイルは結合され、より具体的なファイルがそうではないファイルのキーを上書きします。つまり、メタデータ情報を複製する必要はありません。例えば、`qmk_firmware/keyboards/clueboard/info.json` は `manufacturer` および `maintainer` を指定し、`qmk_firmware/keyboards/clueboard/66/info.json` は Clueboard 66% についてのより具体的な情報を指定します。 - -## `info.json` の形式 - -`info.json` ファイルは設定可能な以下のキーを持つ JSON 形式の辞書です。全てを設定する必要はなく、キーボードに適用するキーだけを設定します。 - -* `keyboard_name` - * キーボードを説明する自由形式のテキスト文字列。 - * 例: `Clueboard 66%` -* `url` - * キーボードの製品ページ、[QMK.fm/keyboards](https://qmk.fm/keyboards) のページ、あるいはキーボードに関する情報を説明する他のページの URL。 -* `maintainer` - * メンテナの GitHub のユーザ名、あるいはコミュニティが管理するキーボードの場合は `qmk` -* `layouts` - * 物理的なレイアウト表現。詳細は以下のセクションを見てください。 - -### レイアウトの形式 - -`info.json` ファイル内の辞書の `layouts` 部分は、幾つかの入れ子になった辞書を含みます。外側のレイヤーは QMK レイアウトマクロで構成されます。例えば、`LAYOUT_ansi` あるいは `LAYOUT_iso`。 - -* `layout` - * 物理レイアウトを説明するキー辞書のリスト。詳細は次のセクションを見てください。 - -### キー辞書形式 - -レイアウトの各キー辞書は、キーの物理プロパティを記述します。 の Raw Code に精通している場合、多くの概念が同じであることが分かります。可能な限り同じキー名とレイアウトの選択を再利用しますが、keyboard-layout-editor とは異なって各キーはステートレスで、前のキーからプロパティを継承しません。 - -全てのキーの位置と回転は、キーボードの左上と、各キーの左上を基準にして指定されます。 - -* `x` - * **必須**: 水平軸でのキーの絶対位置(キー単位)。 -* `y` - * **必須**: 垂直軸でのキーの絶対位置(キー単位)。 -* `w` - * キー単位でのキーの幅。`ks` が指定された場合は無視されます。デフォルト: `1` -* `h` - * キー単位でのキーの高さ。`ks` が指定された場合は無視されます。デフォルト: `1` -* `r` - * キーを回転させる時計回りの角度。 -* `rx` - * キーを回転させる点の水平軸における絶対位置。デフォルト: `x` -* `ry` - * キーを回転させる点の垂直軸における絶対位置。デフォルト: `y` -* `ks` - * キー形状: キー単位で頂点を列挙することでポリゴンを定義します。 - * **重要**: これらはキーの左上からの相対位置で、絶対位置ではありません。 - * ISO Enter の例: `[ [0,0], [1.5,0], [1.5,2], [0.25,2], [0.25,1], [0,1], [0,0] ]` -* `label` - * マトリックス内のこの位置につける名前。 - * これは通常 PCB 上でこの位置にシルクスクリーン印刷されるものと同じ名前でなければなりません。 - -## メタデータはどのように公開されますか? - -このメタデータは主に2つの方法で使われます: - -* Web ベースの configurator が動的に UI を生成できるようにする。 -* 新しい `make keyboard:keymap:qmk` ターゲットをサポートする。これは、このメタデータをファームウェアにバンドルして QMK Toolbox をよりスマートにします。 - -Configurator の作成者は、JSON API の使用に関する詳細について、[QMK Compiler](https://docs.api.qmk.fm/using-the-api) ドキュメントを参照することができます。 diff --git a/docs/ja/reference_keymap_extras.md b/docs/ja/reference_keymap_extras.md deleted file mode 100644 index fb9d167ae035..000000000000 --- a/docs/ja/reference_keymap_extras.md +++ /dev/null @@ -1,89 +0,0 @@ -# 言語固有のキーコード - - - -キーボードは多くの言語をサポートすることができます。ただし、それらはキーを押したことで生成される実際の文字を送信しません - 代わりに数字のコードを送信します。USB HID の仕様ではそれらは "usages" と呼ばれますが、キーボードの文脈では「スキャンコード」あるいは「キーコード」と呼ばれることが多いです。 -HID Keyboard/Keypad usage ページでは 256 未満の usage が定義されており、それらの一部は現在のオペレーティングシステムでは機能しません。では、この言語のサポートはどのようにして実現されるのでしょうか? - -簡単に言うと、オペレーティングシステムはユーザが設定したキーボードレイアウトに基づいて受け取った usage を適切な文字にマップします。例えば、スウェーデン人がキーボードの `å` という文字が刻印されたキーを押すと、キーボードは *実際には* `[` のキーコードを送信します。 - -明らかにこれは混乱する可能性があるため、QMK は多くのキーボードレイアウトのために言語固有のキーコードのエイリアスを提供します。これらはそれだけでは何もしません - さらに OS の設定で対応するキーボードレイアウトを設定する必要があります。それらをキーマップのキーキャップラベルと考えてください。 - -これらを使うには、`keymap.c` で対応する [ヘッダファイル](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras) を `#include` し、それらで定義されているキーコードを `KC_` プリフィクスの代わりに追加します: - -| レイアウト | ヘッダファイル | -|-----------------------------|----------------------------------| -| Canadian Multilingual (CSA) | `keymap_canadian_multilingual.h` | -| Croatian | `keymap_croatian.h` | -| Czech | `keymap_czech.h` | -| Danish | `keymap_danish.h` | -| Dutch (Belgium) | `keymap_belgian.h` | -| English (Ireland) | `keymap_irish.h` | -| English (UK) | `keymap_uk.h` | -| English (US International) | `keymap_us_international.h` | -| Estonian | `keymap_estonian.h` | -| Finnish | `keymap_finnish.h` | -| French | `keymap_french.h` | -| French (AFNOR) | `keymap_french_afnor.h` | -| French (BÉPO) | `keymap_bepo.h` | -| French (Belgium) | `keymap_belgian.h` | -| French (Switzerland) | `keymap_fr_ch.h` | -| French (macOS, ISO) | `keymap_french_osx.h` | -| German | `keymap_german.h` | -| German (Switzerland) | `keymap_german_ch.h` | -| German (macOS) | `keymap_german_osx.h` | -| German (Neo2)* | `keymap_neo2.h` | -| Greek* | `keymap_greek.h` | -| Hebrew* | `keymap_hebrew.h` | -| Hungarian | `keymap_hungarian.h` | -| Icelandic | `keymap_icelandic.h` | -| Italian | `keymap_italian.h` | -| Italian (macOS, ANSI) | `keymap_italian_osx_ansi.h` | -| Italian (macOS, ISO) | `keymap_italian_osx_iso.h` | -| Japanese | `keymap_jp.h` | -| Korean | `keymap_korean.h` | -| Latvian | `keymap_latvian.h` | -| Lithuanian (ĄŽERTY) | `keymap_lithuanian_azerty.h` | -| Lithuanian (QWERTY) | `keymap_lithuanian_qwerty.h` | -| Norwegian | `keymap_norwegian.h` | -| Polish | `keymap_polish.h` | -| Portuguese | `keymap_portuguese.h` | -| Portuguese (macOS, ISO) | `keymap_portuguese_osx_iso.h` | -| Portuguese (Brazil) | `keymap_br_abnt2.h` | -| Romanian | `keymap_romanian.h` | -| Russian* | `keymap_russian.h` | -| Serbian* | `keymap_serbian.h` | -| Serbian (Latin) | `keymap_serbian_latin.h` | -| Slovak | `keymap_slovak.h` | -| Slovenian | `keymap_slovenian.h` | -| Spanish | `keymap_spanish.h` | -| Spanish (Dvorak) | `keymap_spanish_dvorak.h` | -| Swedish | `keymap_swedish.h` | -| Turkish (F) | `keymap_turkish_f.h` | -| Turkish (Q) | `keymap_turkish_q.h` | - -言語固有でないものもありますが、QWERTY レイアウトを使っていない場合に役立ちます: - -| レイアウト | ヘッダファイル | -|---------------------|--------------------------| -| Colemak | `keymap_colemak.h` | -| Dvorak | `keymap_dvorak.h` | -| Dvorak (French) | `keymap_dvorak_fr.h` | -| Dvorak (Programmer) | `keymap_dvp.h` | -| Norman | `keymap_norman.h` | -| Plover* | `keymap_plover.h` | -| Plover (Dvorak)* | `keymap_plover_dvorak.h` | -| Steno* | `keymap_steno.h` | -| Workman | `keymap_workman.h` | -| Workman (ZXCVM) | `keymap_workman_zxcvm.h` | - -## Sendstring サポート - -デフォルトでは、`SEND_STRING()` は US ANSI キーボードレイアウトが設定されたと見なします。別のレイアウトを使っている場合は、キーマップで(上記のように)`#include "sendstring_*.h"` して、ASCII 文字をキーコードにマッピングするために使われるルックアップテーブルを上書きすることができます。 - -ここで注意すべき重要な点は、`SEND_STRING()` は [ASCII 文字](https://en.wikipedia.org/wiki/ASCII#Character_set) でのみ機能するということです。これは、ユニコード文字を含む文字列を渡すことができないことを意味します - 残念ながら、これには希望のレイアウトに存在する可能性のあるアクセント付き文字が含まれています。 -多くのレイアウトでは、Grave または Tilde などの特定の文字を[デッドキー](https://en.wikipedia.org/wiki/Dead_key)としてのみ使えるようにしています。そのため、デッドキーが次の文字と潜在的に結合されることを防ぐためには、送信したい文字列の中のデッドキーのすぐ後にスペースを追加する必要があります。 -ラテン語由来のアルファベットを使わない(例えば、ギリシャ語やロシア語のような)他のレイアウトには、Sendstring ヘッダーがありません。従って ASCII 文字セットのほとんどを入力する方法がありません。これらは上記で `*` でマークされています。 diff --git a/docs/ja/serial_driver.md b/docs/ja/serial_driver.md deleted file mode 100644 index 72071f4f7ed3..000000000000 --- a/docs/ja/serial_driver.md +++ /dev/null @@ -1,75 +0,0 @@ -# 'シリアル' ドライバ - - - -このドライバは[分割キーボード](ja/feature_split_keyboard.md) 機能に使います。 - -?> この文章でのシリアルは、UART/USART/RS485/RS232 規格の実装ではなく、**一度に1ビットの情報を送信するもの**として読まれるべきです。 - -このカテゴリの全てのドライバには以下の特徴があります: -* 1本の線上でデータと信号を提供 -* シングルマスタ、シングルスレーブに限定 - -## サポートされるドライバの種類 - -| | AVR | ARM | -|-------------------|--------------------|--------------------| -| bit bang | :heavy_check_mark: | :heavy_check_mark: | -| USART Half-duplex | | :heavy_check_mark: | - -## ドライバ設定 - -### Bitbang -デフォルトのドライバ。設定がない場合はこのドライバが想定されます。設定するには、以下を rules.mk に追加します: - -```make -SERIAL_DRIVER = bitbang -``` - -config.h を介してドライバを設定します: -```c -#define SOFT_SERIAL_PIN D0 // または D1, D2, D3, E6 -#define SELECT_SOFT_SERIAL_SPEED 1 // または 0, 2, 3, 4, 5 - // 0: 約 189kbps (実験目的のみ) - // 1: 約 137kbps (デフォルト) - // 2: 約 75kbps - // 3: 約 39kbps - // 4: 約 26kbps - // 5: 約 20kbps -``` - -#### ARM - -!> bitbang ドライバは bitbang WS2812 ドライバと接続の問題があります - -上記の一般的なオプションに加えて、halconf.h で `PAL_USE_CALLBACKS` 機能もオンにする必要があります。 - -### USART Half-duplex -通信が USART ハードウェアデバイスに送信される STM32 ボードが対象です。これにより高速で正確なタイミングを提供できることが利点です。このドライバの `SOFT_SERIAL_PIN` は、設定された USART TX ピンです。**TX ピンに適切なプルアップ抵抗が必要です**。設定するには、以下を rules.mk に追加します: - -```make -SERIAL_DRIVER = usart -``` - -config.h を介してハードウェアを設定します: -```c -#define SOFT_SERIAL_PIN B6 // USART TX ピン -#define SELECT_SOFT_SERIAL_SPEED 1 // または 0, 2, 3, 4, 5 - // 0: 約 460800 ボー - // 1: 約 230400 ボー (デフォルト) - // 2: 約 115200 ボー - // 3: 約 57600 ボー - // 4: 約 38400 ボー - // 5: 約 19200 ボー -#define SERIAL_USART_DRIVER SD1 // TX ピンの USART ドライバ。デフォルトは SD1 -#define SERIAL_USART_TX_PAL_MODE 7 // 「代替機能」 ピン。MCU の適切な値については、それぞれのデータシートを見てください。デフォルトは 7 -``` - -また、ChibiOS `SERIAL` 機能を有効にする必要があります: -* キーボードの halconf.h: `#define HAL_USE_SERIAL TRUE` -* キーボードの mcuconf.h: `#define STM32_SERIAL_USE_USARTn TRUE` (ここで、'n' は MCU で選択した USART のペリフェラル番号と一致) - -必要な構成は、`UART` 周辺機器ではなく、`SERIAL` 周辺機器であることに注意してください。 diff --git a/docs/ja/support.md b/docs/ja/support.md deleted file mode 100644 index 01c2d41d19cb..000000000000 --- a/docs/ja/support.md +++ /dev/null @@ -1,22 +0,0 @@ -# 助けを得る - - - -QMK に関して助けを得るための多くのリソースがあります。 - -コミュニティスペースに参加する前に[行動規範](https://qmk.fm/coc/)を読んでください。 - -## リアルタイムチャット - -何かについて助けが必要な場合は、迅速なサポートを受けるための最良の場所は、[Discord Server](https://discord.gg/Uq7gcHh) です。通常は誰かがオンラインで、非常に助けになる多くの人がいます。 - -## OLKB Subreddit - -公式の QMK フォーラムは [reddit.com](https://reddit.com) の [/r/olkb](https://reddit.com/r/olkb) です。 - -## GitHub Issues - -[GitHub で issue](https://github.com/qmk/qmk_firmware/issues) を開くことができます。issue は長期的な議論あるいはデバッグを必要とする場合は、特に便利です。 diff --git a/docs/ja/syllabus.md b/docs/ja/syllabus.md deleted file mode 100644 index 9209cb49e086..000000000000 --- a/docs/ja/syllabus.md +++ /dev/null @@ -1,76 +0,0 @@ -# QMK シラバス - - - -このページは最初に基本を紹介し、そして、QMK に習熟するために必要な全ての概念を理解するように導くことで、QMK の知識を構築するのに役立ちます。 - -# 初級トピック - -他に何も読んでいない場合は、このセクションのドキュメントを読んでください。[QMK 初心者ガイド](ja/newbs.md)を読み終わると、基本的なキーマップを作成し、それをコンパイルし、キーボードに書き込みできるようになっているはずです。残りのドキュメントはこれらの基本的な知識を具体的に肉付けします。 - -* **QMK Tools の使い方を学ぶ** - * [QMK 初心者ガイド](ja/newbs.md) - * [CLI](ja/cli.md) - * [Git](ja/newbs_git_best_practices.md) -* **キーマップについて学ぶ** - * [レイヤー](ja/feature_layers.md) - * [キーコード](ja/keycodes.md) - * 使用できるキーコードの完全なリスト。中級または上級トピックにある知識が必要な場合もあることに注意してください。 -* **IDE の設定** - オプション - * [Eclipse](ja/other_eclipse.md) - * [VS Code](ja/other_vscode.md) - -# 中級トピック - -これらのトピックでは、QMK がサポートする幾つかの機能について掘り下げます。これらのドキュメントを全て読む必要はありませんが、これらの一部をスキップすると、上級トピックのセクションの一部のドキュメントが意味をなさなくなるかもしれません。 - -* **機能の設定方法を学ぶ** - - * [オーディオ](ja/feature_audio.md) - * 電飾 - * [バックライト](ja/feature_backlight.md) - * [LED マトリックス](ja/feature_led_matrix.md) - * [RGB ライト](ja/feature_rgblight.md) - * [RGB マトリックス](ja/feature_rgb_matrix.md) - * [タップホールド設定](ja/tap_hold.md) -* **キーマップについてさらに学ぶ** - * [キーマップ](ja/keymap.md) - * [カスタム関数とキーコード](ja/custom_quantum_functions.md) - * マクロ - * [動的マクロ](ja/feature_dynamic_macros.md) - * [コンパイル済みのマクロ](ja/feature_macros.md) - * [タップダンス](ja/feature_tap_dance.md) - * [コンボ](ja/feature_combo.md) - * [ユーザスペース](ja/feature_userspace.md) - * [キーオーバーライド](ja/feature_key_overrides.md) - -# 上級トピック - -以下の全ては多くの基礎知識を必要とします。高度な機能を使ってキーマップを作成できることに加えて、`config.h` と `rules.mk` の両方を使ってキーボードのオプションを設定することに慣れている必要があります。 - -* **QMK 内のキーボードの保守** - * [キーボードの手配線](ja/hand_wire.md) - * [キーボードガイドライン](ja/hardware_keyboard_guidelines.md) - * [info.json リファレンス](ja/reference_info_json.md) - * [デバウンス API](ja/feature_debounce_type.md) -* **高度な機能** - * [ユニコード](ja/feature_unicode.md) - * [API](ja/api_overview.md) - * [ブートマジックライト](ja/feature_bootmagic.md) -* **ハードウェア** - * [キーボードがどのように動作するか](ja/how_keyboards_work.md) - * [キーボードマトリックスの仕組み](ja/how_a_matrix_works.md) - * [分割キーボード](ja/feature_split_keyboard.md) - * [速記](ja/feature_stenography.md) - * [ポインティングデバイス](ja/feature_pointing_device.md) -* **コア開発** - * [コーディング規約](ja/coding_conventions_c.md) - * [互換性のあるマイクロコントローラ](ja/compatible_microcontrollers.md) - * [カスタムマトリックス](ja/custom_matrix.md) - * [QMK を理解する](ja/understanding_qmk.md) -* **CLI 開発** - * [コーディング規約](ja/coding_conventions_python.md) - * [CLI 開発の概要](ja/cli_development.md) diff --git a/docs/ja/tap_hold.md b/docs/ja/tap_hold.md deleted file mode 100644 index 00b80c8b22ca..000000000000 --- a/docs/ja/tap_hold.md +++ /dev/null @@ -1,167 +0,0 @@ -# タップホールド設定オプション - - - -タップホールドオプションは素晴らしいものですが、問題が無いわけではありません。デフォルト設定を適切なものにしようとしましたが、一部の人にとってまだ問題を引き起こすかもしれません。 - -次のオプションによりタップホールドキーの挙動を変更することができます。 - -## タッピング時間 - -以下の機能の全ての核心は、タッピング時間の設定です。これにより、何をタップとし、何をホールドとするかが決まります。これが自然に感じられるぴったりのタイミングは、キーボードごと、スイッチごと、あるいはキーごとに異ることもありえます。 - -`config.h` に以下の設定を追加することで、この時間を全体的に設定することができます: - -```c -#define TAPPING_TERM 200 -``` - -この設定はミリ秒で定義され、デフォルトは 200ms です。これは大多数の人にとっての適切な平均値です。 - -この機能をより細かく制御するために、以下を `config.h` に追加することができます: -```c -#define TAPPING_TERM_PER_KEY -``` - -そして、以下の関数をキーマップに追加します: - -```c -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return TAPPING_TERM + 1250; - case LT(1, KC_GRV): - return 130; - default: - return TAPPING_TERM; - } -} -``` - - -## 許容ホールド - -[PR#1359](https://github.com/qmk/qmk_firmware/pull/1359/) 以降、新しい `config.h` オプションがあります: - -```c -#define PERMISSIVE_HOLD -``` - -これは高速なタイピストや高い `TAPPING_TERM` 設定に対して、タップとホールドキー(モッドタップのような)の動作を向上させます。 - -モッドタップキーを押し、他のキーをタップ(押して放す)して、モッドタップキーを放すという動作の全てをタッピング時間内に行うと、両方のキーのタッピング機能が出力されます。 - -例えば: - -- `SFT_T(KC_A)` を押す -- `KC_X` を押す -- `KC_X` を放す -- `SFT_T(KC_A)` を放す - -通常、これら全てを `TAPPING_TERM` (デフォルト: 200ms) 内で行うと、ファームウェアとホストシステムによって `ax` として登録されます。許容ホールドを有効にすると、別のキーがタップされた場合にモッドタップキーを修飾キーと見なすように処理を変更し、 `X` (`SHIFT`+`x`) と登録されます。 - -この機能をより細かく制御するために、以下を `config.h` に追加することができます: - -```c -#define PERMISSIVE_HOLD_PER_KEY -``` - -そして、以下の関数をキーマップに追加します: - -```c -bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(1, KC_BSPC): - return true; - default: - return false; - } -} -``` - -## タッピング強制ホールド - -`タッピング強制ホールド` を有効にするには、以下を `config.h` に追加します: - -```c -#define TAPPING_FORCE_HOLD -``` - -タップの後でユーザがキーをホールドすると、ホールド機能がアクティブになるのではなく、デフォルトでタッピング機能が繰り返されます。これにより、デュアルロールキーのタッピング機能を自動繰り返しする機能を維持することができます。`TAPPING_FORCE_HOLD` は、デュアルロールキーをタップした後ホールドした場合、ユーザがホールド機能をアクティブにする機能を削除します。 - -例: - -- `SFT_T(KC_A)` を押す -- `SFT_T(KC_A)` を放す -- `SFT_T(KC_A)` を押す -- タッピング時間が終了するまで待ちます... -- `SFT_T(KC_A)` を放す - -デフォルトの設定では、最初に放したときに `a` が送信され、2回目の押下で `a` が送信され、コンピュータに自動リピート機能を作動させることができます。 - -`TAPPING_FORCE_HOLD` を使うと、2回目の押下は Shift として解釈され、それをタップして使った後ですぐに修飾キーとして使うことができます。 - -!> `TAPPING_FORCE_HOLD` はタッピングトグル(`TT` レイヤーキーコード、ワンショットタップトグルなど)を使うものをすべて破壊します。 - -この機能をより細かく制御するために、以下を `config.h` に追加することができます: - -```c -#define TAPPING_FORCE_HOLD_PER_KEY -``` - -そして、以下の関数をキーマップに追加します: - -```c -bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(1, KC_BSPC): - return true; - default: - return false; - } -} -``` - -## レトロタッピング - -`レトロタッピング`を有効にするには、以下を `config.h` に追加してください: - -```c -#define RETRO_TAPPING -``` - -他のキーを押さずにデュアルファンクションキーを押して放しても何も起こりません。レトロタッピングを有効にすると、他のキーを押さずにキーを放すと、元のキーコードがタッピング時間外であっても送信されます。 - -例えば、他のキーを押すことなく `LT(2, KC_SPACE)` を押したり放したりしても何も起こりません。これを有効にすると、代わりに `KC_SPACE` を送信します。 - -この機能をより細かく制御するために、以下を `config.h` に追加することができます: - -```c -#define RETRO_TAPPING_PER_KEY -``` - -そして、以下の関数をキーマップに追加します: - -```c -bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(2, KC_SPACE): - return true; - default: - return false; - } -} -``` - -## キー別の関数にキーレコードを含めるのはなぜですか? - -「キー別」の関数全てにキーレコードを含んでいることに気付いたかもしれません。そしてなぜそうしたのか不思議に思っているかもしれません。 - -まぁ、それは単純に本当にカスタマイズのためです。ただし、具体的には、それはキーボードの配線方法によって異なります。例えば、各行が実際にキーボードのマトリックスの1行を使っている場合、キーコード全体をチェックする代わりに、`if (record->event.row == 3)` を使うほうが簡単かもしれません。これは、ホームキー行でタップホールドタイプのキーを使っている人にとって特に便利です。そのため、通常のタイピングを妨げないように微調整することができるのではないでしょうか。 - -## `*_kb` や `*_user` 関数が無いのはなぜですか? - -QMK にある他の多くの関数とは異なり、quantum あるいはキーボードレベルの関数を持つ必要はありません (または理由さえありません)。ここではユーザレベルの関数だけが有用なため、そのようにマークする必要はありません。 diff --git a/docs/ja/translating.md b/docs/ja/translating.md deleted file mode 100644 index f7a273308a64..000000000000 --- a/docs/ja/translating.md +++ /dev/null @@ -1,60 +0,0 @@ -# QMK ドキュメントを翻訳する - - - -ルートフォルダ (`docs/`) にある全てのファイルは英語でなければなりません - 他の全ての言語は、ISO 639-1 言語コードと、それに続く`-`と関連する国コードのサブフォルダにある必要があります。[一般的なもののリストはここで見つかります](https://www.andiamo.co.uk/resources/iso-language-codes/)。このフォルダが存在しない場合、作成することができます。翻訳された各ファイルは英語バージョンと同じ名前でなければなりません。そうすることで、正常にフォールバックできます。 - -`_summary.md` ファイルはこのフォルダの中に存在し、各ファイルへのリンクのリスト、翻訳された名前、言語フォルダに続くリンクが含まれている必要があります。 - -```markdown - * [QMK简介](zh-cn/getting_started_introduction.md) -``` - -他の docs ページへの全てのリンクにも、言語のフォルダが前に付いている必要があります。もしリンクがページの特定の部分(例えば、特定の見出し)への場合、以下のように見出しに英語の ID を使う必要があります: - -```markdown -[建立你的环境](zh-cn/newbs-getting-started.md#set-up-your-environment) - -## 建立你的环境 :id=set-up-your-environment -``` - -新しい言語の翻訳が完了したら、以下のファイルも修正する必要があります: - -* [`docs/_langs.md`](https://github.com/qmk/qmk_firmware/blob/master/docs/_langs.md) -各行は、[GitHub emoji shortcode](https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#country-flag) の形式で国フラグと、それに続く言語で表される名前を含む必要があります。 - - ```markdown - - [:cn: 中文](/zh-cn/) - ``` - -* [`docs/index.html`](https://github.com/qmk/qmk_firmware/blob/master/docs/index.html) -`placeholder` と `noData` の両方のオブジェクトは、文字列で言語フォルダの辞書エントリが必要です: - - ```js - '/zh-cn/': '没有结果!', - ``` - - サイドバーの「QMK ファームウェア」の見出しリンクを設定するために、`nameLink` オブジェクトも以下のように追加される必要があります: - - ```js - '/zh-cn/': '/#/zh-cn/', - ``` - - また、`fallbackLanguages` リストに言語フォルダを追加して、404 ではなく英語に適切にフォールバックするようにしてください: - - ```js - fallbackLanguages: [ - // ... - 'zh-cn', - // ... - ], - ``` - -## 翻訳のプレビュー - -ドキュメントのローカルインスタンスをセットアップする方法については、[ドキュメントのプレビュー](ja/contributing.md#previewing-the-documentation)を見てください - 右上の "Translations" メニューから新しい言語を選択することができるはずです。 - -作業に満足したら、遠慮なくプルリクエストを開いてください! diff --git a/docs/ja/understanding_qmk.md b/docs/ja/understanding_qmk.md deleted file mode 100644 index 0e8c99e6929f..000000000000 --- a/docs/ja/understanding_qmk.md +++ /dev/null @@ -1,190 +0,0 @@ -# QMK のコードの理解 - - - -このドキュメントでは、QMK ファームウェアがどのように機能するかを非常に高いレベルから説明しようとしています。基本的なプログラミングの概念を理解していることを前提としていますが、(実例を示す必要がある場合を除き) C に精通していることを前提にはしていません。以下のドキュメントの基本的な知識があることを前提としています。 - -* [入門](ja/getting_started_introduction.md) -* [キーボードがどのように動作するか](ja/how_keyboards_work.md) -* [FAQ](ja/faq_general.md) - -## スタートアップ - -QMK は他のコンピュータプログラムと何ら変わりないと考えることができます。開始され、タスクを実行し、そして終了します。プログラムのエントリーポイントは、他の C プログラムと同様に、`main()` 関数です。ただし、QMK を初めて触る人は、`main()` 関数が複数の場所に現れるため、混乱するかもしれません。また、どれを見ればよいか分かりにくいかもしれません。 - -複数ある理由は、QMK は様々なプラットフォームをサポートするからです。最も一般的なプラットフォームは `lufa` です。これは atmega32u4 のような AVR プロセッサ上で実行されます。また、`chibios` および `vusb` もサポートします。 - -ここでは AVR プロセッサに焦点を当てます。これは `lufa` プラットフォームを使います。`main()` 関数は [tmk_core/protocol/lufa/lufa.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1028) にあります。関数にざっと目を通すと、(ホストへの USB も含めて)設定された全てのハードウェアが初期化され、プログラムのコア部分が [`while(1)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/protocol/lufa/lufa.c#L1069) で開始されることが分かります。これが[メインループ](#the-main-loop)です。 - -## メインループ - -コードのこの部分は、同じ命令セットを永久にループ処理するため、「メインループ」と呼ばれます。ここはキーボードに必要なことを実行させる関数を QMK が呼び出す場所です。一見、多くの機能を持つように見えるかもしれませんが、大抵の場合、コードは `#define` によって無効にされます。 - -``` - keyboard_task(); -``` - -ここで、全てのキーボードの固有の機能が実行されます。`keyboard_task()` のソースコードは [tmk_core/common/keyboard.c](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/keyboard.c#L216) にあり、マトリックスの変化を検知し、LED の状態をオンオフする責任があります。 - -`keyboard_task()` に以下を処理するコードがあります: - -* [マトリックスのスキャン](#matrix-scanning) -* マウスの処理 -* シリアルリンク -* ビジュアライザ -* キーボードの状態の LED (Caps Lock, Num Lock, Scroll Lock) - -#### マトリックスのスキャン - -マトリックスのスキャンはキーボードファームウェアのコアの機能です。これは今どのキーが押されているかを検知するプロセスであり、キーボードはこの機能を1秒間に何度も何度も実行します。ファームウェアの CPU 時間の 99% はマトリックスのスキャンに費やされていると言っても過言ではありません。 - -実際のマトリックスの検知には様々な方法がありますが、それはこのドキュメントの対象外です。マトリックスのスキャンをブラックボックスとして扱っても問題ありません。マトリックスの現在の状態を求めると、以下のようなデータ構造を取得します: - - -``` -{ - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -これは 4行x5列のテンキー(訳注: 5行x4列の間違いと思われます)のマトリックスを表す直接的な表現のデータ構造です。キーが押されると、マトリックス内のそのキーの位置が、 `0` ではなく `1` として返されます。 - -マトリックスのスキャンは1秒間に何度も実行されます。正確なレートは様々ですが、知覚できるような遅延を避けるために、秒間に少なくとも10回実行します。 - -##### マトリックスから物理的なレイアウトへのマップ - -キーボード上の各スイッチの状態が分かると、それをキーコードへマップする必要があります。QMK ではキーコードへのマップは C マクロを使うことで行われ、C マクロにより物理的なレイアウトの定義はキーコードの定義から分離されています。(訳注:「キーコードの定義」は「キーコードのマトリクス配列による定義」と思われる) - -キーボードレベルで、キーボードのマトリックスを物理キーにマップする C マクロ (一般的には、`LAYOUT()` という名前)を定義します。マトリックスにスイッチがない場所がある場合、このマクロを使って KC_NO を事前に埋め込むことができ、キーマップの定義を扱いやすくすることができます。以下は、テンキー用の `LAYOUT()` マクロです: - -```c -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ -) { \ - { k00, k01, k02, k03, }, \ - { k10, k11, k12, k13, }, \ - { k20, k21, k22, KC_NO, }, \ - { k30, k31, k32, k33, }, \ - { k40, KC_NO, k42, KC_NO } \ -} -``` - -`LAYOUT()` マクロの2つ目のブロックが、上記のマトリックススキャン配列とどのように一致しているかに注目してください。このマクロはマトリックスのスキャン配列をキーコードにマップするものです。ただし、17キーのテンキーを見ると、マトリックスにはスイッチが置けるが、キーが大きいために実際にはスイッチが無い箇所が3つあることが分かります。これらのスペースに `KC_NO` を設定したので、キーマップ定義には必要ありません。 - -このマクロを使って、少し変わったマトリックスのレイアウト、例えば [Clueboard rev 2](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/66/rev2/rev2.h) を扱うこともできます。その説明はこのドキュメントの範囲外です。 - -##### キーコードの割り当て - -キーマップレべルでは、上記の `LAYOUT()` マクロを使って、物理的な場所からマトリックスの場所にマッピングします。以下のようになります: - -``` -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { -[0] = LAYOUT( - KC_NUM, KC_PSLS, KC_PAST, KC_PMNS, \ - KC_P7, KC_P8, KC_P9, KC_PPLS, \ - KC_P4, KC_P5, KC_P6, \ - KC_P1, KC_P2, KC_P3, KC_PENT, \ - KC_P0, KC_PDOT) -} -``` - -これら全ての引数が、前のセクションの `LAYOUT()` マクロの前半とどのように一致しているかについて注目してください。このようにして、キーコードを取得して、それを前述のマトリックススキャンにマップします。 - -##### 状態変更の検知 - -上記のマトリックススキャンはある時点のマトリックスの状態を伝えますが、コンピュータは変更のみを知りたいだけで、現在の状態を気にしません。QMK は最後のマトリックススキャンの結果を格納し、このマトリックスから結果を比較して、いつキーが押されたか放されたかを決定します。 - -例を見てみましょう。キーボードスキャンループの途中に移動して、前のスキャンが以下のようになっていることがわかったとします: - -``` -{ - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -現在のスキャンが完了すると、以下のように見えるとします: - -``` -{ - {1,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -キーマップと比較すると、押されたキーが KC_NUM であることが分かります。ここから、`process_record` 関数群を呼び出します。 - - - -##### Process Record - -`process_record()` 関数自体は一見簡単に見えますが、その内部は QMK の様々なレベルで機能を上書きするためのゲートウェイが隠されています。キーボード/キーマップレベルの機能について調べる必要があるときは、以下に列挙した一連のイベントを手引帳として使います。`rules.mk` またはほかの場所で設定されたオプションに応じて、最終的なファームウェアに以下の関数のサブセットのみが含まれます。 - -* [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/tmk_core/common/action.c#L172) - * [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L206) - * [このレコードをキーコードにマップする](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L226) - * [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/c1c5922aae7b60b7c7d13d3769350eed9dda17ab/quantum/velocikey.c#L27) - * [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L119) - * [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_key_lock.c#L62) - * [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_clicky.c#L79) - * [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/2cee371bf125a6ec541dd7c5a809573facc7c456/drivers/haptic/haptic.c#L216) - * [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/card.c#L20) - * [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/keyboards/clueboard/card/keymaps/default/keymap.c#L58) - * [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_midi.c#L81) - * [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_audio.c#L19) - * [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_steno.c#L160) - * [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_music.c#L114) - * [`bool process_key_override(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/5a1b857dea45a17698f6baa7dd1b7a7ea907fb0a/quantum/process_keycode/process_key_override.c#L397) - * [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_tap_dance.c#L141) - * [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode_common.c#L169) は、以下のいずれかを呼び出します: - * [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicode.c#L20) - * [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_unicodemap.c#L46) - * [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_ucis.c#L95) - * [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_leader.c#L51) - * [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_combo.c#L115) - * [`bool process_printer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_printer.c#L77) - * [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/process_keycode/process_auto_shift.c#L94) - * [Quantum 固有のキーコードを識別して処理する](https://github.com/qmk/qmk_firmware/blob/e1203a222bb12ab9733916164a000ef3ac48da93/quantum/quantum.c#L291) - -この一連のイベントの中の任意のステップで (`process_record_kb()` のような)関数は `false` を返して、以降の処理を停止することができます。 - -この呼び出しの後で、`post_process_record()` が呼ばれます。これはキーコードが通常処理された後に実行する必要がある追加のクリーンアップを処理するために使うことができます。 - -* [`void post_process_record(keyrecord_t *record)`]() - * [`void post_process_record_quantum(keyrecord_t *record)`]() - * [このレコードをキーコードにマップする]() - * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]() - * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]() - * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]() - - diff --git a/docs/keycodes.md b/docs/keycodes.md index e5b6246af794..65762234a448 100644 --- a/docs/keycodes.md +++ b/docs/keycodes.md @@ -848,8 +848,8 @@ See also: [Unicode Support](feature_unicode.md) |Key |Aliases |Description | |----------------------------|---------|----------------------------------------------------------------| |`UC(c)` | |Send Unicode code point `c`, up to `0x7FFF` | -|`X(i)` | |Send Unicode code point at index `i` in `unicode_map` | -|`XP(i, j)` | |Send Unicode code point at index `i`, or `j` if Shift/Caps is on| +|`UM(i)` | |Send Unicode code point at index `i` in `unicode_map` | +|`UP(i, j)` | |Send Unicode code point at index `i`, or `j` if Shift/Caps is on| |`QK_UNICODE_MODE_NEXT` |`UC_NEXT`|Cycle through selected input modes | |`QK_UNICODE_MODE_PREVIOUS` |`UC_PREV`|Cycle through selected input modes in reverse | |`QK_UNICODE_MODE_MACOS` |`UC_MAC` |Switch to macOS input | diff --git a/docs/keycodes_basic.md b/docs/keycodes_basic.md deleted file mode 100644 index c95accd79edf..000000000000 --- a/docs/keycodes_basic.md +++ /dev/null @@ -1,260 +0,0 @@ -# Basic Keycodes - -The basic set of keycodes are based on the [HID Keyboard/Keypad Usage Page (0x07)](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) with the exception of `KC_NO`, `KC_TRNS` and keycodes in the `0xA5-DF` range. See below for more details. - -## Letters and Numbers - -|Key |Description| -|------|-----------| -|`KC_A`|`a` and `A`| -|`KC_B`|`b` and `B`| -|`KC_C`|`c` and `C`| -|`KC_D`|`d` and `D`| -|`KC_E`|`e` and `E`| -|`KC_F`|`f` and `F`| -|`KC_G`|`g` and `G`| -|`KC_H`|`h` and `H`| -|`KC_I`|`i` and `I`| -|`KC_J`|`j` and `J`| -|`KC_K`|`k` and `K`| -|`KC_L`|`l` and `L`| -|`KC_M`|`m` and `M`| -|`KC_N`|`n` and `N`| -|`KC_O`|`o` and `O`| -|`KC_P`|`p` and `P`| -|`KC_Q`|`q` and `Q`| -|`KC_R`|`r` and `R`| -|`KC_S`|`s` and `S`| -|`KC_T`|`t` and `T`| -|`KC_U`|`u` and `U`| -|`KC_V`|`v` and `V`| -|`KC_W`|`w` and `W`| -|`KC_X`|`x` and `X`| -|`KC_Y`|`y` and `Y`| -|`KC_Z`|`z` and `Z`| -|`KC_1`|`1` and `!`| -|`KC_2`|`2` and `@`| -|`KC_3`|`3` and `#`| -|`KC_4`|`4` and `$`| -|`KC_5`|`5` and `%`| -|`KC_6`|`6` and `^`| -|`KC_7`|`7` and `&`| -|`KC_8`|`8` and `*`| -|`KC_9`|`9` and `(`| -|`KC_0`|`0` and `)`| - -## F Keys - -|Key |Description| -|--------|-----------| -|`KC_F1` |F1 | -|`KC_F2` |F2 | -|`KC_F3` |F3 | -|`KC_F4` |F4 | -|`KC_F5` |F5 | -|`KC_F6` |F6 | -|`KC_F7` |F7 | -|`KC_F8` |F8 | -|`KC_F9` |F9 | -|`KC_F10`|F10 | -|`KC_F11`|F11 | -|`KC_F12`|F12 | -|`KC_F13`|F13 | -|`KC_F14`|F14 | -|`KC_F15`|F15 | -|`KC_F16`|F16 | -|`KC_F17`|F17 | -|`KC_F18`|F18 | -|`KC_F19`|F19 | -|`KC_F20`|F20 | -|`KC_F21`|F21 | -|`KC_F22`|F22 | -|`KC_F23`|F23 | -|`KC_F24`|F24 | - -## Punctuation - -|Key |Aliases |Description | -|--------------------|---------|--------------------------| -|`KC_ENTER` |`KC_ENT` |Return (Enter) | -|`KC_ESCAPE` |`KC_ESC` |Escape | -|`KC_BACKSPACE` |`KC_BSPC`|Delete (Backspace) | -|`KC_TAB` | |Tab | -|`KC_SPACE` |`KC_SPC` |Spacebar | -|`KC_MINUS` |`KC_MINS`|`-` and `_` | -|`KC_EQUAL` |`KC_EQL` |`=` and `+` | -|`KC_LEFT_BRACKET` |`KC_LBRC`|`[` and `{` | -|`KC_RIGHT_BRACKET` |`KC_RBRC`|`]` and `}` | -|`KC_BACKSLASH` |`KC_BSLS`|`\` and `\|` | -|`KC_NONUS_HASH` |`KC_NUHS`|Non-US `#` and `~` | -|`KC_SEMICOLON` |`KC_SCLN`|`;` and `:` | -|`KC_QUOTE` |`KC_QUOT`|`'` and `"` | -|`KC_GRAVE` |`KC_GRV` |` and `~`| -|`KC_COMMA` |`KC_COMM`|`,` and `<` | -|`KC_DOT` | |`.` and `>` | -|`KC_SLASH` |`KC_SLSH`|`/` and `?` | -|`KC_NONUS_BACKSLASH`|`KC_NUBS`|Non-US `\` and `\|` | - -## Lock Keys - -|Key |Aliases |Description | -|------------------------|--------------------|------------------------------------| -|`KC_CAPS_LOCK` |`KC_CAPS` |Caps Lock | -|`KC_SCROLL_LOCK` |`KC_SCRL`, `KC_BRMD`|Scroll Lock, Brightness Down (macOS)| -|`KC_NUM_LOCK` |`KC_NUM` |Keypad Num Lock and Clear | -|`KC_LOCKING_CAPS_LOCK` |`KC_LCAP` |Locking Caps Lock | -|`KC_LOCKING_NUM_LOCK` |`KC_LNUM` |Locking Num Lock | -|`KC_LOCKING_SCROLL_LOCK`|`KC_LSCR` |Locking Scroll Lock | - -## Modifiers - -|Key |Aliases |Description | -|----------------|-------------------------------|------------------------------------| -|`KC_LEFT_CTRL` |`KC_LCTL` |Left Control | -|`KC_LEFT_SHIFT` |`KC_LSFT` |Left Shift | -|`KC_LEFT_ALT` |`KC_LALT`, `KC_LOPT` |Left Alt (Option) | -|`KC_LEFT_GUI` |`KC_LGUI`, `KC_LCMD`, `KC_LWIN`|Left GUI (Windows/Command/Meta key) | -|`KC_RIGHT_CTRL` |`KC_RCTL` |Right Control | -|`KC_RIGHT_SHIFT`|`KC_RSFT` |Right Shift | -|`KC_RIGHT_ALT` |`KC_RALT`, `KC_ROPT`, `KC_ALGR`|Right Alt (Option/AltGr) | -|`KC_RIGHT_GUI` |`KC_RGUI`, `KC_RCMD`, `KC_RWIN`|Right GUI (Windows/Command/Meta key)| - -## International - -|Key |Aliases |Description | -|--------------------|---------|---------------------| -|`KC_INTERNATIONAL_1`|`KC_INT1`|JIS `\` and `_` | -|`KC_INTERNATIONAL_2`|`KC_INT2`|JIS Katakana/Hiragana| -|`KC_INTERNATIONAL_3`|`KC_INT3`|JIS `¥` and `\|` | -|`KC_INTERNATIONAL_4`|`KC_INT4`|JIS Henkan | -|`KC_INTERNATIONAL_5`|`KC_INT5`|JIS Muhenkan | -|`KC_INTERNATIONAL_6`|`KC_INT6`|JIS Numpad `,` | -|`KC_INTERNATIONAL_7`|`KC_INT7`|International 7 | -|`KC_INTERNATIONAL_8`|`KC_INT8`|International 8 | -|`KC_INTERNATIONAL_9`|`KC_INT9`|International 9 | -|`KC_LANGUAGE_1` |`KC_LNG1`|Hangul/English | -|`KC_LANGUAGE_2` |`KC_LNG2`|Hanja | -|`KC_LANGUAGE_3` |`KC_LNG3`|JIS Katakana | -|`KC_LANGUAGE_4` |`KC_LNG4`|JIS Hiragana | -|`KC_LANGUAGE_5` |`KC_LNG5`|JIS Zenkaku/Hankaku | -|`KC_LANGUAGE_6` |`KC_LNG6`|Language 6 | -|`KC_LANGUAGE_7` |`KC_LNG7`|Language 7 | -|`KC_LANGUAGE_8` |`KC_LNG8`|Language 8 | -|`KC_LANGUAGE_9` |`KC_LNG9`|Language 9 | - -## Commands - -|Key |Aliases |Description | -|--------------------|------------------------------|--------------------------------------| -|`KC_PRINT_SCREEN` |`KC_PSCR` |Print Screen | -|`KC_PAUSE` |`KC_PAUS`, `KC_BRK`, `KC_BRMU`|Pause, Brightness Up (macOS) | -|`KC_INSERT` |`KC_INS` |Insert | -|`KC_HOME` | |Home | -|`KC_PAGE_UP` |`KC_PGUP` |Page Up | -|`KC_DELETE` |`KC_DEL` |Forward Delete | -|`KC_END` | |End | -|`KC_PAGE_DOWN` |`KC_PGDN` |Page Down | -|`KC_RIGHT` |`KC_RGHT` |Right Arrow | -|`KC_LEFT` | |Left Arrow | -|`KC_DOWN` | |Down Arrow | -|`KC_UP` | |Up Arrow | -|`KC_APPLICATION` |`KC_APP` |Application (Windows Context Menu Key)| -|`KC_KB_POWER` | |System Power | -|`KC_EXECUTE` |`KC_EXEC` |Execute | -|`KC_HELP` | |Help | -|`KC_MENU` | |Menu | -|`KC_SELECT` |`KC_SLCT` |Select | -|`KC_STOP` | |Stop | -|`KC_AGAIN` |`KC_AGIN` |Again | -|`KC_UNDO` | |Undo | -|`KC_CUT` | |Cut | -|`KC_COPY` | |Copy | -|`KC_PASTE` |`KC_PSTE` |Paste | -|`KC_FIND` | |Find | -|`KC_KB_MUTE` | |Mute | -|`KC_KB_VOLUME_UP` | |Volume Up | -|`KC_KB_VOLUME_DOWN` | |Volume Down | -|`KC_ALTERNATE_ERASE`|`KC_ERAS` |Alternate Erase | -|`KC_SYSTEM_REQUEST` |`KC_SYRQ` |SysReq/Attention | -|`KC_CANCEL` |`KC_CNCL` |Cancel | -|`KC_CLEAR` |`KC_CLR` |Clear | -|`KC_PRIOR` |`KC_PRIR` |Prior | -|`KC_RETURN` |`KC_RETN` |Return | -|`KC_SEPARATOR` |`KC_SEPR` |Separator | -|`KC_OUT` | |Out | -|`KC_OPER` | |Oper | -|`KC_CLEAR_AGAIN` |`KC_CLAG` |Clear/Again | -|`KC_CRSEL` |`KC_CRSL` |CrSel/Props | -|`KC_EXSEL` |`KC_EXSL` |ExSel | - -## Media Keys - -These keycodes are not part of the Keyboard/Keypad usage page. The `SYSTEM_` keycodes are found in the Generic Desktop page, and the rest are located in the Consumer page. - -?> Some of these keycodes may behave differently depending on the OS. For example, on macOS, the keycodes `KC_MEDIA_FAST_FORWARD`, `KC_MEDIA_REWIND`, `KC_MEDIA_NEXT_TRACK` and `KC_MEDIA_PREV_TRACK` skip within the current track when held, but skip the entire track when tapped. - -|Key |Aliases |Description | -|-----------------------|---------|--------------------| -|`KC_SYSTEM_POWER` |`KC_PWR` |System Power Down | -|`KC_SYSTEM_SLEEP` |`KC_SLEP`|System Sleep | -|`KC_SYSTEM_WAKE` |`KC_WAKE`|System Wake | -|`KC_AUDIO_MUTE` |`KC_MUTE`|Mute | -|`KC_AUDIO_VOL_UP` |`KC_VOLU`|Volume Up | -|`KC_AUDIO_VOL_DOWN` |`KC_VOLD`|Volume Down | -|`KC_MEDIA_NEXT_TRACK` |`KC_MNXT`|Next Track | -|`KC_MEDIA_PREV_TRACK` |`KC_MPRV`|Previous Track | -|`KC_MEDIA_STOP` |`KC_MSTP`|Stop Track | -|`KC_MEDIA_PLAY_PAUSE` |`KC_MPLY`|Play/Pause Track | -|`KC_MEDIA_SELECT` |`KC_MSEL`|Launch Media Player | -|`KC_MEDIA_EJECT` |`KC_EJCT`|Eject | -|`KC_MAIL` | |Launch Mail | -|`KC_CALCULATOR` |`KC_CALC`|Launch Calculator | -|`KC_MY_COMPUTER` |`KC_MYCM`|Launch My Computer | -|`KC_WWW_SEARCH` |`KC_WSCH`|Browser Search | -|`KC_WWW_HOME` |`KC_WHOM`|Browser Home | -|`KC_WWW_BACK` |`KC_WBAK`|Browser Back | -|`KC_WWW_FORWARD` |`KC_WFWD`|Browser Forward | -|`KC_WWW_STOP` |`KC_WSTP`|Browser Stop | -|`KC_WWW_REFRESH` |`KC_WREF`|Browser Refresh | -|`KC_WWW_FAVORITES` |`KC_WFAV`|Browser Favorites | -|`KC_MEDIA_FAST_FORWARD`|`KC_MFFD`|Next Track | -|`KC_MEDIA_REWIND` |`KC_MRWD`|Previous Track | -|`KC_BRIGHTNESS_UP` |`KC_BRIU`|Brightness Up | -|`KC_BRIGHTNESS_DOWN` |`KC_BRID`|Brightness Down | -|`KC_CONTROL_PANEL` |`KC_CPNL`|Open Control Panel | -|`KC_ASSISTANT` |`KC_ASST`|Launch Assistant | -|`KC_MISSION_CONTROL` |`KC_MCTL`|Open Mission Control| -|`KC_LAUNCHPAD` |`KC_LPAD`|Open Launchpad | - -## Number Pad - -|Key |Aliases |Description | -|-------------------|---------|------------------------------| -|`KC_KP_SLASH` |`KC_PSLS`|Keypad `/` | -|`KC_KP_ASTERISK` |`KC_PAST`|Keypad `*` | -|`KC_KP_MINUS` |`KC_PMNS`|Keypad `-` | -|`KC_KP_PLUS` |`KC_PPLS`|Keypad `+` | -|`KC_KP_ENTER` |`KC_PENT`|Keypad Enter | -|`KC_KP_1` |`KC_P1` |Keypad `1` and End | -|`KC_KP_2` |`KC_P2` |Keypad `2` and Down Arrow | -|`KC_KP_3` |`KC_P3` |Keypad `3` and Page Down | -|`KC_KP_4` |`KC_P4` |Keypad `4` and Left Arrow | -|`KC_KP_5` |`KC_P5` |Keypad `5` | -|`KC_KP_6` |`KC_P6` |Keypad `6` and Right Arrow | -|`KC_KP_7` |`KC_P7` |Keypad `7` and Home | -|`KC_KP_8` |`KC_P8` |Keypad `8` and Up Arrow | -|`KC_KP_9` |`KC_P9` |Keypad `9` and Page Up | -|`KC_KP_0` |`KC_P0` |Keypad `0` and Insert | -|`KC_KP_DOT` |`KC_PDOT`|Keypad `.` and Delete | -|`KC_KP_EQUAL` |`KC_PEQL`|Keypad `=` | -|`KC_KP_COMMA` |`KC_PCMM`|Keypad `,` | -|`KC_KP_EQUAL_AS400`| |Keypad `=` on AS/400 keyboards| - -## Special Keys - -In addition to these, keycodes in the range of `0xA5-DF` are reserved for internal use. - -|Key |Aliases |Description | -|----------------|--------------------|---------------------------------------| -|`KC_NO` |`XXXXXXX` |Ignore this key (NOOP) | -|`KC_TRANSPARENT`|`KC_TRNS`, `_______`|Use the next lowest non-transparent key| diff --git a/docs/keycodes_magic.md b/docs/keycodes_magic.md deleted file mode 100644 index 84706123456f..000000000000 --- a/docs/keycodes_magic.md +++ /dev/null @@ -1,41 +0,0 @@ -# Magic Keycodes :id=magic-keycodes - -**Magic Keycodes** are prefixed with `MAGIC_`, and allow you to access the functionality of the deprecated Bootmagic feature *after* your keyboard has initialized. To use the keycodes, assign them to your keymap as you would any other keycode. - -|Key |Aliases |Description | -|-------------------------------------|---------|--------------------------------------------------------------------------| -|`QK_MAGIC_SWAP_CONTROL_CAPS_LOCK` |`CL_SWAP`|Swap Caps Lock and Left Control | -|`QK_MAGIC_UNSWAP_CONTROL_CAPS_LOCK` |`CL_NORM`|Unswap Caps Lock and Left Control | -|`QK_MAGIC_TOGGLE_CONTROL_CAPS_LOCK` |`CL_TOGG`|Toggle Caps Lock and Left Control swap | -|`QK_MAGIC_CAPS_LOCK_AS_CONTROL_ON` |`CL_CTRL`|Treat Caps Lock as Control | -|`QK_MAGIC_CAPS_LOCK_AS_CONTROL_OFF` |`CL_CAPS`|Stop treating Caps Lock as Control | -|`QK_MAGIC_SWAP_ESCAPE_CAPS_LOCK` |`EC_SWAP`|Swap Caps Lock and Escape | -|`QK_MAGIC_UNSWAP_ESCAPE_CAPS_LOCK` |`EC_NORM`|Unswap Caps Lock and Escape | -|`QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK` |`EC_TOGG`|Toggle Caps Lock and Escape swap | -|`QK_MAGIC_SWAP_LCTL_LGUI` |`CG_LSWP`|Swap Left Control and GUI | -|`QK_MAGIC_UNSWAP_LCTL_LGUI` |`CG_LNRM`|Unswap Left Control and GUI | -|`QK_MAGIC_SWAP_RCTL_RGUI` |`CG_RSWP`|Swap Right Control and GUI | -|`QK_MAGIC_UNSWAP_RCTL_RGUI` |`CG_RNRM`|Unswap Right Control and GUI | -|`QK_MAGIC_SWAP_CTL_GUI` |`CG_SWAP`|Swap Control and GUI on both sides | -|`QK_MAGIC_UNSWAP_CTL_GUI` |`CG_NORM`|Unswap Control and GUI on both sides | -|`QK_MAGIC_TOGGLE_CTL_GUI` |`CG_TOGG`|Toggle Control and GUI swap on both sides | -|`QK_MAGIC_SWAP_LALT_LGUI` |`AG_LSWP`|Swap Left Alt and GUI | -|`QK_MAGIC_UNSWAP_LALT_LGUI` |`AG_LNRM`|Unswap Left Alt and GUI | -|`QK_MAGIC_SWAP_RALT_RGUI` |`AG_RSWP`|Swap Right Alt and GUI | -|`QK_MAGIC_UNSWAP_RALT_RGUI` |`AG_RNRM`|Unswap Right Alt and GUI | -|`QK_MAGIC_SWAP_ALT_GUI` |`AG_SWAP`|Swap Alt and GUI on both sides | -|`QK_MAGIC_UNSWAP_ALT_GUI` |`AG_NORM`|Unswap Alt and GUI on both sides | -|`QK_MAGIC_TOGGLE_ALT_GUI` |`AG_TOGG`|Toggle Alt and GUI swap on both sides | -|`QK_MAGIC_GUI_OFF` |`GU_OFF` |Disable the GUI keys | -|`QK_MAGIC_GUI_ON` |`GU_ON` |Enable the GUI keys | -|`QK_MAGIC_TOGGLE_GUI` |`GU_TOGG`|Toggles the status of the GUI keys | -|`QK_MAGIC_SWAP_GRAVE_ESC` |`GE_SWAP`|Swap ` and Escape | -|`QK_MAGIC_UNSWAP_GRAVE_ESC` |`GE_NORM`|Unswap ` and Escape | -|`QK_MAGIC_SWAP_BACKSLASH_BACKSPACE` |`BS_SWAP`|Swap `\` and Backspace | -|`QK_MAGIC_UNSWAP_BACKSLASH_BACKSPACE`|`BS_NORM`|Unswap `\` and Backspace | -|`QK_MAGIC_TOGGLE_BACKSLASH_BACKSPACE`|`BS_TOGG`|Toggle `\` and Backspace swap state | -|`QK_MAGIC_NKRO_ON` |`NK_ON` |Enable N-key rollover | -|`QK_MAGIC_NKRO_OFF` |`NK_OFF` |Disable N-key rollover | -|`QK_MAGIC_TOGGLE_NKRO` |`NK_TOGG`|Toggle N-key rollover | -|`QK_MAGIC_EE_HANDS_LEFT` |`EH_LEFT`|Set the master half of a split keyboard as the left hand (for `EE_HANDS`) | -|`QK_MAGIC_EE_HANDS_RIGHT` |`EH_RGHT`|Set the master half of a split keyboard as the right hand (for `EE_HANDS`)| diff --git a/docs/keycodes_us_ansi_shifted.md b/docs/keycodes_us_ansi_shifted.md deleted file mode 100644 index e9749b7b170b..000000000000 --- a/docs/keycodes_us_ansi_shifted.md +++ /dev/null @@ -1,37 +0,0 @@ -# US ANSI Shifted Symbols - -These keycodes correspond to characters that are "shifted" on a standard US ANSI keyboard. They do not have keycodes of their own but are simply shortcuts for `LSFT(kc)`, and as such send a Left Shift with the unshifted keycode, not the symbol itself. - -## Caveats - -Unfortunately, these keycodes cannot be used in Mod-Taps or Layer-Taps, since any modifiers specified in the keycode are ignored. - -Additionally, you may run into issues when using Remote Desktop Connection on Windows. Because these codes send shift very fast, Remote Desktop may miss the codes. - -To fix this, open Remote Desktop Connection, click on "Show Options", open the "Local Resources" tab. In the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly. - -## Keycodes - -|Key |Aliases |Description| -|------------------------|-------------------|-----------| -|`KC_TILDE` |`KC_TILD` |`~` | -|`KC_EXCLAIM` |`KC_EXLM` |`!` | -|`KC_AT` | |`@` | -|`KC_HASH` | |`#` | -|`KC_DOLLAR` |`KC_DLR` |`$` | -|`KC_PERCENT` |`KC_PERC` |`%` | -|`KC_CIRCUMFLEX` |`KC_CIRC` |`^` | -|`KC_AMPERSAND` |`KC_AMPR` |`&` | -|`KC_ASTERISK` |`KC_ASTR` |`*` | -|`KC_LEFT_PAREN` |`KC_LPRN` |`(` | -|`KC_RIGHT_PAREN` |`KC_RPRN` |`)` | -|`KC_UNDERSCORE` |`KC_UNDS` |`_` | -|`KC_PLUS` | |`+` | -|`KC_LEFT_CURLY_BRACE` |`KC_LCBR` |`{` | -|`KC_RIGHT_CURLY_BRACE` |`KC_RCBR` |`}` | -|`KC_PIPE` | |`\|` | -|`KC_COLON` |`KC_COLN` |`:` | -|`KC_DOUBLE_QUOTE` |`KC_DQUO`, `KC_DQT`|`"` | -|`KC_LEFT_ANGLE_BRACKET` |`KC_LABK`, `KC_LT` |`<` | -|`KC_RIGHT_ANGLE_BRACKET`|`KC_RABK`, `KC_GT` |`>` | -|`KC_QUESTION` |`KC_QUES` |`?` | diff --git a/docs/keymap.md b/docs/keymap.md deleted file mode 100644 index f9d45b32676c..000000000000 --- a/docs/keymap.md +++ /dev/null @@ -1,191 +0,0 @@ -# Keymap Overview - -QMK keymaps are defined inside a C source file. The data structure is an array of arrays. The outer array is a list of layer arrays while the inner layer array is a list of keys. Most keyboards define a `LAYOUT()` macro to help you create this array of arrays. - - -## Keymap and Layers :id=keymap-and-layers -In QMK, **`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`** holds multiple **layers** of keymap information in **16 bit** data holding the **action code**. You can define **32 layers** at most. - -For trivial key definitions, the higher 8 bits of the **action code** are all 0 and the lower 8 bits holds the USB HID usage code generated by the key as **keycode**. - -Respective layers can be validated simultaneously. Layers are indexed with 0 to 31 and higher layer has precedence. - - Keymap: 32 Layers Layer: action code matrix - ----------------- --------------------- - stack of layers array_of_action_code[row][column] - ____________ precedence _______________________ - / / | high / ESC / F1 / F2 / F3 .... - 31 /___________// | /-----/-----/-----/----- - 30 /___________// | / TAB / Q / W / E .... - 29 /___________/ | /-----/-----/-----/----- - : _:_:_:_:_:__ | : /LCtrl/ A / S / D .... - : / : : : : : / | : / : : : : - 2 /___________// | 2 `-------------------------- - 1 /___________// | 1 `-------------------------- - 0 /___________/ V low 0 `-------------------------- - - -Sometimes, the action code stored in keymap may be referred as keycode in some documents due to the TMK history. - -### Keymap Layer Status :id=keymap-layer-status - -The state of the Keymap layer is determined by two 32 bit parameters: - -* **`default_layer_state`** indicates a base keymap layer (0-31) which is always valid and to be referred (the default layer). -* **`layer_state`** has current on/off status of each layer in its bits. - -Keymap layer '0' is usually the `default_layer`, with other layers initially off after booting up the firmware, although this can configured differently in `config.h`. It is useful to change `default_layer` when you completely switch a key layout, for example, if you want to switch to Colemak instead of Qwerty. - - Initial state of Keymap Change base layout - ----------------------- ------------------ - - 31 31 - 30 30 - 29 29 - : : - : : ____________ - 2 ____________ 2 / / - 1 / / ,->1 /___________/ - ,->0 /___________/ | 0 - | | - `--- default_layer = 0 `--- default_layer = 1 - layer_state = 0x00000001 layer_state = 0x00000002 - -On the other hand, you can change `layer_state` to overlay the base layer with other layers for features such as navigation keys, function keys (F1-F12), media keys, and/or special actions. - - Overlay feature layer - --------------------- bit|status - ____________ ---+------ - 31 / / 31 | 0 - 30 /___________// -----> 30 | 1 - 29 /___________/ -----> 29 | 1 - : : | : - : ____________ : | : - 2 / / 2 | 0 - ,->1 /___________/ -----> 1 | 1 - | 0 0 | 0 - | + - `--- default_layer = 1 | - layer_state = 0x60000002 <-' - - - -### Layer Precedence and Transparency -Note that ***higher layers have higher priority within the stack of layers***. The firmware works its way down from the highest active layers to look up keycodes. Once the firmware locates a keycode other than `KC_TRNS` (transparent) on an active layer, it stops searching, and lower layers aren't referenced. - - ____________ - / / <--- Higher layer - / KC_TRNS // - /___________// <--- Lower layer (KC_A) - /___________/ - - In the above scenario, the non-transparent keys on the higher layer would be usable, but whenever `KC_TRNS` (or equivalent) is defined, the keycode (`KC_A`) on the lower level would be used. - -**Note:** Valid ways to denote transparency on a given layer: -* `KC_TRANSPARENT` -* `KC_TRNS` (alias) -* `_______` (alias) - -These keycodes allow the processing to fall through to lower layers in search of a non-transparent keycode to process. - -## Anatomy of a `keymap.c` - -For this example we will walk through an [older version of the default Clueboard 66% keymap](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c). You'll find it helpful to open that file in another browser window so you can look at everything in context. - -There are 2 main sections of a `keymap.c` file you'll want to concern yourself with: - -* [The Definitions](#definitions) -* [The Layer/Keymap Datastructure](#layers-and-keymaps) - -### Definitions - -At the top of the file you'll find this: - - #include QMK_KEYBOARD_H - - // Helpful defines - #define GRAVE_MODS (MOD_BIT(KC_LSFT)|MOD_BIT(KC_RSFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * You can use _______ in place for KC_TRNS (transparent) * - * Or you can use XXXXXXX for KC_NO (NOOP) * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - - // Each layer gets a name for readability. - // The underscores don't mean anything - you can - // have a layer called STUFF or any other name. - // Layer names don't all need to be of the same - // length, and you can also skip them entirely - // and just use numbers. - enum layer_names { - _BL, - _FL, - _CL, - }; - -These are some handy definitions we can use when building our keymap and our custom function. The `GRAVE_MODS` definition will be used later in our custom function, and the following `_BL`, `_FL`, and `_CL` defines make it easier to refer to each of our layers. - -Note: You may also find some older keymap files may also have a define(s) for `_______` and/or `XXXXXXX`. These can be used in place for `KC_TRNS` and `KC_NO` respectively, making it easier to see what keys a layer is overriding. These definitions are now unecessary, as they are included by default. - -### Layers and Keymaps - -The main part of this file is the `keymaps[]` definition. This is where you list your layers and the contents of those layers. This part of the file begins with this definition: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -After this you'll find the layer definitions. Typically you'll have one or more "base layers" (such as QWERTY, Dvorak, or Colemak) and then you'll layer on top of that one or more "function" layers. Due to the way layers are processed you can't overlay a "lower" layer on top of a "higher" layer. - -`keymaps[][MATRIX_ROWS][MATRIX_COLS]` in QMK holds the 16 bit action code (sometimes referred as the quantum keycode) in it. For the keycode representing typical keys, its high byte is 0 and its low byte is the USB HID usage ID for keyboard. - -> TMK from which QMK was forked uses `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` instead and holds the 8 bit keycode. - -#### Base Layer - -Here is an example of the Clueboard's base layer: - -```c -[_BL] = LAYOUT( - F(0), 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_GRV, KC_BSPC, KC_PGUP, - 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_PGDN, - 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_NUHS, KC_ENT, - KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_INT1, KC_RSFT, KC_UP, - KC_LCTL, KC_LGUI, KC_LALT, KC_INT5, KC_SPC,KC_SPC, KC_INT4, KC_RALT, KC_RCTL, MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT -), -``` - -Some interesting things to note about this: - -* The layer is defined using the LAYOUT macro, traditionally defined in the keyboard's `.h` file. -* The LAYOUT macro takes a single list of keycodes, but we have written it in the C source using embedded whitespace and newlines to visualize where each key is on the physical device. -* The LAYOUT macro hides and handles the mapping to the hardware's key scan matrix. -* Plain keyboard scancodes are prefixed with KC_, while "special" keys are not. -* The upper left key activates custom function 0 (`F(0)`) -* The "Fn" key is defined with `MO(_FL)`, which moves to the `_FL` layer while that key is being held down. - -#### Function Overlay Layer - -Our function layer is, from a code point of view, no different from the base layer. Conceptually, however, you will build that layer as an overlay, not a replacement. For many people this distinction does not matter, but as you build more complicated layering setups it matters more and more. - -```c -[_FL] = LAYOUT( - 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, BL_STEP, - _______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,KC_SCRL, KC_PAUS, _______, _______, _______, _______, - _______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, - _______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, - _______, _______, _______, _______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END -), -``` - -Some interesting things to note: - -* We have used our `_______` definition to turn `KC_TRNS` into `_______`. This makes it easier to spot the keys that have changed on this layer. -* While in this layer if you press one of the `_______` keys it will activate the key in the next lowest active layer. - -# Nitty Gritty Details - -This should have given you a basic overview for creating your own keymap. For more details see the following resources: - -* [Keycodes](keycodes.md) -* [Keymap FAQ](faq_keymap.md) - -We are actively working to improve these docs. If you have suggestions for how they could be made better please [file an issue](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/docs/mod_tap.md b/docs/mod_tap.md deleted file mode 100644 index 8b953d76b485..000000000000 --- a/docs/mod_tap.md +++ /dev/null @@ -1,135 +0,0 @@ -# Mod-Tap - -The Mod-Tap key `MT(mod, kc)` acts like a modifier when held, and a regular keycode when tapped. In other words, you can have a key that sends Escape when you tap it, but functions as a Control or Shift key when you hold it down. - -The modifiers this keycode and `OSM()` accept are prefixed with `MOD_`, not `KC_`: - -|Modifier |Description | -|----------|----------------------------------------| -|`MOD_LCTL`|Left Control | -|`MOD_LSFT`|Left Shift | -|`MOD_LALT`|Left Alt | -|`MOD_LGUI`|Left GUI (Windows/Command/Meta key) | -|`MOD_RCTL`|Right Control | -|`MOD_RSFT`|Right Shift | -|`MOD_RALT`|Right Alt (AltGr) | -|`MOD_RGUI`|Right GUI (Windows/Command/Meta key) | -|`MOD_HYPR`|Hyper (Left Control, Shift, Alt and GUI)| -|`MOD_MEH` |Meh (Left Control, Shift, and Alt) | - -You can combine these by ORing them together like so: - -```c -MT(MOD_LCTL | MOD_LSFT, KC_ESC) -``` - -This key would activate Left Control and Left Shift when held, and send Escape when tapped. - -For convenience, QMK includes some Mod-Tap shortcuts to make common combinations more compact in your keymap: - -|Key |Aliases |Description | -|------------|-----------------------------------------------------------------|--------------------------------------------------------------| -|`LCTL_T(kc)`|`CTL_T(kc)` |Left Control when held, `kc` when tapped | -|`LSFT_T(kc)`|`SFT_T(kc)` |Left Shift when held, `kc` when tapped | -|`LALT_T(kc)`|`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |Left Alt when held, `kc` when tapped | -|`LGUI_T(kc)`|`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|Left GUI when held, `kc` when tapped | -|`RCTL_T(kc)`| |Right Control when held, `kc` when tapped | -|`RSFT_T(kc)`| |Right Shift when held, `kc` when tapped | -|`RALT_T(kc)`|`ROPT_T(kc)`, `ALGR_T(kc)` |Right Alt when held, `kc` when tapped | -|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |Right GUI when held, `kc` when tapped | -|`LSG_T(kc)` |`SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` |Left Shift and GUI when held, `kc` when tapped | -|`LAG_T(kc)` | |Left Alt and GUI when held, `kc` when tapped | -|`RSG_T(kc)` | |Right Shift and GUI when held, `kc` when tapped | -|`RAG_T(kc)` | |Right Alt and GUI when held, `kc` when tapped | -|`LCA_T(kc)` | |Left Control and Alt when held, `kc` when tapped | -|`LSA_T(kc)` | |Left Shift and Alt when held, `kc` when tapped | -|`RSA_T(kc)` |`SAGR_T(kc)` |Right Shift and Right Alt (AltGr) when held, `kc` when tapped | -|`RCS_T(kc)` | |Right Control and Right Shift when held, `kc` when tapped | -|`LCAG_T(kc)`| |Left Control, Alt and GUI when held, `kc` when tapped | -|`RCAG_T(kc)`| |Right Control, Alt and GUI when held, `kc` when tapped | -|`C_S_T(kc)` | |Left Control and Shift when held, `kc` when tapped | -|`MEH_T(kc)` | |Left Control, Shift and Alt when held, `kc` when tapped | -|`HYPR_T(kc)`|`ALL_T(kc)` |Left Control, Shift, Alt and GUI when held, `kc` when tapped - more info [here](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)| - -## Caveats - -Currently, the `kc` argument of `MT()` is limited to the [Basic Keycode set](keycodes_basic.md), meaning you can't use keycodes like `LCTL()`, `KC_TILD`, or anything greater than `0xFF`. This is because QMK uses 16-bit keycodes, of which 3 bits are used for the function identifier, 1 bit for selecting right or left mods, and 4 bits to tell which mods are used, leaving only 8 bits for the keycode. Additionally, if at least one right-handed modifier is specified in a Mod-Tap, it will cause all modifiers specified to become right-handed, so it is not possible to mix and match the two - for example, Left Control and Right Shift would become Right Control and Right Shift. - -Expanding this would be complicated, at best. Moving to a 32-bit keycode would solve a lot of this, but would double the amount of space that the keymap matrix uses. And it could potentially cause issues, too. If you need to apply modifiers to your tapped keycode, [Tap Dance](feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) can be used to accomplish this. - -You may also run into issues when using Remote Desktop Connection on Windows. Because these keycodes send key events faster than a human, Remote Desktop could miss them. -To fix this, open Remote Desktop Connection, click on "Show Options", open the "Local Resources" tab, and in the keyboard section, change the drop down to "On this Computer". This will fix the issue, and allow the characters to work correctly. -It can also be mitigated by increasing [`TAP_CODE_DELAY`](config_options.md#behaviors-that-can-be-configured). - -## Intercepting Mod-Taps - -### Changing tap function - -The basic keycode limitation with Mod-Tap can be worked around by intercepting it in `process_record_user`. For example, shifted keycode `KC_DQUO` cannot be used with `MT()` because it is a 16-bit keycode alias of `LSFT(KC_QUOT)`. Modifiers on `KC_DQUO` will be masked by `MT()`. But the following custom code can be used to intercept the "tap" function to manually send `KC_DQUO`: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LCTL_T(KC_DQUO): - if (record->tap.count && record->event.pressed) { - tap_code16(KC_DQUO); // Send KC_DQUO on tap - return false; // Return false to ignore further processing of key - } - break; - } - return true; -} -``` - -### Changing hold function - -Likewise, similar custom code can also be used to intercept the hold function to send custom user key code. The following example uses `LT(0, kc)` (layer-tap key with no practical use because layer 0 is always active) to add cut, copy and paste function to X,C and V keys when they are held down: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(0,KC_X): - if (!record->tap.count && record->event.pressed) { - tap_code16(C(KC_X)); // Intercept hold function to send Ctrl-X - return false; - } - return true; // Return true for normal processing of tap keycode - case LT(0,KC_C): - if (!record->tap.count && record->event.pressed) { - tap_code16(C(KC_C)); // Intercept hold function to send Ctrl-C - return false; - } - return true; // Return true for normal processing of tap keycode - case LT(0,KC_V): - if (!record->tap.count && record->event.pressed) { - tap_code16(C(KC_V)); // Intercept hold function to send Ctrl-V - return false; - } - return true; // Return true for normal processing of tap keycode - } - return true; -} -``` - -### Changing both tap and hold - -This last example implements custom tap and hold function with `LT(0,KC_NO)` to create a single copy-on-tap, paste-on-hold key: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(0,KC_NO): - if (record->tap.count && record->event.pressed) { - tap_code16(C(KC_C)); // Intercept tap function to send Ctrl-C - } else if (record->event.pressed) { - tap_code16(C(KC_V)); // Intercept hold function to send Ctrl-V - } - return false; - } - return true; -} -``` - -## Other Resources - -See the [Tap-Hold Configuration Options](tap_hold.md) for additional flags that tweak Mod-Tap behavior. diff --git a/docs/newbs.md b/docs/newbs.md deleted file mode 100644 index 2763b2612272..000000000000 --- a/docs/newbs.md +++ /dev/null @@ -1,24 +0,0 @@ -# The QMK Tutorial - -Your computer keyboard has a processor inside of it, similar to the one inside your computer. This processor runs software that is responsible for detecting button presses and informing the computer when keys are pressed. QMK Firmware fills the role of that software, detecting button presses and passing that information on to the host computer. When you build your custom keymap, you are creating an executable program for your keyboard. - -QMK tries to put a lot of power into your hands by making easy things easy, and hard things possible. You don't have to know how to program to create powerful keymaps — you only have to follow a few simple syntax rules. - -Not sure if your keyboard can run QMK? If it's a mechanical keyboard you built yourself chances are good it can. We support a [large number of hobbyist boards](https://qmk.fm/keyboards/). If your current keyboard can't run QMK there are a lot of choices out there for boards that do. - -?> **Is This Guide For Me?**
-If the thought of programming intimidates you, please [take a look at our online GUI](newbs_building_firmware_configurator.md) instead. - -## Overview - -This guide is suitable for everyone who wants to build a keyboard firmware using the source code. If you are already a programmer you will find the process very familiar and easier to follow. There are 3 main sections to this guide: - -1. [Setup Your Environment](newbs_getting_started.md) -2. [Building Your First Firmware](newbs_building_firmware.md) -3. [Flashing Firmware](newbs_flashing.md) - -This guide is focused on helping someone who has never compiled software before. It makes choices and recommendations based on that viewpoint. There are alternative methods for many of these procedures, and we support most of those alternatives. If you have any doubt about how to accomplish a task you can [ask us for guidance](getting_started_getting_help.md). - -## Additional Resources - -Beyond this guide there are several resources you may find helpful while you learn QMK. We've collected them on the [Syllabus](syllabus.md) and [Learning Resources](newbs_learn_more_resources.md) pages. diff --git a/docs/newbs_building_firmware.md b/docs/newbs_building_firmware.md deleted file mode 100644 index de9217e9f0b7..000000000000 --- a/docs/newbs_building_firmware.md +++ /dev/null @@ -1,78 +0,0 @@ -# Building Your First Firmware - -Now that you have set up your build environment you are ready to start building custom firmware. For this section of the guide we will bounce between 3 programs- your file manager, your text editor, and your terminal window. Keep all 3 open until you are done and happy with your keyboard firmware. - -## Configure Your Build Environment Defaults (Optional) - -You can configure your build environment to set the defaults and make working with QMK less tedious. Let's do that now! - -Most people new to QMK only have 1 keyboard. You can set this keyboard as your default with the `qmk config` command. For example, to set your default keyboard to `clueboard/66/rev4`: - - qmk config user.keyboard=clueboard/66/rev4 - -?> The keyboard option is the path relative to the keyboard directory, the above example would be found in `qmk_firmware/keyboards/clueboard/66/rev4`. If you're unsure you can view a full list of supported keyboards with `qmk list-keyboards`. - -You can also set your default keymap name. Most people use their GitHub username like the keymap name from the previous steps: - - qmk config user.keymap= - -## Create a New Keymap - -To create your own keymap you'll want to create a copy of the `default` keymap. If you configured your build environment in the last step you can do that easily with the QMK CLI: - - qmk new-keymap - -If you did not configure your environment, or you have multiple keyboards, you can specify a keyboard name: - - qmk new-keymap -kb - -Look at the output from that command, you should see something like this: - - Ψ Created a new keymap called in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/. - -This is the location of your new `keymap.c` file. - -## Open `keymap.c` In Your Favorite Text Editor - -Open your `keymap.c` file in your text editor. Inside this file you'll find the structure that controls how your keyboard behaves. At the top of `keymap.c` there may be some defines and enums that make the keymap easier to read. Farther down you'll find a line that looks like this: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -This line indicates where the list of Layers begins. Below that you'll find lines containing `LAYOUT`, and these lines indicate the start of a layer. Below that line is the list of keys that comprise a particular layer. - -!> When editing your keymap file be careful not to add or remove any commas. If you do, you will prevent your firmware from compiling and it may not be easy to figure out where the extra, or missing, comma is. - -## Customize The Layout To Your Liking - -How to complete this step is entirely up to you. Make the one change that's been bugging you, or completely rework everything. You can remove layers if you don't need all of them, or add layers up to a total of 32. There are a lot of features in QMK, explore the sidebar to the left under "Using QMK" to see the full list. To get you started here are a few of the easier to use features: - -* [Basic Keycodes](keycodes_basic.md) -* [Quantum Keycodes](quantum_keycodes.md) -* [Grave/Escape](feature_grave_esc.md) -* [Mouse keys](feature_mouse_keys.md) - -?> While you get a feel for how keymaps work, keep each change small. Bigger changes make it harder to debug any problems that arise. - -## Build Your Firmware :id=build-your-firmware - -When your changes to the keymap are complete you will need to build the firmware. To do so go back to your terminal window and run the compile command: - - qmk compile - -If you did not configure defaults for your environment, or you have multiple keyboards, you can specify a keyboard and/or keymap: - - qmk compile -kb -km - -While this compiles you will have a lot of output going to the screen informing you of what files are being compiled. It should end with output that looks similar to this: - -``` -Linking: .build/planck_rev5_default.elf [OK] -Creating load file for flashing: .build/planck_rev5_default.hex [OK] -Copying planck_rev5_default.hex to qmk_firmware folder [OK] -Checking file size of planck_rev5_default.hex [OK] - * The firmware size is fine - 27312/28672 (95%, 1360 bytes free) -``` - -## Flash Your Firmware - -Move on to [Flashing Firmware](newbs_flashing.md) to learn how to write your new firmware to your keyboard. diff --git a/docs/newbs_building_firmware_configurator.md b/docs/newbs_building_firmware_configurator.md deleted file mode 100644 index eae0cef2c280..000000000000 --- a/docs/newbs_building_firmware_configurator.md +++ /dev/null @@ -1,13 +0,0 @@ -# QMK Configurator - -[![QMK Configurator Screenshot](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/) - -The [QMK Configurator](https://config.qmk.fm) is an online graphical user interface that generates QMK Firmware `.hex` or `.bin` files. - -Watch the [Video Tutorial](https://www.youtube.com/watch?v=-imgglzDMdY). Many people find that is enough information to start programming their own keyboard. - -The QMK Configurator works best with Chrome or Firefox. - -!> **Note: Files from other tools such as Keyboard Layout Editor (KLE), or kbfirmware will not be compatible with QMK Configurator. Do not load them, do not import them. QMK Configurator is a DIFFERENT tool.** - -Please refer to [QMK Configurator: Step by Step](configurator_step_by_step.md). diff --git a/docs/newbs_building_firmware_workflow.md b/docs/newbs_building_firmware_workflow.md deleted file mode 100644 index 51ce30490131..000000000000 --- a/docs/newbs_building_firmware_workflow.md +++ /dev/null @@ -1,192 +0,0 @@ -# Building QMK with GitHub Userspace - -This is an intermediate QMK tutorial to setup an out-of-tree build environment with a personal GitHub repository. It avoids using a fork of the QMK firmware to store and build your keymap within its source tree. Keymap files will instead be stored in your own personal GitHub repository, in [Userspace](https://docs.qmk.fm/#/feature_userspace) format, and built with an action workflow. Unlike the [default tutorial](https://docs.qmk.fm/#/newbs), this guide requires some familiarity with using Git. - -?> **Is This Guide For Me?**
-This is a lean setup to avoid space-consuming local build environment in your computer. Troubleshooting compile-time errors will be slower with commit uploads to GitHub for the compiler workflow. - - -## Prerequisites - -The following are required to get started: - -* [GitHub Account](https://github.com/new) - * A working account is required to setup and host your repository for GitHub Actions to build QMK firmware. -* [Text editor](newbs_learn_more_resources.md#text-editor-resources) - * You’ll need a program that can edit and save plain text files. The default editor that comes with many OS's does not save plain text files, so you'll need to make sure that whatever editor you chose does. -* [Toolbox](https://github.com/qmk/qmk_toolbox) - * A graphical program for Windows and macOS that allows you to both program and debug your custom keyboard. - - -## Environment Setup - -?> If you are familiar with using [github.dev](https://docs.github.com/en/codespaces/the-githubdev-web-based-editor), you can skip to [step 2](#_2-create-github-repository) and commit the code files that follows directly on GitHub using the web-based VSCode editor. - -### 1. Install Git - -A working Git client is required for your local operating system to commit and push changes to GitHub. - - - -### ** Windows ** - -QMK maintains a bundle of MSYS2, the CLI and all necessary dependencies including Git. Install [QMK MSYS](https://msys.qmk.fm/) with the latest release [here](https://github.com/qmk/qmk_distro_msys/releases/latest). Git will be part of the bundle. - -### ** macOS ** - -Install Homebrew following the instructions on https://brew.sh. Git will be part of the bundle. - -### ** Linux/WSL ** - -It's very likely that you already have Git installed. If not, use one of the following commands: - -* Debian / Ubuntu / Devuan: `sudo apt install -y git` -* Fedora / Red Hat / CentOS: `sudo yum -y install git` -* Arch / Manjaro: `sudo pacman --needed --noconfirm -S git` -* Void: `sudo xbps-install -y git` -* Solus: `sudo eopkg -y install git` -* Sabayon: `sudo equo install dev-vcs/git` -* Gentoo: `sudo emerge dev-vcs/git` - - - -### 2. GitHub authentication - -If your GitHub account is not configured for [authenticated Git operations](https://github.blog/2020-12-15-token-authentication-requirements-for-git-operations/), you will need to setup at least one of the following: -* [Personal access token](https://docs.github.com/en/authentication/keeping-your-account-and-data-secure/creating-a-personal-access-token) -* [Connecting with SSH](https://docs.github.com/en/authentication/connecting-to-github-with-ssh) - -### 3. Create a repository - -You will need a personal GitHub repository to host your QMK code. Follow [this guide](https://docs.github.com/en/get-started/quickstart/create-a-repo#create-a-repository) to create one named `qmk_keymap`. Do not proceed to commit any files just yet. - - -## Initial Code Commit - -### Create template files - -Run the following commands in your computer to create a folder with a few template files: -``` -mkdir -p ~/qmk_keymap/.github/workflows -touch ~/qmk_keymap/.github/workflows/build.yml -touch ~/qmk_keymap/config.h -echo "SRC += source.c" > ~/qmk_keymap/rules.mk -echo "#include QMK_KEYBOARD_H" > ~/qmk_keymap/source.c -``` - -?> For Windows user running MSYS, those commands will create the folder `qmk_keymap/` and its content in the `C:\Users\\qmk_keymap\` path location. - -### Add a JSON keymap - -Visit the [QMK Configurator](https://config.qmk.fm/#/) to create a keymap file: - -1. Select your keyboard from the drop-down list (and choose a layout if required). -2. Use your GitHub username for the **Keymap Name** field. -3. Customise the key layout according to your preference. -4. Select download next to **KEYMAP.JSON** and save the JSON file into the `~/qmk_keymap/` folder. - -### Add a GitHub Action workflow - -Open the file `~/qmk_keymap/.github/workflows/build.yml` with your favorite [text editor](newbs_learn_more_resources.md#text-editor-resources), paste the following workflow content, and save it: -```yml -name: Build QMK firmware -on: [push, workflow_dispatch] - -jobs: - build: - runs-on: ubuntu-latest - container: ghcr.io/qmk/qmk_cli - strategy: - fail-fast: false - matrix: -# List of keymap json files to build - file: - - username.json -# End of json file list - - steps: - - - name: Disable git safe directory checks - run : git config --global --add safe.directory '*' - - - name: Checkout QMK - uses: actions/checkout@v3 - with: - repository: qmk/qmk_firmware - submodules: recursive - - - name: Checkout userspace - uses: actions/checkout@v3 - with: - path: users/${{ github.actor }} - - - name: Build firmware - run: qmk compile "users/${{ github.actor }}/${{ matrix.file }}" - - - name: Archive firmware - uses: actions/upload-artifact@v3 - continue-on-error: true - with: - name: ${{ matrix.file }}_${{ github.actor }} - path: | - *.hex - *.bin - *.uf2 -``` -Replace `username.json` with the JSON file name that was downloaded from [QMK Configurator](https://config.qmk.fm/#/) in the previous step. - -!> Do note that the `build.yml` file requires ***proper indentation*** for every line. Incorrect spacing will trigger workflow syntax errors. - -### Commit files to GitHub - -If you have completed all steps correctly, the folder `qmk_keymap/` will contain the following files: -``` -|-- .github -| `-- workflows -| `-- build.yml -|-- rules.mk -|-- config.h -|-- source.c -|-- username.json -``` - -To commit and push them into GitHub, run the following commands (replacing `gh-username` with your GitHub user name): -``` -cd ~/qmk_keymap -git init -git add -A -git commit -m "Initial QMK keymap commit" -git branch -M main -git remote add origin https://github.com/gh-username/qmk_keymap.git -git push -u origin main -``` -?> Use your GitHub personal access token at the password prompt. If you have setup SSH access, replace `https://github.com/gh-username/qmk_keymap.git` with `git@github.com:gh-username/qmk_keymap.git` in the remote origin command above. - -### Review workflow output - -Files committed to GitHub in the previous step will automatically trigger the workflow to build the JSON file listed in `build.yml`. To review its output: -1. Visit your "**qmk_keymap**" repository page on [GitHub](https://github.com/). -2. Select **Actions** tab to display the "**Build QMK Firmware**" workflow. -3. Select that workflow to display its run from the last commit. -4. Successfully compiled firmware will be under the "**Artifacts**" section. -5. If there are build errors, review the job log for details. - -Download and flash the firmware file into your keyboard using [QMK Toolbox](https://docs.qmk.fm/#/newbs_flashing?id=flashing-your-keyboard-with-qmk-toolbox). - - -## Customising your keymap - -This setup and workflow relies on the QMK [Userspace](https://docs.qmk.fm/#/feature_userspace) feature. The build process will copy the QMK source codes and clone your repository into its `users/` folder in a container. You must adhere to the following guidelines when customising your keymaps: - -* Keymap layout files must be retained in JSON format and cannot be converted to `keymap.c`. -* User callback and functions (e.g. `process_record_user()`) can be placed in the `source.c` file. -* Multiple keymap JSON files can be built in the same workflow. List them under `matrix.file:`, e.g.: -```yml - file: - - planck.json - - crkbd.json -``` -* Code changes will require Git commit into GitHub to trigger the build workflow. - - -?> See [GitHub Actions guide](https://docs.github.com/en/actions/learn-github-actions) to learn more about development workflow. diff --git a/docs/newbs_flashing.md b/docs/newbs_flashing.md deleted file mode 100644 index 549ffcb2be60..000000000000 --- a/docs/newbs_flashing.md +++ /dev/null @@ -1,120 +0,0 @@ -# Flashing Your Keyboard - -Now that you've built a custom firmware file you'll want to flash your keyboard. - -## Put Your Keyboard into DFU (Bootloader) Mode - -In order to flash your custom firmware you must first put your keyboard into a special flashing mode. While it is in this mode you will not be able to type or otherwise use your keyboard. It is very important that you do not unplug the keyboard or otherwise interrupt the flashing process while the firmware is being written. - -Different keyboards have different ways to enter this special mode. If your PCB currently runs QMK, TMK, or PS2AVRGB (Bootmapper Client) and you have not been given specific instructions, try the following, in order: - -* Hold down both shift keys and press `Pause` -* Hold down both shift keys and press `B` -* Unplug your keyboard, hold down the Spacebar and `B` at the same time, plug in your keyboard and wait a second before releasing the keys -* Unplug your keyboard, hold down the top or bottom left key (usually Escape or Left Control) and plug in your keyboard -* Press the physical `RESET` button, usually located on the underside of the PCB -* Locate header pins on the PCB labeled `RESET` and `GND`, and short them together while plugging your PCB in - -If you've attempted all of the above to no avail, and the main chip on the board says `STM32` on it, this may be a bit more complicated. Generally your best bet is to ask on [Discord](https://discord.gg/Uq7gcHh) for assistance. It's likely some photos of the board will be asked for -- if you can get them ready beforehand it'll help move things along! - -Otherwise, you should see a message in yellow, similar to this in QMK Toolbox: - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -``` - -and this bootloader device will also be present in Device Manager, System Information.app, or `lsusb`. - -## Flashing Your Keyboard with QMK Toolbox - -The simplest way to flash your keyboard will be with the [QMK Toolbox](https://github.com/qmk/qmk_toolbox/releases). - -However, the Toolbox is currently only available for Windows and macOS. If you're using Linux (or just wish to flash the firmware from the command line), skip to the [Flash your Keyboard from the Command Line](#flash-your-keyboard-from-the-command-line) section. - -### Load the File into QMK Toolbox - -Begin by opening the QMK Toolbox application. You'll want to locate the firmware file in Finder or Explorer. Your keyboard firmware may be in one of two formats- `.hex` or `.bin`. QMK tries to copy the appropriate one for your keyboard into the root `qmk_firmware` directory. - -If you are on Windows or macOS, there are commands you can use to easily open the current folder in Explorer or Finder. - - - -#### ** Windows ** - -``` -start . -``` - -#### ** macOS ** - -``` -open . -``` - - - -The firmware file always follows this naming format: - -``` -_.{bin,hex} -``` - -For example, the `planck/rev5` with a `default` keymap will have this filename: - -``` -planck_rev5_default.hex -``` - -Once you have located your firmware file, drag it into the "Local file" box in QMK Toolbox, or click "Open" and navigate to where your firmware file is stored. - -### Flash Your Keyboard - -Click the `Flash` button in QMK Toolbox. You will see output similar to the following: - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -*** Attempting to flash, please don't remove device ->>> dfu-programmer.exe atmega32u4 erase --force - Erasing flash... Success - Checking memory from 0x0 to 0x6FFF... Empty. ->>> dfu-programmer.exe atmega32u4 flash "D:\Git\qmk_firmware\gh60_satan_default.hex" - Checking memory from 0x0 to 0x3F7F... Empty. - 0% 100% Programming 0x3F80 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - 0% 100% Reading 0x7000 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - Validating... Success - 0x3F80 bytes written into 0x7000 bytes memory (56.70%). ->>> dfu-programmer.exe atmega32u4 reset - -*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000) -``` - -## Flash your Keyboard from the Command Line - -This has been made pretty simple compared to what it used to be. When you are ready to compile and flash your firmware, open up your terminal window and run the flash command: - - qmk flash - -If you did not configure your keyboard/keymap name in the CLI according to the [Configure your build environment](newbs_getting_started.md) section, or you have multiple keyboards, you can specify the keyboard and keymap: - - qmk flash -kb -km - -This will check the keyboard's configuration, and then attempt to flash it based on the specified bootloader. This means that you don't need to know which bootloader that your keyboard uses. Just run the command, and let the command do the heavy lifting. - -However, this does rely on the bootloader being set by the keyboard. If this information is not configured, or you're using a board that doesn't have a supported target to flash it, you will see this error: - - WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. - -In this case, you'll have to fall back on specifying the bootloader. See the [Flashing Firmware](flashing.md) Guide for more details. - -!> If your bootloader is not detected by `qmk flash`, try running `qmk doctor` for suggestions on how to fix common problems. - -## Test It Out! - -Congrats! Your custom firmware has been programmed to your keyboard and you're ready to test it out! - -With a little bit of luck everything will work perfectly, but if not there are steps that will help you figure out what's wrong. -Testing your keyboard is usually pretty straightforward. Press every single key and make sure it sends the keys you expect. You can use [QMK Configurator](https://config.qmk.fm/#/test/)'s test mode to check your keyboard, even if it doesn't run QMK. - -Still not working? Browse the FAQ topics for more information, or [chat with us on Discord](https://discord.gg/Uq7gcHh). diff --git a/docs/newbs_getting_started.md b/docs/newbs_getting_started.md deleted file mode 100644 index b0d28d89d163..000000000000 --- a/docs/newbs_getting_started.md +++ /dev/null @@ -1,189 +0,0 @@ -# Setting Up Your QMK Environment - -Before you can build keymaps, you need to install some software and set up your build environment. This only has to be done once no matter how many keyboards you plan to compile firmware for. - -## 1. Prerequisites - -There are a few pieces of software you'll need to get started. - -* [Text editor](newbs_learn_more_resources.md#text-editor-resources) - * You’ll need a program that can edit and save plain text files. The default editor that comes with many OS's does not save plain text files, so you'll need to make sure that whatever editor you chose does. -* [Toolbox (optional)](https://github.com/qmk/qmk_toolbox) - * A graphical program for Windows and macOS that allows you to both program and debug your custom keyboard - -?> If you haven't worked with the Linux/Unix command line before, there are a few basic concepts and commands you should learn. [These resources](newbs_learn_more_resources.md#command-line-resources) will teach you enough to be able to work with QMK. - -## 2. Prepare Your Build Environment :id=set-up-your-environment - -We've tried to make QMK as easy to set up as possible. You only have to prepare your Linux or Unix environment, then let QMK install the rest. - - - -### ** Windows ** - -QMK maintains a Bundle of MSYS2, the CLI and all necessary dependencies. It also provides a handy `QMK MSYS` terminal shortcut to boot you directly into the correct environment. - -#### Prerequisites - -You will need to install [QMK MSYS](https://msys.qmk.fm/). The latest release is available [here](https://github.com/qmk/qmk_distro_msys/releases/latest). - -
- Advanced Users - -!> This process is not recommended for new users. - -If you'd like to manually install MSYS2, the following sections will walk you through the process. - -#### Prerequisites - -You will need to install [MSYS2](https://www.msys2.org). Once installed, close any open MSYS terminals (purple icon) and open a new MinGW 64-bit terminal (blue icon) from the Start Menu. - -!> **NOTE:** The MinGW 64-bit terminal is *not* the same as the MSYS terminal that opens when installation is completed. Your prompt should say "MINGW64" in purple text, rather than "MSYS". See [this page](https://www.msys2.org/wiki/MSYS2-introduction/#subsystems) for more information on the differences. - -#### Installation - -Install the QMK CLI by running: - - pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-python-qmk - -
- -### ** macOS ** - -QMK maintains a Homebrew tap and formula which will automatically install the CLI and all necessary dependencies. - -#### Prerequisites - -You will need to install Homebrew. Follow the instructions on https://brew.sh. - -!> **NOTE:** If you are using Apple Silicon, such as the M1, you will need to install a rosetta compatible version of Homebrew. This version does not override the base Homebrew. This can be done by running `arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"`. See here: [Rosetta-compatible Homebrew](https://stackoverflow.com/questions/64882584/how-to-run-the-homebrew-installer-under-rosetta-2-on-m1-macbook) - -#### Installation - -Install the QMK CLI by running: - - brew install qmk/qmk/qmk - -Install the QMK CLI on an Apple Silicon Mac by running: - - arch -x86_64 brew install qmk/qmk/qmk - -### ** Linux/WSL ** - -?> **Note for WSL users**: By default, the installation process will clone the QMK repository into your WSL home directory, but if you have cloned manually, ensure that it is located inside the WSL instance instead of the Windows filesystem (ie. not in `/mnt`), as accessing it is currently [extremely slow](https://github.com/microsoft/WSL/issues/4197). - -#### Prerequisites - -You will need to install Git and Python. It's very likely that you already have both, but if not, one of the following commands should install them: - -* Debian / Ubuntu / Devuan: `sudo apt install -y git python3-pip` -* Fedora / Red Hat / CentOS: `sudo yum -y install git python3-pip` -* Arch / Manjaro: `sudo pacman --needed --noconfirm -S git python-pip libffi` -* Void: `sudo xbps-install -y git python3-pip` -* Solus: `sudo eopkg -y install git python3` -* Sabayon: `sudo equo install dev-vcs/git dev-python/pip` -* Gentoo: `sudo emerge dev-vcs/git dev-python/pip` - -#### Installation - -Install the QMK CLI by running: - - python3 -m pip install --user qmk - -#### Community Packages - -These packages are maintained by community members, so may not be up to date or completely functional. If you encounter problems, please report them to their respective maintainers. - -On Arch-based distros you can install the CLI from the official repositories (NOTE: at the time of writing this package marks some dependencies as optional that should not be): - - sudo pacman -S qmk - -You can also try the `qmk-git` package from AUR: - - yay -S qmk-git - -### ** FreeBSD ** - -#### Installation - -Install the FreeBSD package for QMK CLI by running: - - pkg install -g "py*-qmk" - -NOTE: remember to follow the instructions printed at the end of installation (use `pkg info -Dg "py*-qmk"` to show them again). - - - -## 3. Run QMK Setup :id=set-up-qmk - - - -### ** Windows ** - -After installing QMK you can set it up with this command: - - qmk setup - -In most situations you will want to answer `y` to all of the prompts. - -### ** macOS ** - -After installing QMK you can set it up with this command: - - qmk setup - -In most situations you will want to answer `y` to all of the prompts. - -### ** Linux/WSL ** - -After installing QMK you can set it up with this command: - - qmk setup - -In most situations you will want to answer `y` to all of the prompts. - -?>**Note on Debian, Ubuntu and their derivatives**: -It's possible, that you will get an error saying something like: `bash: qmk: command not found`. -This is due to a [bug](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155) Debian introduced with their Bash 4.4 release, which removed `$HOME/.local/bin` from the PATH. This bug was later fixed on Debian and Ubuntu. -Sadly, Ubuntu reintroduced this bug and is [yet to fix it](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562). -Luckily, the fix is easy. Run this as your user: `echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc` - -### ** FreeBSD ** - -After installing QMK you can set it up with this command: - - qmk setup - -In most situations you will want to answer `y` to all of the prompts. - - - -?> The qmk home folder can be specified at setup with `qmk setup -H `, and modified afterwards using the [cli configuration](cli_configuration.md?id=single-key-example) and the variable `user.qmk_home`. For all available options run `qmk setup --help`. - -?> If you already know how to use GitHub, [we recommend that you follow these instructions](getting_started_github.md) and use `qmk setup /qmk_firmware` to clone your personal fork. If you don't know what that means you can safely ignore this message. - -## 4. Test Your Build Environment - -Now that your QMK build environment is set up, you can build a firmware for your keyboard. Start by trying to build the keyboard's default keymap. You should be able to do that with a command in this format: - - qmk compile -kb -km default - -For example, to build a firmware for a Clueboard 66% you would use: - - qmk compile -kb clueboard/66/rev3 -km default - -?> The keyboard option is the path relative to the keyboard directory, the above example would be found in `qmk_firmware/keyboards/clueboard/66/rev3`. If you're unsure you can view a full list of supported keyboards with `qmk list-keyboards`. - -When it is done you should have a lot of output that ends similar to this: - -``` -Linking: .build/clueboard_66_rev3_default.elf [OK] -Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] -Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] -Checking file size of clueboard_66_rev3_default.hex [OK] - * The firmware size is fine - 26356/28672 (2316 bytes free) -``` - -# Creating Your Keymap - -You are now ready to create your own personal keymap! Move on to [Building Your First Firmware](newbs_building_firmware.md) for that. diff --git a/docs/newbs_git_best_practices.md b/docs/newbs_git_best_practices.md deleted file mode 100644 index c0cb3a29449d..000000000000 --- a/docs/newbs_git_best_practices.md +++ /dev/null @@ -1,16 +0,0 @@ -# Best Git Practices for Working with QMK - -## Or, "How I Learned to Stop Worrying and Love Git." - -This section aims to instruct novices in the best ways to have a smooth experience in contributing to QMK. We will walk through the process of contributing to QMK, detailing some ways to make this task easier, and then later we'll break some things in order to teach you how to fix them. - -This section assumes a few things: - -1. You have a GitHub account, and have [forked the qmk_firmware repository](getting_started_github.md) to your account. -2. You've set up both [your build environment](newbs_getting_started.md#set-up-your-environment) and [QMK](newbs_getting_started.md#set-up-qmk). - ---- - -- Part 1: [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md) -- Part 2: [Resolving Merge Conflicts](newbs_git_resolving_merge_conflicts.md) -- Part 3: [Resynchronizing an Out-of-Sync Git Branch](newbs_git_resynchronize_a_branch.md) diff --git a/docs/newbs_git_resolving_merge_conflicts.md b/docs/newbs_git_resolving_merge_conflicts.md deleted file mode 100644 index 467c13abba9f..000000000000 --- a/docs/newbs_git_resolving_merge_conflicts.md +++ /dev/null @@ -1,79 +0,0 @@ -# Resolving Merge Conflicts - -Sometimes when your work in a branch takes a long time to complete, changes that have been made by others conflict with changes you have made to your branch when you open a pull request. This is called a *merge conflict*, and is what happens when multiple people edit the same parts of the same files. - -?> This document builds upon the concepts detailed in [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md). If you are not familiar with that document, please read it first, then return here. - -## Rebasing Your Changes - -A *rebase* is Git's way of taking changes that were applied at one point in the commit history, reversing them, and then applying the same changes at another point. In the case of a merge conflict, you can rebase your branch to grab the changes that were made between when you created your branch and the present time. - -To start, run the following: - -``` -git fetch upstream -git rev-list --left-right --count HEAD...upstream/master -``` - -The `git rev-list` command entered here returns the number of commits that differ between the current branch and QMK's master branch. We run `git fetch` first to make sure we have the refs that represent the current state of the upstream repo. The output of the `git rev-list` command entered returns two numbers: - -``` -$ git rev-list --left-right --count HEAD...upstream/master -7 35 -``` - -The first number represents the number of commits on the current branch since it was created, and the second number is the number of commits made to `upstream/master` since the current branch was created, and thus, the changes that are not recorded in the current branch. - -Now that the current states of both the current branch and the upstream repo are known, we can start a rebase operation: - -``` -git rebase upstream/master -``` - -This tells Git to undo the commits on the current branch, and then reapply them against QMK's master branch. - -``` -$ git rebase upstream/master -First, rewinding head to replay your work on top of it... -Applying: Commit #1 -Using index info to reconstruct a base tree... -M conflicting_file_1.txt -Falling back to patching base and 3-way merge... -Auto-merging conflicting_file_1.txt -CONFLICT (content): Merge conflict in conflicting_file_1.txt -error: Failed to merge in the changes. -hint: Use 'git am --show-current-patch' to see the failed patch -Patch failed at 0001 Commit #1 - -Resolve all conflicts manually, mark them as resolved with -"git add/rm ", then run "git rebase --continue". -You can instead skip this commit: run "git rebase --skip". -To abort and get back to the state before "git rebase", run "git rebase --abort". -``` - -This tells us that we have a merge conflict, and gives the name of the file with the conflict. Open the conflicting file in your text editor, and somewhere in the file, you'll find something like this: - -``` -<<<<<<< HEAD -

For help with any issues, email us at support@webhost.us.

-======= -

Need help? Email support@webhost.us.

->>>>>>> Commit #1 -``` - -The line `<<<<<<< HEAD` marks the beginning of a merge conflict, and the `>>>>>>> Commit #1` line marks the end, with the conflicting sections separated by `=======`. The part on the `HEAD` side is from the QMK master version of the file, and the part marked with the commit message is from the current branch and commit. - -Because Git tracks *changes to files* rather than the contents of the files directly, if Git can't find the text that was in the file previous to the commit that was made, it won't know how to edit the file. Re-editing the file will solve the conflict. Make your changes, and then save the file. - -``` -

Need help? Email support@webhost.us.

-``` - -Now run: - -``` -git add conflicting_file_1.txt -git rebase --continue -``` - -Git logs the changes to the conflicting file, and continues applying the commits from our branch until it reaches the end. diff --git a/docs/newbs_git_resynchronize_a_branch.md b/docs/newbs_git_resynchronize_a_branch.md deleted file mode 100644 index b15c6cf7a85d..000000000000 --- a/docs/newbs_git_resynchronize_a_branch.md +++ /dev/null @@ -1,71 +0,0 @@ -# Resynchronizing an Out-of-Sync Git Branch - -Suppose you have committed to your `master` branch, and now need to update your QMK repository. You could `git pull` QMK's `master` branch into your own, but GitHub will tell you that your branch is a number of commits ahead of `qmk:master`, which can create issues if you want to make a pull request to QMK. - -?> This document builds upon the concepts detailed in [Your Fork's Master: Update Often, Commit Never](newbs_git_using_your_master_branch.md). If you are not familiar with that document, please read it first, then return here. - -## Backing Up the Changes on Your Own Master Branch (Optional) - -No one wants to lose work if it can be helped. If you want to save the changes you've already made to your `master` branch, the simplest way to do so is to simply create a duplicate of your "dirty" `master` branch: - -``` -git branch old_master master -``` - -Now you have a branch named `old_master` that is a duplicate of your `master` branch. - -## Resynchronizing Your Branch - -Now it's time to resynchronize your `master` branch. For this step, you'll want to have QMK's repository configured as a remote in Git. To check your configured remotes, run `git remote -v`, which should return something similar to: - -``` -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -If you only see one fork referenced: - -``` -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com/qmk/qmk_firmware.git (fetch) -origin https://github.com/qmk/qmk_firmware.git (push) -``` - -add a new remote with: - -``` -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -Then, redirect the `origin` remote to your own fork with: - -``` -git remote set-url origin https://github.com//qmk_firmware.git -``` - -Now that you have both remotes configured, you need to update the references for the upstream repository, which is QMK's, by running: - -``` -git fetch --recurse-submodules upstream -``` - -At this point, resynchronize your branch to QMK's by running: - -``` -git reset --recurse-submodules --hard upstream/master -``` - -These steps will update the repository on your computer, but your GitHub fork will still be out of sync. To resynchronize your fork on GitHub, you need to push to your fork, instructing Git to override any remote changes that are not reflected in your local repository. To do this, run: - -``` -git push --recurse-submodules=on-demand --force-with-lease -``` - -!> **DO NOT** run `git push --recurse-submodules=on-demand --force-with-lease` on a fork to which other users post commits. This will erase their commits. - -Now your GitHub fork, your local files, and QMK's repository are all the same. From here you can make further needed changes ([use a branch!](newbs_git_using_your_master_branch.md#making-changes)) and post them as normal. diff --git a/docs/newbs_git_using_your_master_branch.md b/docs/newbs_git_using_your_master_branch.md deleted file mode 100644 index c27323f55153..000000000000 --- a/docs/newbs_git_using_your_master_branch.md +++ /dev/null @@ -1,74 +0,0 @@ -# Your Fork's Master: Update Often, Commit Never - -It is highly recommended for QMK development, regardless of what is being done or where, to keep your `master` branch updated, but ***never*** commit to it. Instead, do all your changes in a development branch and issue pull requests from your branches when you're developing. - -To reduce the chances of merge conflicts — instances where two or more users have edited the same part of a file concurrently — keep your `master` branch relatively up-to-date, and start any new developments by creating a new branch. - -## Updating your master branch - -To keep your `master` branch updated, it is recommended to add the QMK Firmware repository ("repo") as a remote repository in git. To do this, open your Git command line interface and enter: - -``` -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -?> The name `upstream` is arbitrary, but a common convention; you can give the QMK remote any name that suits you. Git's `remote` command uses the syntax `git remote add `, `` being shorthand for the remote repo. This name can be used with many Git commands, including but not limited to `fetch`, `pull` and `push`, to specify the remote repo on which to act. - -To verify that the repository has been added, run `git remote -v`, which should return the following: - -``` -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -Now that this is done, you can check for updates to the repo by running `git fetch upstream`. This retrieves the branches and tags — collectively referred to as "refs" — from the QMK repo, which now has the nickname `upstream`. We can now compare the data on our fork `origin` to that held by QMK. - -To update your fork's master, run the following, hitting the Enter key after each line: - -``` -git checkout master -git fetch upstream -git pull upstream master -git push origin master -``` - -This switches you to your `master` branch, retrieves the refs from the QMK repo, downloads the current QMK `master` branch to your computer, and then uploads it to your fork. - -## Making Changes :id=making-changes - -To make changes, create a new branch by entering: - -``` -git checkout -b dev_branch -git push --set-upstream origin dev_branch -``` - -This creates a new branch named `dev_branch`, checks it out, and then saves the new branch to your fork. The `--set-upstream` argument tells git to use your fork and the `dev_branch` branch every time you use `git push` or `git pull` from this branch. It only needs to be used on the first push; after that, you can safely use `git push` or `git pull`, without the rest of the arguments. - -?> With `git push`, you can use `-u` in place of `--set-upstream` — `-u` is an alias for `--set-upstream`. - -You can name your branch nearly anything you want, though it is recommended to name it something related to the changes you are going to make. - -By default `git checkout -b` will base your new branch on the branch that is currently checked out. You can base your new branch on an existing branch that is not checked out by adding the name of the existing branch to the command: - -``` -git checkout -b dev_branch master -``` - -Now that you have a development branch, open your text editor and make whatever changes you need to make. It is recommended to make many small commits to your branch; that way, any change that causes issues can be more easily traced and undone if needed. To make your changes, edit and save any files that need to be updated, add them to Git's *staging area*, and then commit them to your branch: - -``` -git add path/to/updated_file -git commit -m "My commit message." -``` - -`git add` adds files that have been changed to Git's *staging area*, which is Git's "loading zone." This contains the changes that are going to be *committed* by `git commit`, which saves the changes to the repo. Use descriptive commit messages so you can know what was changed at a glance. - -?> If you've changed multiple files, you can use `git add -- path/to/file1 path/to/file2 ...` to add all your desired files. - -## Publishing Your Changes - -The last step is to push your changes to your fork. To do this, enter `git push`. Git will then publish the current state of `dev_branch` to your fork. diff --git a/docs/newbs_learn_more_resources.md b/docs/newbs_learn_more_resources.md deleted file mode 100644 index 1afdc206bd46..000000000000 --- a/docs/newbs_learn_more_resources.md +++ /dev/null @@ -1,28 +0,0 @@ -# Learning Resources - -These resources are aimed at giving new members in the QMK community more understanding to the information provided in the Newbs docs. - -### QMK resources - -* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – A user-created blog covering the basics of how to use QMK Firmware, as seen from a new user's perspective. - -### Command Line resources - -* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line) -* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
-* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) - -### Text Editor resources - -Not sure which text editor to use? -* [a great introduction to the subject](https://learntocodewith.me/programming/basics/text-editors/) - -Editors specifically made for code: -* [Sublime Text](https://www.sublimetext.com/) -* [VS Code](https://code.visualstudio.com/) - -### Git resources - -* [Great General Tutorial](https://www.codecademy.com/learn/learn-git) -* [Flight Rules For Git](https://github.com/k88hudson/git-flight-rules) -* [Git Game To Learn From Examples](https://learngitbranching.js.org/) diff --git a/docs/newbs_testing_debugging.md b/docs/newbs_testing_debugging.md deleted file mode 100644 index c3550489e5c4..000000000000 --- a/docs/newbs_testing_debugging.md +++ /dev/null @@ -1,9 +0,0 @@ -# Testing and Debugging - -## Testing - -[Moved here](faq_misc.md#testing) - -## Debugging :id=debugging - -[Moved here](faq_debug.md#debugging) diff --git a/docs/one_shot_keys.md b/docs/one_shot_keys.md deleted file mode 100644 index 515830ea3248..000000000000 --- a/docs/one_shot_keys.md +++ /dev/null @@ -1,105 +0,0 @@ -# One Shot Keys - -One shot keys are keys that remain active until the next key is pressed, and then are released. This allows you to type keyboard combinations without pressing more than one key at a time. These keys are usually called "Sticky keys" or "Dead keys". - -For example, if you define a key as `OSM(MOD_LSFT)`, you can type a capital A character by first pressing and releasing shift, and then pressing and releasing A. Your computer will see the shift key being held the moment shift is pressed, and it will see the shift key being released immediately after A is released. - -One shot keys also work as normal modifiers. If you hold down a one shot key and type other keys, your one shot will be released immediately after you let go of the key. - -Additionally, hitting keys five times in a short period will lock that key. This applies for both One Shot Modifiers and One Shot Layers, and is controlled by the `ONESHOT_TAP_TOGGLE` define. - -You can control the behavior of one shot keys by defining these in `config.h`: - -```c -#define ONESHOT_TAP_TOGGLE 5 /* Tapping this number of times holds the key until tapped once again. */ -#define ONESHOT_TIMEOUT 5000 /* Time (in ms) before the one shot key is released */ -``` - -* `OSM(mod)` - Momentarily hold down *mod*. You must use the `MOD_*` keycodes as shown in [Mod Tap](mod_tap.md), not the `KC_*` codes. -* `OSL(layer)` - momentary switch to *layer*. -* `OS_ON` - Turns on One Shot keys. -* `OS_OFF` - Turns off One Shot keys. OSM act as regular mod keys, OSL act like `MO`. -* `OS_TOGG` - Toggles the one shot key status. - -Sometimes, you want to activate a one-shot key as part of a macro or tap dance routine. - -For one shot layers, you need to call `set_oneshot_layer(LAYER, ONESHOT_START)` on key down, and `clear_oneshot_layer_state(ONESHOT_PRESSED)` on key up. If you want to cancel the oneshot, call `reset_oneshot_layer()`. - -For one shot mods, you need to call `set_oneshot_mods(MOD_BIT(KC_*))` to set it, or `clear_oneshot_mods()` to cancel it. - -!> If you're having issues with OSM translating over Remote Desktop Connection, this can be fixed by opening the settings, going to the "Local Resources" tab, and in the keyboard section, change the drop down to "On this Computer". This will fix the issue and allow OSM to function properly over Remote Desktop. - -## Callbacks - -When you'd like to perform custom logic when pressing a one shot key, there are several callbacks you can choose to implement. You could indicate changes in one shot keys by flashing an LED or making a sound, for example. - -There is a callback for `OSM(mod)`. It is called whenever the state of any one shot modifier key is changed: when it toggles on, but also when it is toggled off. You can use it like this: - -```c -void oneshot_mods_changed_user(uint8_t mods) { - if (mods & MOD_MASK_SHIFT) { - println("Oneshot mods SHIFT"); - } - if (mods & MOD_MASK_CTRL) { - println("Oneshot mods CTRL"); - } - if (mods & MOD_MASK_ALT) { - println("Oneshot mods ALT"); - } - if (mods & MOD_MASK_GUI) { - println("Oneshot mods GUI"); - } - if (!mods) { - println("Oneshot mods off"); - } -} -``` - -The `mods` argument contains the active mods after the change, so it reflects the current state. - -When you use One Shot Tap Toggle (by adding `#define ONESHOT_TAP_TOGGLE 2` in your `config.h` file), you may lock a modifier key by pressing it the specified amount of times. There's a callback for that, too: - -```c -void oneshot_locked_mods_changed_user(uint8_t mods) { - if (mods & MOD_MASK_SHIFT) { - println("Oneshot locked mods SHIFT"); - } - if (mods & MOD_MASK_CTRL) { - println("Oneshot locked mods CTRL"); - } - if (mods & MOD_MASK_ALT) { - println("Oneshot locked mods ALT"); - } - if (mods & MOD_MASK_GUI) { - println("Oneshot locked mods GUI"); - } - if (!mods) { - println("Oneshot locked mods off"); - } -} -``` - -Last, there is also a callback for the `OSL(layer)` one shot key: - -```c -void oneshot_layer_changed_user(uint8_t layer) { - if (layer == 1) { - println("Oneshot layer 1 on"); - } - if (!layer) { - println("Oneshot layer off"); - } -} -``` - -If any one shot layer is switched off, `layer` will be zero. When you're looking to do something on any layer change instead of one shot layer changes, `layer_state_set_user` is a better callback to use. - -If you are making your own keyboard, there are also `_kb` equivalent functions: - -```c -void oneshot_locked_mods_changed_kb(uint8_t mods); -void oneshot_mods_changed_kb(uint8_t mods); -void oneshot_layer_changed_kb(uint8_t layer); -``` - -As with any callback, be sure to call the `_user` variant to allow for further customizability. diff --git a/docs/other_eclipse.md b/docs/other_eclipse.md deleted file mode 100644 index de8cdf9b8c9f..000000000000 --- a/docs/other_eclipse.md +++ /dev/null @@ -1,90 +0,0 @@ -# Setting up Eclipse for QMK Development - -[Eclipse][1] is an open-source [Integrated Development Environment](https://en.wikipedia.org/wiki/Integrated_development_environment) (IDE) widely used for Java development, but with an extensible plugin system that allows to customize it for other languages and usages. - -Using an IDE such as Eclipse provides many advantages over a plain text editor, such as: -* intelligent code completion -* convenient navigation in the code -* refactoring tools -* build automation (no need for the command-line) -* a GUI for GIT -* static code analysis -* many other tools such as debugging, code formatting, showing call hierarchies etc. - -The purpose of this page is to document how to set-up Eclipse for developing AVR software, and working on the QMK code base. - -Note that this set-up has been tested on Ubuntu 16.04 only for the moment. - -# Prerequisites -## Build Environment -Before starting, you must have followed the [Getting Started](newbs_getting_started.md) section of the Tutorial. In particular, you must have been able to build the firmware with [the `qmk compile` command](newbs_building_firmware.md#build-your-firmware). - -## Java -Eclipse is a Java application, so you will need to install Java 8 or more recent to be able to run it. You may choose between the JRE or the JDK, the latter being useful if you intend to do Java development. - -# Install Eclipse and Its Plugins -Eclipse comes in [several flavours](https://www.eclipse.org/downloads/eclipse-packages/) depending on the target usage that you will have. There is no package comprising the AVR stack, so we will need to start from Eclipse CDT (C/C++ Development Tooling) and install the necessary plugins. - -## Download and Install Eclipse CDT -If you already have Eclipse CDT on your system, you can skip this step. However it is advised to keep it up-to-date for better support. - -If you have another Eclipse package installed, it is normally possible to [install the CDT plugin over it](https://eclipse.org/cdt/downloads.php). However it is probably better to reinstall it from scratch to keep it light and avoid the clutter of tools that you don't need for the projects you will be working on. - -Installation is very simple: follow the [5 Steps to Install Eclipse](https://eclipse.org/downloads/eclipse-packages/?show_instructions=TRUE), and choose **Eclipse IDE for C/C++ Developers** at Step 3. - -Alternatively, you can also directly [download Eclipse IDE for C/C++ Developers](https://www.eclipse.org/downloads/eclipse-packages/) ([direct link to current version](https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr)) and extract the package to the location of your choice (this creates an `eclipse` folder). - -## First Launch -When installation is complete, click the Launch button. (If you extracted the package manually, open the Eclipse installation folder and double-click the `eclipse` executable) - -When you are prompted with the Workspace Selector, select a directory that will hold Eclipse metadata and usually your projects. **Do not select the `qmk_firmware` directory**, this will be the project directory. Select the parent folder instead, or another (preferably empty) folder of your choice (the default is fine if you do not use it yet). - -Once started, click the Workbench button at the top right to switch to the workbench view (there is a also checkbox at the bottom to skip the welcome screen at startup). - -## Install the Necessary Plugins -Note: you do not need to restart Eclipse after installing each plugin. Simply restart once all plugins are installed. - -### [The AVR Plugin](https://avr-eclipse.sourceforge.net/) -This is the most important plugin as it will allow Eclipse to _understand_ AVR C code. Follow [the instructions for using the update site](https://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download#Update_Site), and agree with the security warning for unsigned content. - -### [ANSI Escape in Console](https://marketplace.eclipse.org/content/ansi-escape-console) -This plugin is necessary to properly display the colored build output generated by the QMK makefile. - -1. Open Help > Eclipse Marketplace… -2. Search for _ANSI Escape in Console_ -3. Click the Install button of the plugin -4. Follow the instructions and agree again with the security warning for unsigned content. - -Once both plugins are installed, restart Eclipse as prompted. - -# Configure Eclipse for QMK -## Importing the Project -1. Click File > New > Makefile Project with Existing Code -2. On the next screen: - * Select the directory where you cloned the repository as _Existing Code Location_; - * (Optional) Give a different name to the project¹, e.g. _QMK_ or _Quantum_; - * Select the _AVR-GCC Toolchain_; - * Keep the rest as-is and click Finish - - ![Importing QMK in Eclipse](https://i.imgur.com/oHYR1yW.png) - -3. The project will now be loaded and indexed. Its files can be browsed easily through the _Project Explorer_ on the left. - -¹ There might be issues for importing the project with a custom name. If it does not work properly, try leaving the default project name (i.e. the name of the directory, probably `qmk_firmware`). - -## Build Your Keyboard - -We will now change the default make target of the project from `all` to the -specific keyboard and keymap combination we are working on, -e.g. `kinesis/kint36:stapelberg`. This way, project-wide actions like cleaning -and building the project will complete quickly, instead of taking a long time or -outright locking up Eclipse. - -1. Focus an editor tab within the project -2. Open the `Project` > `Properties` window, then select the `C/C++ Build` list - entry and switch to the `Behavior` tab. -3. Change the default `Make build target` text fields for all enabled builds - from `all` to e.g. `kinesis/kint41:stapelberg`. -4. Verify your setup works by selecting `Project` > `Clean...`. - - [1]: https://en.wikipedia.org/wiki/Eclipse_(software) diff --git a/docs/other_vscode.md b/docs/other_vscode.md deleted file mode 100644 index 83ae6e6ed060..000000000000 --- a/docs/other_vscode.md +++ /dev/null @@ -1,119 +0,0 @@ -# Setting up Visual Studio Code for QMK Development - -[Visual Studio Code](https://code.visualstudio.com/) (VS Code) is an open-source code editor that supports many different programming languages. - -Using a full-featured editor such as VS Code provides many advantages over a plain text editor, such as: -* intelligent code completion -* convenient navigation in the code -* refactoring tools -* build automation (no need for the command-line) -* a graphical front end for GIT -* many other tools such as debugging, code formatting, showing call hierarchies etc. - -The purpose of this page is to document how to set up VS Code for developing QMK Firmware. - -This guide covers how to configure everything needed on Windows and Ubuntu 18.04 - -# Set up VS Code -Before starting, you will want to make sure that you have all of the build tools set up, and QMK Firmware cloned. Head to the [Newbs Getting Started Guide](newbs_getting_started.md) to get things set up, if you haven't already. - -## Windows - -### Prerequisites - -* [Git for Windows](https://git-scm.com/download/win) (This link will prompt to save/run the installer) - - 1. Disable all of the options but `Git LFS (Large File Support)` and `Check daily for Git for Windows updates`. - 2. Set the default editor to `Use Visual Studio Code as Git's default editor` - 3. Select the `Use Git from Git Bash only` option, since that's the option that you should use here. - 4. For the `Choosing HTTPS transport backend`, either option should be fine. - 5. Select the `Checkout as-is, commit Unix-style line endings` option. QMK Firmware uses Unix style commits. - 6. For the extra options, leave the default options as is. - - This software is needed for Git support in VS Code. It may be possible to not include this, but it is much simpler to just use this. - -* [Git Credential Manager for Windows](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases) (Optional) - - This software provides better support for Git by providing secure storage for git credentials, MFA and personal access token generation. - - This isn't strictly needed, but we would recommend it. - - -### Installing VS Code - -1. Head to [VS Code](https://code.visualstudio.com/) and download the installer -2. Run the installer - -This part is super simple. However, there is some configuration that we need to do to ensure things are configured correctly. - -#### MSYS2 Setup - -Now, we will set up the MSYS2 window to show up in VSCode as the integrated terminal. This has a number of advantages. Mostly, you can control+click on errors and jump to those files. This makes debugging much easier. It's also nice, in that you don't have to jump to another window. - -1. Click File > Preferences > > Settings -2. Click on the {} button, in the top right to open the `settings.json` file. -3. Set the file's content to: - - ```json - { - "terminal.integrated.profiles.windows": { - "QMK_MSYS": { - "path": "C:/QMK_MSYS/usr/bin/bash.exe", - "env": { - "MSYSTEM": "MINGW64", - "CHERE_INVOKING": "1" - }, - "args": ["--login"] - } - }, - - "terminal.integrated.cursorStyle": "line" - } - ``` - - If there are settings here already, then just add everything between the first and last curly brackets and separate the existing settings with a comma from the newly added ones. - -?> If you installed MSYS2 to a different folder, then you'll need to change the path for `terminal.integrated.shell.windows` to the correct path for your system. - -4. Hit Ctrl-` (Grave) to bring up the terminal or go to View > Terminal (command `workbench.action.terminal.toggleTerminal`). A new terminal will be opened if there isn‘t one already. - - This should start the terminal in the workspace's folder (so the `qmk_firmware` folder), and then you can compile your keyboard. - - -## Every other Operating System - -1. Head to [VS Code](https://code.visualstudio.com/) and download the installer -2. Run the installer -3. That's it - -No, really, that's it. The paths needed are already included when installing the packages, and it is much better about detecting the current workspace files and parsing them for IntelliSense. - -## Extensions - -There are a number of extensions that you may want to install: - -* [Git Extension Pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack) - This installs a bunch of Git related tools that may make using Git with QMK Firmware easier. -* [clangd](https://marketplace.visualstudio.com/items?itemName=llvm-vs-code-extensions.vscode-clangd) - _[Optional]_ - This is the language server for C/C++ that VS Code uses. It provides IntelliSense and other features. -* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - _[Optional]_ - Helps to keep the code to the QMK Coding Conventions. -* [GitHub Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview) - _[Optional]_ - Makes the markdown preview in VS Code more like GitHub's. -* [VS Live Share Extension Pack](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) - _[Optional]_ - This extension allows somebody else to access your workspace (or you to access somebody else's workspace) and help out. This is great if you're having issues and need some help from somebody. - -Restart once you've installed any extensions. - -# Configure VS Code for QMK - -1. Click File > Open Folder -2. Open the QMK Firmware folder that you cloned from GitHub. -3. Click File > Save Workspace As... - -## Configuring VS Code - -Using the [standard `compile_commands.json` database](https://clang.llvm.org/docs/JSONCompilationDatabase.html), we can get the VS code _clangd_ extension to use the correct includes and defines used for your keyboard and keymap. - -1. Run `qmk generate-compilation-database -kb -km ` to generate the `compile_commands.json`. -1. Inside VS code, press Ctrl + Shift + P (macOS: Command + Shift + P) to open the command palette. -1. Start typing `clangd: Download Language Server` and select it when it appears. Note that this only needs to be done once on clangd extension installation, if it didn't already ask to do so. -1. Inside VS code, press Ctrl + Shift + P (macOS: Command + Shift + P) to open the command palette. -1. Start typing `clangd: Restart Language Server` and select it when it appears. - -Now you're ready to code QMK Firmware in VS Code! diff --git a/docs/platformdev_blackpill_f4x1.md b/docs/platformdev_blackpill_f4x1.md deleted file mode 100644 index a8d21c255c7d..000000000000 --- a/docs/platformdev_blackpill_f4x1.md +++ /dev/null @@ -1,49 +0,0 @@ -# WeAct Blackpill (STM32F4x1) - -This document applies to the F401- and F411-based Blackpills. - -The WeAct Blackpill is a popular choice for handwired boards, as it offers a powerful micro controller, USB Type C, a good number of pins to use, and a large amount of firmware space. All for a ~$6 USD price tag. - -* [WeAct GitHub for F4x1 Blackpill](https://github.com/WeActStudio/WeActStudio.MiniSTM32F4x1) - * Unfortunately, due to supply issues official WeAct F411 based blackpills may not be available. - -![Blackpill F411](https://i.imgur.com/nCgeolTh.png) - - -## Pin Usage Limitations - -While the Blackpill is a great choice to use in your keyboard, there are a number of caveats in regards to using them. The first is that a number of exposed pins cannot be used, or have special considerations/hardware tweaks that are required for proper operation. - -### Unusable pins -* Pins `A11` and `A12` are not usable because they're used for USB connection, and cannot be shared. - * In theory, these pins can be used. However, doing so may disable USB connectivity, outright, if used for anything other than a USB port -* Pin `B2` is used by `BOOT1` and cannot be used, without causing problems. -* `VBAT` is not a usable pin. -* `NRST` is not a usable pin. - -### Pins to be avoided -* Pin `A9` is meant for VBUS Sense and should not be used, if it can be avoided. It has an internal pull-down resistor, which may cause issues with usage. However, a pull-up resistor can work (~5.1k), but should be avoided. -* Pin `A10` can be used, but should be avoided. Any connection on this pin can prevent the bootloader from entering the proper mode for DFU flashing. A pull-up resistor (~22k) on this pin fixes the bootloader issue. - -### Shared Usage -* Pin `A0` is shared with the User Key (button) on the controller. It can be used. -* Pin `C13` is shared with the onboard LED indicator, and is connected to +3.3V. This can be used, but may cause the LED to blink intermittently, depending on activity on the pin. -* Pins `A4`, `A5`, `A6` and `A7` are used by the SOI8 footprint on the back of the controller, that can be used for either an SPI Flash chip, or an SPI EEPROM chip. `A4` is the Chip Select pin, and cannot be shared. However, `A5`, `A6`, and `A7` are the `SCK`, `MISO`, and `MOSI` pins, respectively, and can be shared with other SPI devices. - -### Limited Usage -* Pins `C13`, `C14`, and `C15` have limits on output current. They should be used only as input, e.g., they should not be used for row pins in COL2ROW matrix configurations, but can be used as column pins. - * This is because the column pins (in COL2ROW) are pulled up (the pull-up strength is independent of the current sourcing limitation) and the ROW is driven low and sinks current, then we check the state of the COLs to look for keypresses. - -* Pins `A0` and `B5` are not 5V tolerant, and should only be used with 3.3V compatible functionality. - -## Additional Information - -### Bootloader issues - -Due to the use of a 25MHz crystal, the controller may have issues entering the bootloader. Heating up the controller can help with this issue. - -Also, if pin `A10` is connected to anything at all, it needs to have a pull-up resistor (see [Pins to be avoided](#pins-to-be-avoided), above) - -### Tiny UF2 Support - -There is [tinyuf2 support for the WeAct Blackpill](https://github.com/adafruit/tinyuf2/tree/master/ports/stm32f4/boards/stm32f411ce_blackpill). Instructions on how to compile the bootloader can be found [here](https://github.com/adafruit/tinyuf2#build-and-flash). Setting `BOOTLOADER = tinyuf2` will enable support for this user bootloader, and the correct configuration to prevent it from being overwritten when flashing firmware. diff --git a/docs/platformdev_chibios_earlyinit.md b/docs/platformdev_chibios_earlyinit.md deleted file mode 100644 index bc4924722271..000000000000 --- a/docs/platformdev_chibios_earlyinit.md +++ /dev/null @@ -1,63 +0,0 @@ -# Arm/ChibiOS Early Initialization :id=chibios-early-init - -This page describes a part of QMK that is a somewhat advanced concept, and is only relevant to keyboard designers. - -QMK uses ChibiOS as the underlying layer to support a multitude of Arm-based devices. Each ChibiOS-supported keyboard has a low-level board definition which is responsible for initializing hardware peripherals such as the clocks, and GPIOs. - -Older QMK revisions required duplication of these board definitions inside your keyboard's directory in order to override such early initialization points; this is now abstracted into the following APIs, and allows usage of the board definitions supplied with ChibiOS itself. Check `/lib/chibios/os/hal/boards` for the list of official definitions. If your keyboard needs extra initialization at a very early stage, consider providing keyboard-level overrides of the following APIs instead of duplicating the board definitions: - -## `early_hardware_init_pre()` :id=early-hardware-init-pre - -The function `early_hardware_init_pre` is the earliest possible code that can be executed by a keyboard firmware. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the start of the function. - -This is executed before RAM gets cleared, and before clocks or GPIOs are configured; for example, ChibiOS delays are not likely to work at this point. After executing this function, RAM on the MCU may be zero'ed. Assigning values to variables during execution of this function may be overwritten. - -As such, if you wish to override this API consider limiting use to writing to low-level registers. The default implementation of this function can be configured to jump to bootloader if a `QK_BOOT` key was pressed: - -| `config.h` override | Description | Default | -|-----------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------| -| `#define EARLY_INIT_PERFORM_BOOTLOADER_JUMP` | Whether or not bootloader is to be executed during the early initialisation code of QMK. | `FALSE` | -| `#define STM32_BOOTLOADER_DUAL_BANK` | Relevant for dual-bank STM32 MCUs, signifies that a GPIO is to be toggled in order to enter bootloader mode. | `FALSE` | -| `#define STM32_BOOTLOADER_DUAL_BANK_GPIO` | Relevant for dual-bank STM32 MCUs, the pin to toggle when attempting to enter bootloader mode, e.g. `B8` | `` | -| `#define STM32_BOOTLOADER_DUAL_BANK_POLARITY` | Relevant for dual-bank STM32 MCUs, the value to set the pin to in order to trigger charging of the RC circuit. e.g. `0` or `1`. | `0` | -| `#define STM32_BOOTLOADER_DUAL_BANK_DELAY` | Relevant for dual-bank STM32 MCUs, an arbitrary measurement of time to delay before resetting the MCU. Increasing number increases the delay. | `100` | - -Kinetis MCUs have no configurable options. - -Alternatively, to implement your own version of this function, in your keyboard's source files: - -```c -void early_hardware_init_pre(void) { - // do things with registers -} -``` - -## `early_hardware_init_post()` :id=early-hardware-init-post - -The function `early_hardware_init_post` is the next earliest possible code that can be executed by a keyboard firmware. This is executed after RAM has been cleared, and clocks and GPIOs are configured. This is intended as a replacement for the ChibiOS board definition's `__early_init` function, and is the equivalent of executing at the end of the function. - -Much like `early_hardware_init_pre`, ChibiOS has not yet been initialized either, so the same restrictions on delays and timing apply. - -If you wish to override this API, consider limiting functionality to register writes, variable initialization, and GPIO toggling. The default implementation of this function is to do nothing. - -To implement your own version of this function, in your keyboard's source files: - -```c -void early_hardware_init_post(void) { - // toggle GPIO pins and write to variables -} -``` - -## `board_init()` :id=board-init - -The function `board_init` is executed directly after the ChibiOS initialization routines have completed. At this stage, all normal low-level functionality should be available for use (including timers and delays), with the restriction that USB is not yet connected. This is intended as a replacement for the ChibiOS board definition's `boardInit` function. - -The default implementation of this function is to do nothing. - -To implement your own version of this function, in your keyboard's source files: - -```c -void board_init(void) { - // initialize anything that requires ChibiOS -} -``` diff --git a/docs/platformdev_proton_c.md b/docs/platformdev_proton_c.md deleted file mode 100644 index 3afec893fa6d..000000000000 --- a/docs/platformdev_proton_c.md +++ /dev/null @@ -1,77 +0,0 @@ -# Proton C - -The Proton C is an Arm STM32F303xC based drop-in replacement for the Pro Micro. - -Proton C - -#### Features - -* Through-hole mounted USB-C Port -* 32-bit 72MHz Cortex-M4 processor (STM32F303CCT6) -* I2C, SPI, PWM, DMA, DAC, USART, I2S -* 23x 3.3V I/O Ports -* 1x 5V output for WS2812 LED chains -* 256kB flash -* 40kB RAM -* AST1109MLTRQ speaker footprint -* Reset button - -## Warnings - -Some of the PCBs compatible with Pro Micro have VCC (3.3V) and RAW (5V) pins connected (shorted) on the pcb. Using the Proton C will short 5V power from USB and regulated 3.3V which is connected directly to the MCU. Shorting those pins may damage the MCU on the Proton C. - -So far, it appears that this is only an issue on the Gherkin PCBs, but other PCBs may be affected in this way. - -In this case, you may want to not hook up the RAW pin at all. - -## Manual Conversion - -To use the Proton C natively, without having to specify `CONVERT_TO=proton_c`, you need to change the `MCU` line in `rules.mk`: - -``` -MCU = STM32F303 -BOARD = QMK_PROTON_C -``` - -Remove these variables if they exist: - -* `BOOTLOADER` -* `EXTRA_FLAGS` - -Finally convert all pin assignments in `config.h` to the stm32 equivalents. - -| Pro Micro Left | Proton C Left | | Proton C Right | Pro Micro Right | -|-----------|----------|-|----------|-----------| -| `D3` | `A9` | | 5v | RAW (5v) | -| `D2` | `A10` | | GND | GND | -| GND | GND | | FLASH | RESET | -| GND | GND | | 3.3v | VCC 1 | -| `D1` | `B7` | | `A2` | `F4` | -| `D0` | `B6` | | `A1` | `F5` | -| `D4` | `B5` | | `A0` | `F6` | -| `C6` | `B4` | | `B8` | `F7` | -| `D7` | `B3` | | `B13` | `B1` | -| `E6` | `B2` | | `B14` | `B3` | -| `B4` | `B1` | | `B15` | `B2` | -| `B5` | `B0` | | `B9` | `B6` | -| `B0` (RX LED) | `C13` 2 | | `C13` 2 | `D5` (TX LED) | - -You can also make use of several new pins on the extended portion of the Proton C: - -| Left | | Right | -|------|-|-------| -| `A4`3 | | `B10` | -| `A5`4 | | `B11` | -| `A6` | | `B12` | -| `A7` | | `A14`5 (SWCLK) | -| `A8` | | `A13`5 (SWDIO) | -| `A15` | | RESET6 | - -Notes: - -1. On a Pro Micro VCC can be 3.3v or 5v. -2. A Proton C only has one onboard LED, not two like a Pro Micro. The Pro Micro has an RX LED on `D5` and a TX LED on `B0`. -3. `A4` is shared with the speaker. -4. `A5` is shared with the speaker. -5. `A13` and `A14` are used for hardware debugging (SWD). You can also use them for GPIO, but should use them last. -6. Short RESET to 3.3v (pull high) to reboot the MCU. This does not enter bootloader mode like a Pro Micro, it only resets the MCU. diff --git a/docs/platformdev_rp2040.md b/docs/platformdev_rp2040.md deleted file mode 100644 index 890dadb6f066..000000000000 --- a/docs/platformdev_rp2040.md +++ /dev/null @@ -1,141 +0,0 @@ -# Raspberry Pi RP2040 - -The following table shows the current driver status for peripherals on RP2040 MCUs: - -| System | Support | -| ---------------------------------------------------------------- | ---------------------------------------------- | -| [ADC driver](adc_driver.md) | :heavy_check_mark: | -| [Audio](audio_driver.md#pwm-hardware) | :heavy_check_mark: | -| [Backlight](feature_backlight.md) | :heavy_check_mark: | -| [I2C driver](i2c_driver.md) | :heavy_check_mark: | -| [SPI driver](spi_driver.md) | :heavy_check_mark: | -| [WS2812 driver](ws2812_driver.md) | :heavy_check_mark: using `PIO` driver | -| [External EEPROMs](eeprom_driver.md) | :heavy_check_mark: using `I2C` or `SPI` driver | -| [EEPROM emulation](eeprom_driver.md#wear_leveling-configuration) | :heavy_check_mark: | -| [serial driver](serial_driver.md) | :heavy_check_mark: using `SIO` or `PIO` driver | -| [UART driver](uart_driver.md) | Support planned (no ETA) | - -## GPIO - -Raspberry Pi Pico pinout -Sparkfun RP2040 Pro Micro pinout - -!> The GPIO pins of the RP2040 are not 5V tolerant! - -### Pin nomenclature - -To address individual pins on the RP2040, QMK uses the `GPx` abbreviation -- where the `x` stands for the GPIO number of the pin. This number can likely be found on the official pinout diagram of your board. Note that these GPIO numbers match the RP2040 MCU datasheet, and don't necessarily match the number you see printed on the board. For instance the Raspberry Pi Pico uses numbers from 1 to 40 for their pins, but these are not identical to the RP2040's GPIO numbers. So if you want to use the pin 11 of the Pico for your keyboard, you would refer to it as `GP8` in the config files. - -### Alternate functions - -The RP2040 features flexible GPIO function multiplexing, this means that every pin can be connected to nearly all the internal peripherals like I2C, SPI, UART or PWM. This allows for flexible PCB designs that are much less restricted in the selection of GPIO pins. To find out which pin can use which peripheral refer to the official [Raspberry PI RP2040 datasheet](https://datasheets.raspberrypi.com/rp2040/rp2040-datasheet.pdf#page=14) section 1.4.3 GPIO functions. - -## Selecting hardware peripherals and drivers - -QMK RP2040 support builds upon ChibiOS and thus follows their convention for activating drivers and associated hardware peripherals. These tables only give a quick overview which values have to be used, please refer to the ChibiOS specific sections on the driver pages. - -### I2C Driver - -| RP2040 Peripheral | `mcuconf.h` values | `I2C_DRIVER` | -| ----------------- | ------------------ | ------------ | -| `I2C0` | `RP_I2C_USE_I2C0` | `I2CD0` | -| `I2C1` | `RP_I2C_USE_I2C1` | `I2CD1` | - -To configure the I2C driver please read the [ChibiOS/ARM](i2c_driver.md#arm-configuration) section. - -### SPI Driver - -| RP2040 Peripheral | `mcuconf.h` values | `SPI_DRIVER` | -| ----------------- | ------------------ | ------------ | -| `SPI0` | `RP_SPI_USE_SPI0` | `SPID0` | -| `SPI1` | `RP_SPI_USE_SPI1` | `SPID1` | - -To configure the SPI driver please read the [ChibiOS/ARM](spi_driver.md#chibiosarm-configuration) section. - -## Double-tap reset boot-loader entry :id=double-tap - -The double-tap reset mechanism is an alternate way in QMK to enter the embedded mass storage UF2 boot-loader of the RP2040. It enables bootloader entry by a fast double-tap of the reset pin on start up, which is similar to the behavior of AVR Pro Micros. This feature activated by default for the Pro Micro RP2040 board, but has to be configured for other boards. To activate it, add the following options to your keyboards `config.h` file: - -```c -#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET // Activates the double-tap behavior -#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_TIMEOUT 200U // Timeout window in ms in which the double tap can occur. -#define RP2040_BOOTLOADER_DOUBLE_TAP_RESET_LED GP17 // Specify a optional status led by GPIO number which blinks when entering the bootloader -``` - -## Pre-defined RP2040 boards - -QMK defines two boards that you can choose from to base your RP2040 powered keyboard upon. These boards provide pre-configured default pins and drivers. - -### Generic Pro Micro RP2040 - -This is the default board that is chosen, unless any other RP2040 board is selected in your keyboards `rules.mk` file. It assumes a pin layout for the I2C, SPI and Serial drivers which is identical to the Sparkfun Pro Micro RP2040, however all values can be overwritten by defining them in your keyboards `config.h` file. The [double-tap](#double-tap) reset to enter boot-loader behavior is activated by default. - - -| Driver configuration define | Value | -| -------------------------------------------------------------------------- | ------------------------------------ | -| **I2C driver** | | -| `I2C_DRIVER` | `I2CD1` | -| `I2C1_SDA_PIN` | `GP2` | -| `I2C1_SCL_PIN` | `GP3` | -| **SPI driver** | | -| `SPI_DRIVER` | `SPID0` | -| `SPI_SCK_PIN` | `GP18` | -| `SPI_MISO_PIN` | `GP20` | -| `SPI_MOSI_PIN` | `GP19` | -| **Serial driver** | | -| `SERIAL_USART_DRIVER` ([SIO Driver](serial_driver.md#the-sio-driver) only) | `SIOD0` | -| `SOFT_SERIAL_PIN` | undefined, use `SERIAL_USART_TX_PIN` | -| `SERIAL_USART_TX_PIN` | `GP0` | -| `SERIAL_USART_RX_PIN` | `GP1` | - -?> The pin-outs of Adafruit's KB2040 and Boardsource's Blok both deviate from the Sparkfun Pro Micro RP2040. Lookup the pin-out of these boards and adjust your keyboards pin definition accordingly if you want to use these boards. - -### Generic RP2040 board - -This board can be chosen as a base for RP2040 keyboards which configure all necessary pins and drivers themselves and do not wish to leverage the configuration matching the Generic Pro Micro RP2040 board. Thus it doesn't provide any pre-configured pins or drivers. To select this board add the following line to your keyboards `rules.mk` file. - -```make -BOARD = GENERIC_RP_RP2040 -``` - -## Split keyboard support - -Split keyboards are fully supported using the [serial driver](serial_driver.md) in both full-duplex and half-duplex configurations. Two driver subsystems are supported by the RP2040, the hardware UART based `SIO` and the Programmable IO based `PIO` driver. - -| Feature | [SIO Driver](serial_driver.md#the-sio-driver) | [PIO Driver](serial_driver.md#the-pio-driver) | -| ----------------------------- | --------------------------------------------- | --------------------------------------------- | -| Half-Duplex operation | | :heavy_check_mark: | -| Full-Duplex operation | :heavy_check_mark: | :heavy_check_mark: | -| `TX` and `RX` pin swapping | | :heavy_check_mark: | -| Any GPIO as `TX` and `RX` pin | Only UART capable pins | :heavy_check_mark: | -| Simple configuration | | :heavy_check_mark: | - -The `PIO` driver is much more flexible then the `SIO` driver, the only "downside" is the usage of `PIO` resources which in turn are not available for advanced user programs. Under normal circumstances, this resource allocation will be a non-issue. - -## RP2040 second stage bootloader selection - -As the RP2040 does not have any internal flash memory it depends on an external SPI flash memory chip to store and execute instructions from. To successfully interact with a wide variety of these chips a second stage bootloader that is compatible with the chosen external flash memory has to be supplied with each firmware image. By default an `W25Q080` compatible bootloader is assumed, but others can be chosen by adding one of the defines listed in the table below to your keyboards `config.h` file. - -| Compatible with flash chip | Selection | -| :------------------------- | ---------------------------------- | -| W25Q080 | Selected by default | -| AT25SF128A | `#define RP2040_FLASH_AT25SF128A` | -| GD25Q64CS | `#define RP2040_FLASH_GD25Q64CS` | -| W25X10CL | `#define RP2040_FLASH_W25X10CL` | -| IS25LP080 | `#define RP2040_FLASH_IS25LP080` | -| Generic 03H flash | `#define RP2040_FLASH_GENERIC_03H` | - -## RP2040 Community Edition :id=rp2040_ce - -The "RP2040 Community Edition" standard is a pinout that was defined by a committee of designers on the BastardKB Discord server. - -These boards are designed to be a drop-in replacement for keyboards wanting an upgrade from ATmega32u4 based pro micros (eg. Elite-C). - -| Pinout Compatible Controllers | -| -------------------------------------------------------------------------------- | -| [0xB2 Splinky](https://github.com/plut0nium/0xB2/) | -| [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) | -| [Sea-Picro EXT](https://github.com/joshajohnson/sea-picro) | -| [0xCB Helios](https://keeb.supply/products/0xcb-helios) | -| [Frood](https://github.com/piit79/Frood) | -| [Liatris](https://splitkb.com/products/liatris) | diff --git a/docs/platformdev_selecting_arm_mcu.md b/docs/platformdev_selecting_arm_mcu.md deleted file mode 100644 index c115aa6e0fdf..000000000000 --- a/docs/platformdev_selecting_arm_mcu.md +++ /dev/null @@ -1,58 +0,0 @@ -# Choosing an Arm MCU :id=choose-arm-mcu - -This page outlines the selection criteria to ensure compatibility with Arm/ChibiOS. - -QMK uses the Hardware Abstraction Layer of ChibiOS in order to run on Arm devices. ChibiOS in general is best supported on STM32 devices, both in the perspective of base MCU support, as well as on-MCU peripheral support. As an extension to the core ChibiOS MCU support, QMK also utilises ChibiOS-Contrib (which includes the Kinetis MCU support layer, as an example), but it does not provide as great a level of peripheral support or general testing for supported devices. - -Adding support for new MCU families must go through ChibiOS or ChibiOS-Contrib -- QMK does not have the bandwidth, resources, nor the inclination to maintain long-term MCU support for your board of choice. - -To be clear: this also includes commercial boards -- unless agreed upon by all parties, QMK will not take over maintenance of a bespoke MCU support package. Even if MCU support is upstreamed into ChibiOS/ChibiOS-Contrib, QMK reserves the right to deprecate and/or remove keyboards utilising support packages that aren't kept up to date with upstream ChibiOS itself. - -## Selecting an already-supported MCU :id=selecting-already-supported-mcu - -### STM32 families - -As outlined earlier, STM32 is the preferred option to ensure greatest compatibility with the subsystems already implemented in QMK. Not all subsystems are compatible yet, but for the most widely-used support is already present. - -The simplest solution to determine if an STM32 MCU is compatible is to navigate to the list of supported STM32 ports in QMK's [ChibiOS fork](https://github.com/qmk/ChibiOS/tree/master/os/hal/ports/STM32). Inside this directory, each of the supported STM32 families will be listed, and inside each family a file called `stm32_registry.h` will be present. Scanning through these files will show `#define`s such as the following, which can be used to determine if ChibiOS supports a particular MCU: - -```c -#if defined(STM32F303xC) || defined(__DOXYGEN__) -``` - -The example shows that STM32F303xC devices are supported by ChibiOS. - -The next step is to ensure that USB is supported on those devices by ChibiOS -- you can confirm this by checking inside the same section guarded by the `#define` above, specifically for the following to be `TRUE`: - -```c -#define STM32_HAS_USB TRUE -``` - -or one of the following being `TRUE`: - -```c -#define STM32_HAS_OTG1 TRUE -#define STM32_HAS_OTG2 TRUE -``` - -For the most part, this is the bare minimum to be able to have a high confidence that QMK will be able to run on your MCU. After that, it's all up to configuration. - -### Non-STM32 families - -ChibiOS does have support for a handful of non-STM32 devices, and the list can be found in QMK's [ChibiOS fork](https://github.com/qmk/ChibiOS/tree/master/os/hal/ports) and [ChibiOS-Contrib fork](https://github.com/qmk/ChibiOS-Contrib/tree/master/os/hal/ports). Non-STM32 support is likely out of date, and only supports ancient MCUs -- whilst it might be possible to use these, it's not recommended. - -Do note that there are sometimes licensing restrictions with respect to redistribution. As an example, binaries built for nRF5 are not able to be redistributed via QMK Configurator, due to the licensing of their board support package. - -## Adding support for a new STM32 MCU (for an existing family) :id=add-new-stm32-mcu - -Usually, one can "masquerade" as an existing MCU of the same family, especially if the only difference is RAM or Flash size. As an example, some MCUs within the same family are virtually identical, with the exception of adding a cryptographic peripheral -- STM32L072 vs. STM32L082 for instance. Given the unlikely use of the cryptographic peripheral, L082 chips can actually run as if they're an L072, and can be targeted accordingly. - -Adding proper support for new MCUs within an existing STM32 family should ideally be upstreamed to ChibiOS. In general, this will require modifications of the `stm32_registry.h` file, providing correct responses for the same `#define`s provided for the other MCUs in that family. - -## Adding support for a new STM32 Family :id=add-new-stm32-family - -If this is a requirement, this needs to go through upstream ChibiOS before QMK would consider accepting boards targeting the new family. More information for porting should be sought by approaching ChibiOS directly, rather than through QMK. - -## Adding support for a new MCU Family :id=add-new-mcu-family - -As stated earlier, in order for a new MCU family to be supported by QMK, it needs to be upstreamed into ChibiOS-Contrib before QMK will consider accepting boards using it. The same principle applies for development -- you're best approaching the ChibiOS-Contrib maintainers to get a bit more of an idea on what's involved with upstreaming your contribution. diff --git a/docs/porting_your_keyboard_to_qmk.md b/docs/porting_your_keyboard_to_qmk.md deleted file mode 100644 index b0213a6d7005..000000000000 --- a/docs/porting_your_keyboard_to_qmk.md +++ /dev/null @@ -1,164 +0,0 @@ -# Adding Your Keyboard to QMK - -This page describes the support for [Compatible Microcontrollers](compatible_microcontrollers.md) in QMK. - -If you have not yet you should read the [Keyboard Guidelines](hardware_keyboard_guidelines.md) to get a sense of how keyboards fit into QMK. - - -QMK has a number of features to simplify working with keyboards. For most, you don't have to write a single line of code. To get started, run `qmk new-keyboard`: - -``` -$ qmk new-keyboard -Ψ Generating a new QMK keyboard directory - -Name Your Keyboard Project -For more infomation, see: -https://docs.qmk.fm/#/hardware_keyboard_guidelines?id=naming-your-keyboardproject - -keyboard Name? mycoolkeeb - -Attribution -Used for maintainer, copyright, etc - -Your GitHub Username? [jsmith] - -More Attribution -Used for maintainer, copyright, etc - -Your Real Name? [John Smith] - -Pick Base Layout -As a starting point, one of the common layouts can be used to bootstrap the process - -Default Layout? - 1. 60_ansi -... - 50. tkl_iso - 51. none of the above -Please enter your choice: [51] - -What Powers Your Project -For more infomation, see: -https://docs.qmk.fm/#/compatible_microcontrollers - -MCU? - 1. atmega32u4 -... - 22. STM32F303 -Please enter your choice: [12] -Ψ Created a new keyboard called mycoolkeeb. -Ψ To start working on things, `cd` into keyboards/mycoolkeeb, -Ψ or open the directory in your preferred text editor. -Ψ And build with qmk compile -kb mycoolkeeb -km default. -``` - -This will create all the files needed to support your new keyboard, and populate the settings with default values. Now you just need to customize it for your keyboard. - -## `readme.md` - -This is where you'll describe your keyboard. Please follow the [Keyboard Readme Template](documentation_templates.md#keyboard-readmemd-template) when writing your `readme.md`. You're encouraged to place an image at the top of your `readme.md`, please use an external service such as [Imgur](https://imgur.com) to host the images. - -## `info.json` - -The `info.json` file is where you configure the hardware and feature set for your keyboard. There are a lot of options that can be placed in that file, too many to list here. For a complete overview of available options see the [Data Driven Configuration Options](reference_info_json.md) page. - -### Hardware Configuration - -At the top of the `info.json` you'll find USB related settings. These control how your keyboard appears to the Operating System. If you don't have a good reason to change you should leave the `usb.vid` as `0xFEED`. For the `usb.pid` you should pick a number that is not yet in use. - -Do change the `manufacturer` and `keyboard_name` lines to accurately reflect your keyboard. - -```json - "keyboard_name": "my_awesome_keyboard", - "maintainer": "You", - "usb": { - "vid": "0xFEED", - "pid": "0x0000", - "device_version": "1.0.0" - }, -``` - -?> Windows and macOS will display the `manufacturer` and `keyboard_name` in the list of USB devices. `lsusb` on Linux instead prefers the values in the list maintained by the [USB ID Repository](http://www.linux-usb.org/usb-ids.html). By default, it will only use `manufacturer` and `keyboard_name` if the list does not contain that `usb.vid` / `usb.pid`. `sudo lsusb -v` will show the values reported by the device, and they are also present in kernel logs after plugging it in. - - -### Matrix Configuration - -The next section of the `info` file deals with your keyboard's matrix. The first thing you should define is which pins on your MCU are connected to rows and columns. To do so simply specify the names of those pins: - -```json - "matrix_pins": { - "cols": ["C1", "C2", "C3", "C4"], - "rows": ["D1", "D2", "D3", "D4"] - }, -``` - -The size of the `matrix_pins.cols` and `matrix_pins.rows` arrays infer the size of the matrix (previously `MATRIX_ROWS` and `MATRIX_COLS`). - -Finally, you can specify the direction your diodes point. This can be `COL2ROW` or `ROW2COL`. - -```json - "diode_direction": "ROW2COL", -``` - -#### Direct Pin Matrix -To configure a keyboard where each switch is connected to a separate pin and ground instead of sharing row and column pins, use `matrix_pins.direct`. The mapping defines the pins of each switch in rows and columns, from left to right. The size of the `matrix_pins.direct` array infers the size of the matrix. Use `NO_PIN` to fill in blank spaces. Overrides the behaviour of `diode_direction`, `matrix_pins.cols` and `matrix_pins.rows`. - -```json - "matrix_pins": { - "direct": [ - ["F1", "E6", "B0", "B2", "B3" ], - ["F5", "F0", "B1", "B7", "D2" ], - ["F6", "F7", "C7", "D5", "D3" ], - ["B5", "C6", "B6", "NO_PIN", "NO_PIN"] - ] - }, -``` - -### Layout macros - -Next is configuring Layout Macro(s). These define the physical arrangement of keys, and its position within the matrix that a switch are connected to. This allows you to have a physical arrangement of keys that differs from the wiring matrix. - -```json - "layouts": { - "LAYOUT_ortho_4x4": { - "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": [1, 3], "x": 3, "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": [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 } - ] - } - } - -``` - -In the above example, - -* `LAYOUT_ortho_4x4` defines the name of the layout macro - * It must conform to the [layout guidelines](hardware_keyboard_guidelines.md#ltkeyboard_namehgt) -* `"matrix": [0, 0]` defines the electrical position - -?> See also: [Split Keyboard Layout Macro](https://docs.qmk.fm/#/feature_split_keyboard?id=layout-macro) and [Matrix to Physical Layout](https://docs.qmk.fm/#/understanding_qmk?id=matrix-to-physical-layout-map). - -## Additional Configuration - -There are a lot of features that can be turned on or off, configured or tuned. Some of these have yet to be migrated over to [Data Driven Configuration](data_driven_config.md). The following sections cover the process for when an `info.json` option is unavailable. - -### Configuration Options -For available options for `config.h`, you should see the [Config Options](config_options.md#the-configh-file) page for more details. - -### Build Options - -For available options for `rules.mk`, see the [Config Options](config_options.md#feature-options) page for a detailed list and description. diff --git a/docs/power.txt b/docs/power.txt deleted file mode 100644 index ff28ba0c7f1c..000000000000 --- a/docs/power.txt +++ /dev/null @@ -1,62 +0,0 @@ -Time to Sleep -============= -USB suspend no activity on USB line for 3ms -No Interaction no user interaction - matrix has no change - matrix has no switch on - - -AVR Power Management -==================== - -V-USB suspend - USB suspend - http://vusb.wikidot.com/examples - -MCUSR MCU Status Register - WDRF Watchdog Reset Flag - BORF - EXTRF - PORF Power-on Reset Flag - -SMCR Sleep Mode Control Register - SE Sleep Enable - SM2:0 - #define set_sleep_mode(mode) \ - #define SLEEP_MODE_IDLE (0) - #define SLEEP_MODE_ADC _BV(SM0) - #define SLEEP_MODE_PWR_DOWN _BV(SM1) - #define SLEEP_MODE_PWR_SAVE (_BV(SM0) | _BV(SM1)) - #define SLEEP_MODE_STANDBY (_BV(SM1) | _BV(SM2)) - #define SLEEP_MODE_EXT_STANDBY (_BV(SM0) | _BV(SM1) | _BV(SM2)) - - -ACSR Analog Comparator Control and Status Register - To disable Analog Comparator - ACSR = 0x80; - or - ACSR &= ~_BV(ACIE); - ACSR |= _BV(ACD); - - ACD: Analog Comparator Disable - When this bit is written logic one, the power to the Analog Comparator is - switched off. This bit can be set at any time to turn off the Analog - Comparator. This will reduce power consumption in Active and Idle mode. - When changing the ACD bit, the Analog Comparator Interrupt must be disabled - by clearing the ACIE bit in ACSR. Otherwise an interrupt can occur when - the bit is changed. - -DIDR1 Digital Input Disable Register 1 - AIN1D - AIN0D - When this bit is written logic one, the digital input buffer on the AIN1/0 pin is disabled. The corresponding PIN Register bit will always read as zero when this bit is set. When an analog signal is applied to the AIN1/0 pin and the digital input from this pin is not needed, this bit should be written logic one to reduce power consumption in the digital input buffer. - - -PRR Power Reduction Register - PRTWI - PRTIM2 - PRTIM0 - PRTIM1 - PRSPI - PRUSART0 - PRADC diff --git a/docs/pr_checklist.md b/docs/pr_checklist.md deleted file mode 100644 index 65584a953812..000000000000 --- a/docs/pr_checklist.md +++ /dev/null @@ -1,226 +0,0 @@ -# PR checklists - -This is a non-exhaustive checklist of what the QMK Collaborators will be checking when reviewing submitted PRs. - -If there are any inconsistencies with these recommendations, you're best off [creating an issue](https://github.com/qmk/qmk_firmware/issues/new) against this document, or getting in touch with a QMK Collaborator on [Discord](https://discord.gg/Uq7gcHh). - -## Requirements for all PRs - -- PR should be submitted using a non-`master` branch on the source repository - - this does not mean you target a different branch for your PR, rather that you're not working out of your own master branch - - if submitter _does_ use their own `master` branch, they'll be given a link to the ["how to git"](newbs_git_using_your_master_branch.md) page after merging -- (end of this document will contain the contents of the message) -- PRs should contain the smallest amount of modifications required for a single change to the codebase - - multiple keyboards at the same time is not acceptable - - exception: keymaps for a single user targeting multiple keyboards and/or userspace is acceptable - - **the smaller the PR, the higher likelihood of a quicker review, higher likelihood of quicker merge, and less chance of conflicts** -- newly-added directories and filenames must be lowercase - - the lowercase requirement may be relaxed if upstream sources originally had uppercase characters (e.g. LUFA, ChibiOS, or imported files from other repositories etc.) - - if there is valid justification (i.e. consistency with existing core files etc.) this can be relaxed - - a board designer naming their keyboard with uppercase letters is not enough justification -- valid license headers on all `*.c` and `*.h` source files - - GPL2/GPL3 recommended for consistency - - an example GPL2+ license header may be copied (and author modified) from the bottom of this document - - other licenses are permitted, however they must be GPL-compatible and must allow for redistribution. Using a different license will almost certainly delay a PR getting merged - - missing license headers will prevent PR merge due to ambiguity with license compatibility - - simple assignment-only `rules.mk` files should not need a license header - where additional logic is used in an `*.mk` file a license header may be appropriate -- QMK Codebase "best practices" followed - - this is not an exhaustive list, and will likely get amended as time goes by - - `#pragma once` instead of `#ifndef` include guards in header files - - no "old-school" or other low-level GPIO/I2C/SPI functions may be used -- must use QMK abstractions unless justifiable (and laziness is not valid justification) - - timing abstractions should be followed too: - - `wait_ms()` instead of `_delay_ms()` (remove `#include ` too) - - `timer_read()` and `timer_read32()` etc. -- see [timer.h](https://github.com/qmk/qmk_firmware/blob/master/platforms/timer.h) for the timing APIs - - if you think a new abstraction is useful, you're encouraged to: - - prototype it in your own keyboard until it's feature-complete - - discuss it with QMK Collaborators on Discord - - refactor it as a separate core change - - remove your specific copy in your board -- fix all merge conflicts before opening the PR (in case you need help or advice, reach out to QMK Collaborators on Discord) - - PR submitters will need to keep up-to-date with their base branch, resolving conflicts along the way - -## Keymap PRs - -- `#include QMK_KEYBOARD_H` preferred to including specific board files -- prefer layer `enum`s to `#define`s -- require custom keycode `enum`s to `#define`s, first entry must have ` = SAFE_RANGE` -- terminating backslash (`\`) in lines of LAYOUT macro parameters is superfluous and should be removed -- some care with spacing (e.g., alignment on commas or first char of keycodes) makes for a much nicer-looking keymap - -## Keyboard PRs - -Closed PRs (for inspiration, previous sets of review comments will help you eliminate ping-pong of your own reviews): -https://github.com/qmk/qmk_firmware/pulls?q=is%3Apr+is%3Aclosed+label%3Akeyboard - -- keyboard moves within the repository *must* go through the `develop` branch instead of `master`, so as to ensure compatibility for users - - `data/mappings/keyboard_aliases.hjson` must be updated to reflect the move, so users with pre-created configurator keymap.json files continue to detect the correct keyboard -- keyboard updates and refactors (eg. to data driven) *must* go through `develop` to reduce `master` -> `develop` merge conflicts -- PR submissions from a `kbfirmware` export (or equivalent) will not be accepted unless converted to new QMK standards -- try `qmk import-kbfirmware` first -- `info.json` - - With the move to [data driven](https://docs.qmk.fm/#/data_driven_config) keyboard configuration, we encourage contributors to utilise as many features as possible of the info.json [schema](https://github.com/qmk/qmk_firmware/blob/master/data/schemas/keyboard.jsonschema). - - the mandatory elements for a minimally complete `info.json` at present are: - - valid URL - - valid maintainer - - valid USB VID/PID and device version - - displays correctly in Configurator (press Ctrl+Shift+I to preview local file, turn on fast input to verify ordering) - - `layout` definitions must include matrix positions, so that `LAYOUT` macros can be generated at build time - - should use standard definitions if applicable - - use the Community Layout macro names where they apply (preferred above `LAYOUT`/`LAYOUT_all`) - - If the keyboard only has a single electrical/switch layout: - - use `LAYOUT` as your macro name, unless a community layout already exists - - If the keyboard has multiple electrical/switch layouts: - - include a `LAYOUT_all` which specifies all possible layout positions in the electrical matrix - - use alternate layout names for all other possible layouts, preferring community layout names if an equivalent is available (e.g. `LAYOUT_tkl_ansi`, `LAYOUT_ortho_4x4` etc.) - - Microcontroller and bootloader - - Diode Direction (if not using direct pins) - - the following are required to be configured in `info.json` if necessary - - Direct pin configuration - - Backlight Configuration (where applicable) - - Split keyboard configuration (where applicable) - - Encoder Configuration - - Bootmagic Configuration - - LED Indicator Configuration -- `readme.md` - - must follow the [template](https://github.com/qmk/qmk_firmware/blob/master/data/templates/keyboard/readme.md) - - flash command is present, and has `:flash` at end - - valid hardware availability link (unless handwired) -- private groupbuys are okay, but one-off prototypes will be questioned. If open-source, a link to files should be provided. - - clear instructions on how to reset the board into bootloader mode - - a picture about the keyboard and preferably about the PCB, too - - images are not to be placed in the `qmk_firmware` repository - - images should be uploaded to an external image hosting service, such as [imgur](https://imgur.com/). - - if imgur is used, images should be resized appropriately: append "h" to the image url i.e. [https://i.imgur.com/vqgE7Ok.jpg](https://i.imgur.com/vqgE7Ok.jpg) becomes [https://i.imgur.com/vqgE7Ok**h**.jpg](https://i.imgur.com/vqgE7Okh.jpg) - - image links should link directly to the image, not a "preview" -- i.e. [https://imgur.com/vqgE7Ok](https://imgur.com/vqgE7Ok) should be [https://i.imgur.com/vqgE7Okh.jpg](https://i.imgur.com/vqgE7Okh.jpg) when using imgur -- `rules.mk` - - removed `MIDI_ENABLE`, `FAUXCLICKY_ENABLE` and `HD44780_ENABLE` - - modified `# Enable Bluetooth with the Adafruit EZ-Key HID` -> `# Enable Bluetooth` - - no `(-/+size)` comments related to enabling features - - remove the list of alternate bootloaders if one has been specified - - no re-definitions of the default MCU parameters if same value, when compared to the equivalent MCU in [mcu_selection.mk](https://github.com/qmk/qmk_firmware/blob/master/builddefs/mcu_selection.mk) - - no "keymap only" features enabled - - `COMBO_ENABLE` - - `ENCODER_MAP_ENABLE` -- keyboard `config.h` - - no `#define DESCRIPTION` - - no Magic Key Options, MIDI Options or HD44780 configuration - - user preference configurable `#define`s need to be moved to keymap `config.h` - - default values should not be redefined, such as `DEBOUNCE`, RGB related settings, etc. - - feature specific documentation contains most default values - - `grep` or alternative tool can be used to search for default values in core directories (e.g. `grep -r "define DEBOUNCE" quantum`) - - no copy/pasted comment blocks explaining a feature and/or its caveats -- this is what the docs are for - - `Force NKRO to be enabled ... toggled again during a power-up` - - commented-out unused defines, such as RGB effects - - no `#include "config_common.h` - - no `#define MATRIX_ROWS/COLS`, unless necessary (e.g. a keyboard with a custom matrix) - - bare minimum required code for a board to boot into QMK should be present - - initialisation code for the matrix and critical devices - - mirroring existing functionality of a commercial board (like custom keycodes and special animations etc.) should be handled through non-`default` keymaps - - Vial-related files or changes will not be accepted, as they are not used by QMK firmware (no Vial-specific core code has been submitted or merged) -- `.c` - - empty `xxxx_xxxx_kb()` or other weak-defined default implemented functions removed - - empty `xxxx_xxxx_user()` or other user-level functions are disallowed at the keyboard level and must be moved to keymaps - - commented-out functions removed too - - `matrix_init_board()` etc. migrated to `keyboard_pre_init_kb()`, see: [keyboard_pre_init*](custom_quantum_functions.md?id=keyboard_pre_init_-function-documentation) - - prefer `CUSTOM_MATRIX = lite` if custom matrix used, allows for standard debounce, see [custom matrix 'lite'](custom_matrix.md?id=lite) - - prefer LED indicator [Configuration Options](feature_led_indicators.md?id=configuration-options) to custom `led_update_*()` implementations where possible - - hardware that's enabled at the keyboard level and requires configuration such as OLED displays or encoders should have basic functionality implemented here -- `.h` - - `#include "quantum.h"` appears at the top - - `LAYOUT` macros are no longer accepted and should instead be moved to `info.json` -- keymap `config.h` - - no duplication of `rules.mk` or `config.h` from keyboard -- `keymaps/default/keymap.c` - - `QMKBEST`/`QMKURL` example macros removed - - if using `MO(1)` and `MO(2)` keycodes together to access a third layer, the [Tri Layer](https://docs.qmk.fm/#/feature_tri_layer) feature should be used, rather than manually implementing this using `layer_on/off()` and `update_tri_layer()` functions in the keymap's `process_record_user()`. -- default (and via) keymaps should be "pristine" - - bare minimum to be used as a "clean slate" for another user to develop their own user-specific keymap - - standard layouts preferred in these keymaps, if possible - - should use [encoder map feature](https://docs.qmk.fm/#/feature_encoders?id=encoder-map), rather than `encoder_update_user()` - - default keymap should not enable VIA -- the VIA integration documentation requires a keymap called `via` -- submitters can have a personal (or bells-and-whistles) keymap showcasing capabilities in the same PR but it shouldn't be embedded in the 'default' keymap -- submitters can also have a "manufacturer-matching" keymap that mirrors existing functionality of the commercial product, if porting an existing board -- Do not include VIA json files in the PR. These do not belong in the QMK repository as they are not used by QMK firmware -- they belong in the [VIA Keyboard Repo](https://github.com/the-via/keyboards) -- Do not include KLE json files in the PR. These have no use within QMK. -- Do not include source files from another keyboard or vendors keyboard folder. Including core files is fine. - - For instance, only `wilba_tech` boards shall include `keyboards/wilba_tech/wt_main.c` and `keyboards/wilba_tech/wt_rgb_backlight.c`. But including `drivers/sensors/pmw3360.c` is absolutely fine for any and all boards that require it. - - Code that needs to be used by multiple boards is a candidate for core code changes, and should be separated out. - -Also, specific to ChibiOS: -- **strong** preference to using existing ChibiOS board definitions. - - a lot of the time, an equivalent Nucleo board can be used with a different flash size or slightly different model in the same family - - example: For an STM32L082KZ, given the similarity to an STM32L073RZ, you can use `BOARD = ST_NUCLEO64_L073RZ` in rules.mk - - QMK is migrating to not having custom board definitions if at all possible, due to the ongoing maintenance burden when upgrading ChibiOS -- New board definitions must not be embedded in a keyboard PR - - See [Core PRs](#core-pr) below for the procedure for adding a new board to QMK -- if a board definition is unavoidable, `board.c` must have a standard `__early_init()` (as per normal ChibiOS board defs) and an empty `boardInit()`: - - see Arm/ChibiOS [early initialization](platformdev_chibios_earlyinit.md?id=board-init) - - `__early_init()` should be replaced by either `early_hardware_init_pre()` or `early_hardware_init_post()` as appropriate - - `boardInit()` should be migrated to `board_init()` - -## Core PRs :id=core-pr - -- all core PRs must now target `develop` branch, which will subsequently be merged back to `master` on the breaking changes timeline -- as indicated above, the smallest set of changes to core components should be included in each PR - - PRs containing multiple areas of change will be asked to be split up and raised separately - - keyboard and keymap changes should only be included if they affect base keyboard builds, or the default-like `default`, `via`, `default_????` keymaps etc. - - keymap modifications for anything other than the default-like keymaps **should not be included in the initial PR** in order to simplify the review process - - the core PR submitter should submit a followup PR affecting other keymaps after initial PR merge - - large-scale refactoring or consolidation PRs that affect other keymaps (such as renaming keycodes) should always be raised separately -- any new boards adding support for new hardware now requires a corresponding test board under `keyboards/handwired/onekey` - - for new MCUs, a new "child" keyboard should be added that targets your newly-added MCU, so that builds can be verified - - for new hardware support such as display panels, core-side matrix implementations, or other peripherals, an associated keymap should be provided - - if an existing keymap exists that can leverage this functionality this may not be required (e.g. a new RGB driver chip, supported by the `rgb` keymap) -- consult with the QMK Collaborators on Discord to determine if there is sufficient overlap already -- any features adding `_kb`/`_user` callbacks must return a `bool`, to allow for user override of keyboard-level callbacks. -- where relevant, unit tests are strongly recommended -- they boost the confidence level that changes behave correctly - - critical areas of the code -- such as the keycode handling pipeline -- will almost certainly require unit tests accompanying them to ensure current and future correctness - - you should not be surprised if a QMK collaborator requests unit tests to be included in your PR if it's critical functionality -- other requirements are at the discretion of QMK collaborators - - core is a lot more subjective given the breadth of posted changes - ---- - -## Notes - -For when people use their own `master` branch, post this after merge: -``` -For future reference, we recommend against committing to your `master` branch as you've done here, because pull requests from modified `master` branches can make it more difficult to keep your QMK fork updated. It is highly recommended for QMK development – regardless of what is being done or where – to keep your master updated, but **NEVER** commit to it. Instead, do all your changes in a branch (branches are basically free in Git) and issue PRs from your branches when you're developing. - -There are instructions on how to keep your fork updated here: - -[**Best Practices: Your Fork's Master: Update Often, Commit Never**](https://docs.qmk.fm/#/newbs_git_using_your_master_branch) - -[Fixing Your Branch](https://docs.qmk.fm/#/newbs_git_resynchronize_a_branch) will walk you through fixing up your `master` branch moving forward. If you need any help with this just ask. - -Thanks for contributing! -``` - -## Review Process - -In general, we want to see two (or more) approvals that are meaningful (e.g. that have inspected code) before a PR will be considered for merge. These reviews are not limited to collaborators -- any community member willing to put in the time is welcomed (and encouraged). The only difference is that your checkmark won't be green, and that's fine! - -Additionally, PR reviews are something that is done in our free time. We are not paid nor compensated for the time we spend reviewing, as it is a labor of love. As such, this means that it can take time for us to get to your Pull Request. Things like family, or life can get in the way of us getting to PRs, and burnout is a serious concern. The QMK firmware repository averages 200 PRs opened and 200 PRs merged every month, so please have patience. - -## Example GPLv2 Header - -``` -/* Copyright 2021 Your Name (@yourgithub) - * - * 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 . - */ -``` - -Or, optionally, using [SPDX identifier](https://spdx.org/licenses/) instead: - -``` -// Copyright 2021 Your Name (@yourgithub) -// SPDX-License-Identifier: GPL-2.0-or-later -``` diff --git a/docs/qmk.css b/docs/qmk.css deleted file mode 100644 index 543cd7f28d4d..000000000000 --- a/docs/qmk.css +++ /dev/null @@ -1,862 +0,0 @@ -* { - -webkit-font-smoothing: antialiased; - -webkit-overflow-scrolling: touch; - -webkit-tap-highlight-color: rgba(0,0,0,0); - -webkit-text-size-adjust: none; - -webkit-touch-callout: none; - -webkit-box-sizing: border-box; - box-sizing: border-box; -} -body:not(.ready) { - overflow: hidden; -} -body:not(.ready) [data-cloak], -body:not(.ready) .app-nav, -body:not(.ready) > nav { - display: none; -} -div#app { - font-size: 30px; - font-weight: lighter; - margin: 40vh auto; - text-align: center; -} -div#app:empty::before { - content: 'Loading...'; -} -.emoji { - height: 1.2rem; - vertical-align: middle; -} -.progress { - background-color: var(--theme-color, #ea6f5a); - height: 2px; - left: 0px; - position: fixed; - right: 0px; - top: 0px; - -webkit-transition: width 0.2s, opacity 0.4s; - transition: width 0.2s, opacity 0.4s; - width: 0%; - z-index: 999999; -} -.search a:hover { - color: var(--theme-color, #ea6f5a); -} -.search .search-keyword { - color: var(--theme-color, #ea6f5a); - font-style: normal; - font-weight: bold; -} -html, -body { - height: 100%; -} -body { - -moz-osx-font-smoothing: grayscale; - -webkit-font-smoothing: antialiased; - color: #efefef; - font-family: 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; - font-size: 15px; - letter-spacing: 0; - margin: 0; - overflow-x: hidden; -} -img { - max-width: 100%; -} -a[disabled] { - cursor: not-allowed; - opacity: 0.6; -} -kbd { - border: solid 1px #ccc; - border-radius: 3px; - display: inline-block; - font-size: 12px !important; - line-height: 12px; - margin-bottom: 3px; - padding: 3px 5px; - vertical-align: middle; -} -.task-list-item { - list-style-type: none; -} -li input[type='checkbox'] { - margin: 0 0.2em 0.25em -1.6em; - vertical-align: middle; -} -.app-nav { - margin: 25px 60px 0 0; - position: absolute; - right: 0; - text-align: right; - z-index: 10; -/* navbar dropdown */ -} -.app-nav.no-badge { - margin-right: 25px; -} -.app-nav p { - margin: 0; -} -.app-nav > a { - margin: 0 1rem; - padding: 5px 0; -} -.app-nav ul, -.app-nav li { - display: inline-block; - list-style: none; - margin: 0; -} -.app-nav a { - color: inherit; - font-size: 16px; - text-decoration: none; - -webkit-transition: color 0.3s; - transition: color 0.3s; -} -.app-nav a:hover { - color: var(--theme-color, #ea6f5a); -} -.app-nav a.active { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - color: var(--theme-color, #ea6f5a); -} -.app-nav li { - display: inline-block; - margin: 0 1rem; - padding: 5px 0; - position: relative; -} -.app-nav li ul { - background-color: #fff; - border: 1px solid #ddd; - border-bottom-color: #ccc; - border-radius: 4px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - display: none; - max-height: calc(100vh - 61px); - overflow-y: auto; - padding: 10px 0; - position: absolute; - right: -15px; - text-align: left; - top: 100%; - white-space: nowrap; -} -.app-nav li ul li { - display: block; - font-size: 14px; - line-height: 1rem; - margin: 0; - margin: 8px 14px; - white-space: nowrap; -} -.app-nav li ul a { - display: block; - font-size: inherit; - margin: 0; - padding: 0; -} -.app-nav li ul a.active { - border-bottom: 0; -} -.app-nav li:hover ul { - display: block; -} -.github-corner { - border-bottom: 0; - position: fixed; - right: 0; - text-decoration: none; - top: 0; - z-index: 1; -} -.github-corner:hover .octo-arm { - -webkit-animation: octocat-wave 560ms ease-in-out; - animation: octocat-wave 560ms ease-in-out; -} -.github-corner svg { - color: #3f3f3f; - fill: var(--theme-color, #ea6f5a); - height: 80px; - width: 80px; -} -main { - display: block; - position: relative; - width: 100vw; - height: 100%; - z-index: 0; -} -main.hidden { - display: none; -} -.anchor { - display: inline-block; - text-decoration: none; - -webkit-transition: all 0.3s; - transition: all 0.3s; -} -.anchor span { - color: #c8c8c8; -} -.anchor:hover { - text-decoration: underline; -} -.sidebar { - border-right: 1px solid rgba(0,0,0,0.07); - overflow-y: auto; - padding: 40px 0 0; - position: absolute; - top: 0; - bottom: 0; - left: 0; - -webkit-transition: -webkit-transform 250ms ease-out; - transition: -webkit-transform 250ms ease-out; - transition: transform 250ms ease-out; - transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; - width: 300px; - z-index: 20; -} -.sidebar > h1 { - margin: 0 auto 1rem; - font-size: 1.5rem; - font-weight: 300; - text-align: center; -} -.sidebar > h1 a { - color: inherit; - text-decoration: none; -} -.sidebar > h1 .app-nav { - display: block; - position: static; -} -.sidebar .sidebar-nav { - line-height: 2em; - padding-bottom: 40px; -} -.sidebar li.collapse .app-sub-sidebar { - display: none; -} -.sidebar ul { - margin: 0; - padding: 0; -} -.sidebar li > p { - font-weight: 700; - margin: 0; -} -.sidebar ul, -.sidebar ul li { - list-style: none; -} -.sidebar ul li a { - border-bottom: none; - display: block; -} -.sidebar ul li ul { - padding-left: 20px; -} -.sidebar::-webkit-scrollbar { - width: 4px; -} -.sidebar::-webkit-scrollbar-thumb { - background: transparent; - border-radius: 4px; -} -.sidebar:hover::-webkit-scrollbar-thumb { - background: rgba(136,136,136,0.4); -} -.sidebar:hover::-webkit-scrollbar-track { - background: rgba(136,136,136,0.1); -} -.sidebar-toggle { - background-color: transparent; - background-color: rgba(63,63,63,0.8); - border: 0; - outline: none; - padding: 10px; - position: absolute; - bottom: 0; - left: 0; - text-align: center; - -webkit-transition: opacity 0.3s; - transition: opacity 0.3s; - width: 284px; - z-index: 30; -} -.sidebar-toggle .sidebar-toggle-button:hover { - opacity: 0.4; -} -.sidebar-toggle span { - background-color: var(--theme-color, #ea6f5a); - display: block; - margin-bottom: 4px; - width: 16px; - height: 2px; -} -body.sticky .sidebar, -body.sticky .sidebar-toggle { - position: fixed; -} -.content { - padding-top: 60px; - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 300px; - -webkit-transition: left 250ms ease; - transition: left 250ms ease; -} -.markdown-section { - margin: 0 auto; - max-width: 800px; - padding: 30px 15px 40px 15px; - position: relative; -} -.markdown-section > * { - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-size: inherit; -} -.markdown-section > :first-child { - margin-top: 0 !important; -} -.markdown-section hr { - border: none; - border-bottom: 1px solid #eee; - margin: 2em 0; -} -.markdown-section iframe { - border: 1px solid #eee; -} -.markdown-section table { - border-collapse: collapse; - border-spacing: 0; - display: block; - margin-bottom: 1rem; - overflow: auto; - width: 100%; -} -.markdown-section th { - border: 1px solid #ddd; - font-weight: bold; - padding: 6px 13px; -} -.markdown-section td { - border: 1px solid #ddd; - padding: 6px 13px; -} -.markdown-section tr { - border-top: 1px solid #ccc; -} -.markdown-section tr:nth-child(2n) { - background-color: #555555; -} -.markdown-section p.tip { - background-color: #555555; - border-bottom-right-radius: 2px; - border-left: 4px solid #f66; - border-top-right-radius: 2px; - margin: 2em 0; - padding: 12px 24px 12px 30px; - position: relative; -} -.markdown-section p.tip:before { - background-color: #f66; - border-radius: 100%; - color: #3f3f3f; - content: '!'; - font-family: 'Dosis', 'Source Sans Pro', 'Helvetica Neue', Arial, sans-serif; - font-size: 14px; - font-weight: bold; - left: -12px; - line-height: 20px; - position: absolute; - height: 20px; - width: 20px; - text-align: center; - top: 14px; -} -.markdown-section p.tip code { - background-color: #efefef; -} -.markdown-section p.tip em { - color: #c8c8c8; -} -.markdown-section p.warn { - background: rgba(234,111,90,0.1); - border-radius: 2px; - padding: 1rem; -} -body.close .sidebar { - -webkit-transform: translateX(-300px); - transform: translateX(-300px); -} -body.close .sidebar-toggle { - width: auto; -} -body.close .content { - left: 0; -} -@media print { - .github-corner, - .sidebar-toggle, - .sidebar, - .app-nav { - display: none; - } -} -@media screen and (max-width: 768px) { - .github-corner, - .sidebar-toggle, - .sidebar { - position: fixed; - } - .app-nav { - margin-top: 16px; - } - .app-nav li ul { - top: 30px; - } - main { - height: auto; - overflow-x: hidden; - } - .sidebar { - left: -300px; - -webkit-transition: -webkit-transform 250ms ease-out; - transition: -webkit-transform 250ms ease-out; - transition: transform 250ms ease-out; - transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; - } - .content { - left: 0; - max-width: 100vw; - position: static; - padding-top: 20px; - -webkit-transition: -webkit-transform 250ms ease; - transition: -webkit-transform 250ms ease; - transition: transform 250ms ease; - transition: transform 250ms ease, -webkit-transform 250ms ease; - } - .app-nav, - .github-corner { - -webkit-transition: -webkit-transform 250ms ease-out; - transition: -webkit-transform 250ms ease-out; - transition: transform 250ms ease-out; - transition: transform 250ms ease-out, -webkit-transform 250ms ease-out; - } - .sidebar-toggle { - background-color: transparent; - width: auto; - padding: 30px 30px 10px 10px; - } - body.close .sidebar { - -webkit-transform: translateX(300px); - transform: translateX(300px); - } - body.close .sidebar-toggle { - background-color: rgba(63,63,63,0.8); - -webkit-transition: 1s background-color; - transition: 1s background-color; - width: 284px; - padding: 10px; - } - body.close .content { - -webkit-transform: translateX(300px); - transform: translateX(300px); - } - body.close .app-nav, - body.close .github-corner { - display: none; - } - .github-corner:hover .octo-arm { - -webkit-animation: none; - animation: none; - } - .github-corner .octo-arm { - -webkit-animation: octocat-wave 560ms ease-in-out; - animation: octocat-wave 560ms ease-in-out; - } -} -@-webkit-keyframes octocat-wave { - 0%, 100% { - -webkit-transform: rotate(0); - transform: rotate(0); - } - 20%, 60% { - -webkit-transform: rotate(-25deg); - transform: rotate(-25deg); - } - 40%, 80% { - -webkit-transform: rotate(10deg); - transform: rotate(10deg); - } -} -@keyframes octocat-wave { - 0%, 100% { - -webkit-transform: rotate(0); - transform: rotate(0); - } - 20%, 60% { - -webkit-transform: rotate(-25deg); - transform: rotate(-25deg); - } - 40%, 80% { - -webkit-transform: rotate(10deg); - transform: rotate(10deg); - } -} -section.cover { - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-position: center center; - background-repeat: no-repeat; - background-size: cover; - height: 100vh; - display: none; -} -section.cover.show { - display: -webkit-box; - display: -ms-flexbox; - display: flex; -} -section.cover.has-mask .mask { - background-color: #3f3f3f; - opacity: 0.8; - position: absolute; - top: 0; - height: 100%; - width: 100%; -} -section.cover .cover-main { - -webkit-box-flex: 1; - -ms-flex: 1; - flex: 1; - margin: -20px 16px 0; - text-align: center; - z-index: 1; -} -section.cover a { - color: inherit; - text-decoration: none; -} -section.cover a:hover { - text-decoration: none; -} -section.cover p { - line-height: 1.5rem; - margin: 1em 0; -} -section.cover h1 { - color: inherit; - font-size: 2.5rem; - font-weight: 300; - margin: 0.625rem 0 2.5rem; - position: relative; - text-align: center; -} -section.cover h1 a { - display: block; -} -section.cover h1 small { - bottom: -0.4375rem; - font-size: 1rem; - position: absolute; -} -section.cover blockquote { - font-size: 1.5rem; - text-align: center; -} -section.cover ul { - line-height: 1.8; - list-style-type: none; - margin: 1em auto; - max-width: 500px; - padding: 0; -} -section.cover .cover-main > p:last-child a { - border-color: var(--theme-color, #ea6f5a); - border-radius: 2rem; - border-style: solid; - border-width: 1px; - -webkit-box-sizing: border-box; - box-sizing: border-box; - color: var(--theme-color, #ea6f5a); - display: inline-block; - font-size: 1.05rem; - letter-spacing: 0.1rem; - margin: 0.5rem 1rem; - padding: 0.75em 2rem; - text-decoration: none; - -webkit-transition: all 0.15s ease; - transition: all 0.15s ease; -} -section.cover .cover-main > p:last-child a:last-child { - background-color: var(--theme-color, #ea6f5a); - color: #fff; -} -section.cover .cover-main > p:last-child a:last-child:hover { - color: inherit; - opacity: 0.8; -} -section.cover .cover-main > p:last-child a:hover { - color: inherit; -} -section.cover blockquote > p > a { - border-bottom: 2px solid var(--theme-color, #ea6f5a); - -webkit-transition: color 0.3s; - transition: color 0.3s; -} -section.cover blockquote > p > a:hover { - color: var(--theme-color, #ea6f5a); -} -body { - background-color: #3f3f3f; -} -/* sidebar */ -.sidebar { - background-color: #3f3f3f; - color: #c8c8c8; -} -.sidebar li { - margin: 6px 15px; -} -.sidebar ul li a { - color: #c8c8c8; - font-size: 14px; - overflow: hidden; - text-decoration: none; - text-overflow: ellipsis; - white-space: nowrap; -} -.sidebar ul li a:hover { - text-decoration: underline; -} -.sidebar ul li ul { - padding: 0; -} -.sidebar ul li.active > a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; -} -/* markdown content found on pages */ -.markdown-section h1, -.markdown-section h2, -.markdown-section h3, -.markdown-section h4, -.markdown-section strong { - color: #657b83; - font-weight: 600; -} -.markdown-section a { - color: var(--theme-color, #ea6f5a); - font-weight: 600; -} -.markdown-section h1 { - font-size: 2rem; - margin: 0 0 1rem; -} -.markdown-section h2 { - font-size: 1.75rem; - margin: 45px 0 0.8rem; -} -.markdown-section h3 { - font-size: 1.5rem; - margin: 40px 0 0.6rem; -} -.markdown-section h4 { - font-size: 1.25rem; -} -.markdown-section h5 { - font-size: 1rem; -} -.markdown-section h6 { - color: #777; - font-size: 1rem; -} -.markdown-section figure, -.markdown-section p, -.markdown-section ul, -.markdown-section ol { - margin: 1.2em 0; -} -.markdown-section p, -.markdown-section ul, -.markdown-section ol { - line-height: 1.6rem; - word-spacing: 0.05rem; -} -.markdown-section ul, -.markdown-section ol { - padding-left: 1.5rem; -} -.markdown-section blockquote { - border-left: 4px solid var(--theme-color, #ea6f5a); - color: #858585; - margin: 2em 0; - padding-left: 20px; -} -.markdown-section blockquote p { - font-weight: 600; - margin-left: 0; -} -.markdown-section iframe { - margin: 1em 0; -} -.markdown-section em { - color: #7f8c8d; -} -.markdown-section code { - background-color: #282828; - border-radius: 2px; - color: #aaaaaa; - font-family: 'Roboto Mono', Monaco, courier, monospace; - font-size: 0.8rem; - margin: 0 2px; - padding: 3px 5px; - white-space: pre-wrap; -} -.markdown-section pre { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #282828; - font-family: 'Roboto Mono', Monaco, courier, monospace; - line-height: 1.5rem; - margin: 1.2em 0; - overflow: auto; - padding: 0 1.4rem; - position: relative; - word-wrap: normal; -} -/* code highlight */ -.token.comment, -.token.prolog, -.token.doctype, -.token.cdata { - color: #8e908c; -} -.token.namespace { - opacity: 0.7; -} -.token.boolean, -.token.number { - color: #c76b29; -} -.token.punctuation { - color: #525252; -} -.token.property { - color: #c08b30; -} -.token.tag { - color: #2973b7; -} -.token.string { - color: var(--theme-color, #ea6f5a); -} -.token.selector { - color: #6679cc; -} -.token.attr-name { - color: #2973b7; -} -.token.entity, -.token.url, -.language-css .token.string, -.style .token.string { - color: #22a2c9; -} -.token.attr-value, -.token.control, -.token.directive, -.token.unit { - color: var(--theme-color, #ea6f5a); -} -.token.keyword { - color: #e96900; -} -.token.statement, -.token.regex, -.token.atrule { - color: #22a2c9; -} -.token.placeholder, -.token.variable { - color: #3d8fd1; -} -.token.deleted { - text-decoration: line-through; -} -.token.inserted { - border-bottom: 1px dotted #202746; - text-decoration: none; -} -.token.italic { - font-style: italic; -} -.token.important, -.token.bold { - font-weight: bold; -} -.token.important { - color: #c94922; -} -.token.entity { - cursor: help; -} -.markdown-section pre > code { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - background-color: #282828; - border-radius: 2px; - color: #657b83; - display: block; - font-family: 'Roboto Mono', Monaco, courier, monospace; - font-size: 0.8rem; - line-height: inherit; - margin: 0 2px; - max-width: inherit; - overflow: inherit; - padding: 2.2em 5px; - white-space: inherit; -} -.markdown-section code::after, -.markdown-section code::before { - letter-spacing: 0.05rem; -} -code .token { - -moz-osx-font-smoothing: initial; - -webkit-font-smoothing: initial; - min-height: 1.5rem; -} -pre::after { - color: #ccc; - content: attr(data-lang); - font-size: 0.6rem; - font-weight: 600; - height: 15px; - line-height: 15px; - padding: 5px 10px 0; - position: absolute; - right: 0; - text-align: right; - top: 0; -} -.markdown-section p.tip { - background-color: #282828; - color: #657b83; -} -input[type='search'] { - background: #4f4f4f; - border-color: #4f4f4f; - color: #c8c8c8; -} diff --git a/docs/qmk_custom_dark.css b/docs/qmk_custom_dark.css deleted file mode 100644 index 35498fbd8636..000000000000 --- a/docs/qmk_custom_dark.css +++ /dev/null @@ -1,41 +0,0 @@ -.sidebar li.active { - background-color: #555; -} - -.markdown-section p.tip, -.markdown-section tr:nth-child(2n) { - background-color:#444; -} - -.markdown-section tr { - border-top: 1px solid #555; -} - -.markdown-section td, .markdown-section th { - border: 1px solid #555; -} - -.markdown-section p.tip code { - background-color: #555; - color: #fff; -} - -.page_toc code { - background-color: #555; -} - -.markdown-section hr, .search { - border-bottom: 1px solid #777 !important; -} - -.markdown-section p.warn > strong { - color: #c8c8c8; -} - -:root { - --docsifytabs-border-color: #555; - --docsifytabs-tab-highlight-color: var(--theme-color,#ea6f5a); - - --docsifytabs-tab-background: #444; - --docsifytabs-tab-background-active: #3f3f3f; -} diff --git a/docs/qmk_custom_light.css b/docs/qmk_custom_light.css deleted file mode 100644 index c65e54396d43..000000000000 --- a/docs/qmk_custom_light.css +++ /dev/null @@ -1,58 +0,0 @@ -.sidebar-toggle { - position: absolute; - top: 0; - bottom: auto; - left: 0; -} - -.search { - margin-top: 40px; -} - -.markdown-section h2 { - padding-top: 0.25rem; -} - -.markdown-section h3 { - margin-top: 0.25rem; -} - -.sidebar, .sidebar-nav { - line-height: 1.5em !important; -} - -.markdown-section ul ul { - margin: 0; -} - -.markdown-section pre { - padding: 0; -} - -@media only screen and (min-width: 768px) { - .flex-container { - display:flex; - flex-flow:row; - } - .flex-container > p { - flex-basis: 100%; - flex: 1; - margin: 1em 2em 1em 2em; - } -} - -.docsify-tabs__tab:focus { - outline: none !important; -} - -.docsify-tabs__content .anchor { - transition: none; -} - -:root { - --docsifytabs-border-color: #ddd; - --docsifytabs-tab-highlight-color: var(--theme-color, #0074d9); - - --docsifytabs-tab-background: #f8f8f8; - --docsifytabs-tab-background-active: transparent; -} diff --git a/docs/quantum_keycodes.md b/docs/quantum_keycodes.md deleted file mode 100644 index bc68cbc92212..000000000000 --- a/docs/quantum_keycodes.md +++ /dev/null @@ -1,17 +0,0 @@ -# Quantum Keycodes - -Quantum keycodes allow for easier customization of your keymap than the basic ones provide, without having to define custom actions. - -All keycodes within quantum are numbers between `0x0000` and `0xFFFF`. Within your `keymap.c` it may look like you have functions and other special cases, but ultimately the C preprocessor will translate those into a single 4 byte integer. QMK has reserved `0x0000` through `0x00FF` for standard keycodes. These are keycodes such as `KC_A`, `KC_1`, and `KC_LCTL`, which are basic keys defined in the USB HID specification. - -On this page we have documented keycodes between `0x00FF` and `0xFFFF` which are used to implement advanced quantum features. If you define your own custom keycodes they will be put into this range as well. - -## QMK Keycodes :id=qmk-keycodes - -|Key |Aliases |Description | -|-----------------|---------|-------------------------------------------------------------------------------------------------------------------------------------------------| -|`QK_BOOTLOADER` |`QK_BOOT`|Put the keyboard into bootloader mode for flashing | -|`QK_DEBUG_TOGGLE`|`DB_TOGG`|Toggle debug mode | -|`QK_CLEAR_EEPROM`|`EE_CLR` |Reinitializes the keyboard's EEPROM (persistent memory) | -|`QK_MAKE` | |Sends `qmk compile -kb (keyboard) -km (keymap)`, or `qmk flash` if shift is held. Puts keyboard into bootloader mode if shift & control are held | -|`QK_REBOOT` |`QK_RBT` |Resets the keyboard. Does not load the bootloader | diff --git a/docs/quantum_painter.md b/docs/quantum_painter.md deleted file mode 100644 index 317a9d9f1a25..000000000000 --- a/docs/quantum_painter.md +++ /dev/null @@ -1,896 +0,0 @@ -# Quantum Painter :id=quantum-painter - -Quantum Painter is the standardised API for graphical displays. It currently includes support for basic drawing primitives, as well as custom images, animations, and fonts. - -Due to the complexity, there is no support for Quantum Painter on AVR-based boards. - -To enable overall Quantum Painter to be built into your firmware, add the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += ...... -``` - -You will also likely need to select an appropriate driver in `rules.mk`, which is listed below. - -!> Quantum Painter is not currently integrated with system-level operations such as disabling displays after a configurable timeout, or when the keyboard goes into suspend. Users will need to handle this manually at the current time. - -The QMK CLI can be used to convert from normal images such as PNG files or animated GIFs, as well as fonts from TTF files. - -Supported devices: - -| Display Panel | Panel Type | Size | Comms Transport | Driver | -|----------------|--------------------|------------------|-----------------|---------------------------------------------| -| GC9A01 | RGB LCD (circular) | 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += gc9a01_spi` | -| ILI9163 | RGB LCD | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9163_spi` | -| ILI9341 | RGB LCD | 240x320 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9341_spi` | -| ILI9488 | RGB LCD | 320x480 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ili9488_spi` | -| SSD1351 | RGB OLED | 128x128 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += ssd1351_spi` | -| ST7735 | RGB LCD | 132x162, 80x160 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7735_spi` | -| ST7789 | RGB LCD | 240x320, 240x240 | SPI + D/C + RST | `QUANTUM_PAINTER_DRIVERS += st7789_spi` | -| RGB565 Surface | Virtual | User-defined | None | `QUANTUM_PAINTER_DRIVERS += rgb565_surface` | - -## Quantum Painter Configuration :id=quantum-painter-config - -| Option | Default | Purpose | -|---------------------------------------------------|---------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `QUANTUM_PAINTER_DISPLAY_TIMEOUT` | `30000` | This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. If set to `0`, the display will remain on indefinitely. | -| `QUANTUM_PAINTER_TASK_THROTTLE` | `1` | This controls the amount of time (in milliseconds) that the Quantum Painter internal task will wait between each execution. Affects animations, display timeout, and LVGL timing if enabled. | -| `QUANTUM_PAINTER_NUM_IMAGES` | `8` | The maximum number of images/animations that can be loaded at any one time. | -| `QUANTUM_PAINTER_NUM_FONTS` | `4` | The maximum number of fonts that can be loaded at any one time. | -| `QUANTUM_PAINTER_CONCURRENT_ANIMATIONS` | `4` | The maximum number of animations that can be executed at the same time. | -| `QUANTUM_PAINTER_LOAD_FONTS_TO_RAM` | `FALSE` | Whether or not fonts should be loaded to RAM. Relevant for fonts stored in off-chip persistent storage, such as external flash. | -| `QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE` | `32` | The limit of the amount of pixel data that can be transmitted in one transaction to the display. Higher values require more RAM on the MCU. | -| `QUANTUM_PAINTER_SUPPORTS_256_PALETTE` | `FALSE` | If 256-color palettes are supported. Requires significantly more RAM on the MCU. | -| `QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS` | `FALSE` | If native color range is supported. Requires significantly more RAM on the MCU. | -| `QUANTUM_PAINTER_DEBUG` | _unset_ | Prints out significant amounts of debugging information to CONSOLE output. Significant performance degradation, use only for debugging. | -| `QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT` | _unset_ | By default, debug output is disabled while the internal task is flushing the display(s). If you want to keep it enabled, add this to your `config.h`. Note: Console will get clogged. | - - -Drivers have their own set of configurable options, and are described in their respective sections. - -## Quantum Painter CLI Commands :id=quantum-painter-cli - - - -### ** `qmk painter-convert-graphics` ** - -This command converts images to a format usable by QMK, i.e. the QGF File Format. - -**Usage**: - -``` -usage: qmk painter-convert-graphics [-h] [-w] [-d] [-r] -f FORMAT [-o OUTPUT] -i INPUT [-v] - -options: - -h, --help show this help message and exit - -w, --raw Writes out the QGF file as raw data instead of c/h combo. - -d, --no-deltas Disables the use of delta frames when encoding animations. - -r, --no-rle Disables the use of RLE when encoding images. - -f FORMAT, --format FORMAT - Output format, valid types: rgb888, rgb565, pal256, pal16, pal4, pal2, mono256, mono16, mono4, mono2 - -o OUTPUT, --output OUTPUT - Specify output directory. Defaults to same directory as input. - -i INPUT, --input INPUT - Specify input graphic file. - -v, --verbose Turns on verbose output. -``` - -The `INPUT` argument can be any image file loadable by Python's Pillow module. Common formats include PNG, or Animated GIF. - -The `OUTPUT` argument needs to be a directory, and will default to the same directory as the input argument. - -The `FORMAT` argument can be any of the following: - -| Format | Meaning | -|-----------|-------------------------------------------------------------------------------------------| -| `rgb888` | 16,777,216 colors in 8-8-8 RGB format (requires `QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS`) | -| `rgb565` | 65,536 colors in 5-6-5 RGB format (requires `QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS`) | -| `pal256` | 256-color palette (requires `QUANTUM_PAINTER_SUPPORTS_256_PALETTE`) | -| `pal16` | 16-color palette | -| `pal4` | 4-color palette | -| `pal2` | 2-color palette | -| `mono256` | 256-shade grayscale (requires `QUANTUM_PAINTER_SUPPORTS_256_PALETTE`) | -| `mono16` | 16-shade grayscale | -| `mono4` | 4-shade grayscale | -| `mono2` | 2-shade grayscale | - -**Examples**: - -``` -$ cd /home/qmk/qmk_firmware/keyboards/my_keeb -$ qmk painter-convert-graphics -f mono16 -i my_image.gif -o ./generated/ -Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.h... -Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/my_image.qgf.c... -``` - -### ** `qmk painter-make-font-image` ** - -This command converts a TTF font to an intermediate format for editing, before converting to the QFF File Format. - -**Usage**: - -``` -usage: qmk painter-make-font-image [-h] [-a] [-u UNICODE_GLYPHS] [-n] [-s SIZE] -o OUTPUT -f FONT - -optional arguments: - -h, --help show this help message and exit - -a, --no-aa Disable anti-aliasing on fonts. - -u UNICODE_GLYPHS, --unicode-glyphs UNICODE_GLYPHS - Also generate the specified unicode glyphs. - -n, --no-ascii Disables output of the full ASCII character set (0x20..0x7E), exporting only the glyphs specified. - -s SIZE, --size SIZE Specify font size. Default 12. - -o OUTPUT, --output OUTPUT - Specify output image path. - -f FONT, --font FONT Specify input font file. -``` - -The `FONT` argument is generally a TrueType Font file (TTF). - -The `OUTPUT` argument is the output image to generate, generally something like `my_font.png`. - -The `UNICODE_GLYPHS` argument allows for specifying extra unicode glyphs to generate, and accepts a string. - -**Examples**: - -``` -$ qmk painter-make-font-image --font NotoSans-ExtraCondensedBold.ttf --size 11 -o noto11.png --unicode-glyphs "ĄȽɂɻɣɈʣ" -``` - -### ** `qmk painter-convert-font-image` ** - -This command converts an intermediate font image to the QFF File Format. - -This command expects an image that conforms to the following format: - -* Top-left pixel (at `0,0`) is the "delimiter" color: - * Each glyph in the font starts when a pixel of this color is found on the first row - * The first row is discarded when converting to the QFF format -* The number of delimited glyphs must match the supplied arguments to the command: - * The full ASCII set `0x20..0x7E` (if `--no-ascii` was not specified) - * The corresponding number of unicode glyphs if any were specified with `--unicode-glyphs` -* The order of the glyphs matches the ASCII set, if any, followed by the Unicode glyph set, if any. - -**Usage**: - -``` -usage: qmk painter-convert-font-image [-h] [-w] [-r] -f FORMAT [-u UNICODE_GLYPHS] [-n] [-o OUTPUT] [-i INPUT] - -options: - -h, --help show this help message and exit - -w, --raw Writes out the QFF file as raw data instead of c/h combo. - -r, --no-rle Disable the use of RLE to minimise converted image size. - -f FORMAT, --format FORMAT - Output format, valid types: rgb565, pal256, pal16, pal4, pal2, mono256, mono16, mono4, mono2 - -u UNICODE_GLYPHS, --unicode-glyphs UNICODE_GLYPHS - Also generate the specified unicode glyphs. - -n, --no-ascii Disables output of the full ASCII character set (0x20..0x7E), exporting only the glyphs specified. - -o OUTPUT, --output OUTPUT - Specify output directory. Defaults to same directory as input. - -i INPUT, --input INPUT - Specify input graphic file. -``` - -The same arguments for `--no-ascii` and `--unicode-glyphs` need to be specified, as per `qmk painter-make-font-image`. - -**Examples**: - -``` -$ cd /home/qmk/qmk_firmware/keyboards/my_keeb -$ qmk painter-convert-font-image --input noto11.png -f mono4 --unicode-glyphs "ĄȽɂɻɣɈʣ" -Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/noto11.qff.h... -Writing /home/qmk/qmk_firmware/keyboards/my_keeb/generated/noto11.qff.c... -``` - - - -## Quantum Painter Display Drivers :id=quantum-painter-drivers - - - -### ** Common: Standard TFT (SPI + D/C + RST) ** - -Most TFT display panels use a 5-pin interface -- SPI SCK, SPI MOSI, SPI CS, D/C, and RST pins. - -For these displays, QMK's `spi_master` must already be correctly configured for the platform you're building for. - -The pin assignments for SPI CS, D/C, and RST are specified during device construction. - - - -#### ** GC9A01 ** - -Enabling support for the GC9A01 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += gc9a01_spi -``` - -Creating a GC9A01 device in firmware can then be done with the following API: - -```c -painter_device_t qp_gc9a01_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_gc9a01_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define GC9A01_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with GC9A01 - -#### ** ILI9163 ** - -Enabling support for the ILI9163 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += ili9163_spi -``` - -Creating a ILI9163 device in firmware can then be done with the following API: - -```c -painter_device_t qp_ili9163_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_ili9163_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define ILI9163_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with ILI9163 - -#### ** ILI9341 ** - -Enabling support for the ILI9341 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += ili9341_spi -``` - -Creating a ILI9341 device in firmware can then be done with the following API: - -```c -painter_device_t qp_ili9341_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_ili9341_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define ILI9341_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with ILI9341 - -#### ** ILI9488 ** - -Enabling support for the ILI9488 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += ili9488_spi -``` - -Creating a ILI9488 device in firmware can then be done with the following API: - -```c -painter_device_t qp_ili9488_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_ili9488_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define ILI9488_NUM_DEVICES 3 -``` - -Native color format rgb888 is compatible with ILI9488 - -#### ** SSD1351 ** - -Enabling support for the SSD1351 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += ssd1351_spi -``` - -Creating a SSD1351 device in firmware can then be done with the following API: - -```c -painter_device_t qp_ssd1351_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_ssd1351_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define SSD1351_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with SSD1351 - -#### ** ST7735 ** - -Enabling support for the ST7735 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += st7735_spi -``` - -Creating a ST7735 device in firmware can then be done with the following API: - -```c -painter_device_t qp_st7735_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_st7735_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define ST7735_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with ST7735 - -!> Some ST7735 devices are known to have different drawing offsets -- despite being a 132x162 pixel display controller internally, some display panels are only 80x160, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered. - -#### ** ST7789 ** - -Enabling support for the ST7789 in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += st7789_spi -``` - -Creating a ST7789 device in firmware can then be done with the following API: - -```c -painter_device_t qp_st7789_make_spi_device(uint16_t panel_width, uint16_t panel_height, pin_t chip_select_pin, pin_t dc_pin, pin_t reset_pin, uint16_t spi_divisor, int spi_mode); -``` - -The device handle returned from the `qp_st7789_make_spi_device` function can be used to perform all other drawing operations. - -The maximum number of displays can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 displays: -#define ST7789_NUM_DEVICES 3 -``` - -Native color format rgb565 is compatible with ST7789 - -!> Some ST7789 devices are known to have different drawing offsets -- despite being a 240x320 pixel display controller internally, some display panels are only 240x240, or smaller. These may require an offset to be applied; see `qp_set_viewport_offsets` above for information on how to override the offsets if they aren't correctly rendered. - - - -### ** Common: Surfaces ** - -Quantum Painter has surface drivers which are able to target a buffer in RAM. In general, surfaces keep track of the "dirty" region -- the area that has been drawn to since the last flush -- so that when transferring to the display they can transfer the minimal amount of data to achieve the end result. - -!> These generally require significant amounts of RAM, so at large sizes and/or higher bit depths, they may not be usable on all MCUs. - - - -#### ** RGB565 Surface ** - -Enabling support for RGB565 surfaces in Quantum Painter is done by adding the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS += rgb565_surface -``` - -Creating a RGB565 surface in firmware can then be done with the following API: - -```c -painter_device_t qp_rgb565_make_surface(uint16_t panel_width, uint16_t panel_height, void *buffer); -``` - -The `buffer` is a user-supplied area of memory, and is assumed to be of the size `sizeof(uint16_t) * panel_width * panel_height`. - -The device handle returned from the `qp_rgb565_make_surface` function can be used to perform all other drawing operations. - -Example: - -```c -static painter_device_t my_surface; -static uint16_t my_framebuffer[320 * 240]; // Allocate a buffer for a 320x240 RGB565 display -void keyboard_post_init_kb(void) { - my_surface = qp_rgb565_make_surface(320, 240, my_framebuffer); - qp_init(my_surface, QP_ROTATION_0); -} -``` - -The maximum number of RGB565 surfaces can be configured by changing the following in your `config.h` (default is 1): - -```c -// 3 surfaces: -#define RGB565_SURFACE_NUM_DEVICES 3 -``` - -To transfer the contents of the RGB565 surface to another display, the following API can be invoked: - -```c -bool qp_rgb565_surface_draw(painter_device_t surface, painter_device_t display, uint16_t x, uint16_t y); -``` - -The `surface` is the surface to copy out from. The `display` is the target display to draw into. `x` and `y` are the target location to draw the surface pixel data. Under normal circumstances, the location should be consistent, as the dirty region is calculated with respect to the `x` and `y` coordinates -- changing those will result in partial, overlapping draws. - -?> Calling `qp_flush()` on the surface resets its dirty region. Copying the surface contents to the display also automatically resets the dirty region. - - - - - -## Quantum Painter Drawing API :id=quantum-painter-api - -All APIs require a `painter_device_t` object as their first parameter -- this object comes from the specific device initialisation, and instructions on creating it can be found in each driver's respective section. - -To use any of the APIs, you need to include `qp.h`: -```c -#include -``` - - - -### ** General Notes ** - -The coordinate system used in Quantum Painter generally accepts `left`, `top`, `right`, and `bottom` instead of x/y/width/height, and each coordinate is inclusive of where pixels should be drawn. This is required as some datatypes used by display panels have a maximum value of `255` -- for any value or geometry extent that matches `256`, this would be represented as a `0`, instead. - -?> Drawing a horizontal line 8 pixels long, starting from 4 pixels inside the left side of the display, will need `left=4`, `right=11`. - -All color data matches the standard QMK HSV triplet definitions: - -* Hue is of the range `0...255` and is internally mapped to 0...360 degrees. -* Saturation is of the range `0...255` and is internally mapped to 0...100% saturation. -* Value is of the range `0...255` and is internally mapped to 0...100% brightness. - -?> Colors used in Quantum Painter are not subject to the RGB lighting CIE curve, if it is enabled. - -### ** Device Control ** - - - -#### ** Display Initialisation ** - -```c -bool qp_init(painter_device_t device, painter_rotation_t rotation); -``` - -The `qp_init` function is used to initialise a display device after it has been created. This accepts a rotation parameter (`QP_ROTATION_0`, `QP_ROTATION_90`, `QP_ROTATION_180`, `QP_ROTATION_270`), which makes sure that the orientation of what's drawn on the display is correct. - -```c -static painter_device_t display; -void keyboard_post_init_kb(void) { - display = qp_make_.......; // Create the display - qp_init(display, QP_ROTATION_0); // Initialise the display -} -``` - -#### ** Display Power ** - -```c -bool qp_power(painter_device_t device, bool power_on); -``` - -The `qp_power` function instructs the display whether or not the display panel should be on or off. - -!> If there is a separate backlight controlled through the normal QMK backlight API, this is not controlled by the `qp_power` function and needs to be manually handled elsewhere. - -```c -static uint8_t last_backlight = 255; -void suspend_power_down_user(void) { - if (last_backlight == 255) { - last_backlight = get_backlight_level(); - } - backlight_set(0); - rgb_matrix_set_suspend_state(true); - qp_power(display, false); -} - -void suspend_wakeup_init_user(void) { - qp_power(display, true); - rgb_matrix_set_suspend_state(false); - if (last_backlight != 255) { - backlight_set(last_backlight); - } - last_backlight = 255; -} -``` - -#### ** Display Clear ** - -```c -bool qp_clear(painter_device_t device); -``` - -The `qp_clear` function clears the display's screen. - -#### ** Display Flush ** - -```c -bool qp_flush(painter_device_t device); -``` - -The `qp_flush` function ensures that all drawing operations are "pushed" to the display. This should be done as the last operation whenever a sequence of draws occur, and guarantees that any changes are applied. - -!> Some display panels may seem to work even without a call to `qp_flush` -- this may be because the driver cannot queue drawing operations and needs to display them immediately when invoked. In general, calling `qp_flush` at the end is still considered "best practice". - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw a rect based off the current RGB color - qp_rect(display, 0, 7, 0, 239, rgb_matrix_get_hue(), 255, 255); - qp_flush(display); - } -} -``` - - - -### ** Drawing Primitives ** - - - -#### ** Set Pixel ** - -```c -bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val); -``` - -The `qp_setpixel` can be used to set a specific pixel on the screen to the supplied color. - -?> Using `qp_setpixel` for large amounts of drawing operations is inefficient and should be avoided unless they cannot be achieved with other drawing APIs. - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw a 240px high vertical rainbow line on X=0: - for (int i = 0; i < 239; ++i) { - qp_setpixel(display, 0, i, i, 255, 255); - } - qp_flush(display); - } -} -``` - -#### ** Draw Line ** - -```c -bool qp_line(painter_device_t device, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t hue, uint8_t sat, uint8_t val); -``` - -The `qp_line` can be used to draw lines on the screen with the supplied color. - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw 8px-wide rainbow down the left side of the display - for (int i = 0; i < 239; ++i) { - qp_line(display, 0, i, 7, i, i, 255, 255); - } - qp_flush(display); - } -} -``` - -#### ** Draw Rect ** - -```c -bool qp_rect(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, uint8_t hue, uint8_t sat, uint8_t val, bool filled); -``` - -The `qp_rect` can be used to draw rectangles on the screen with the supplied color, with or without a background fill. If not filled, any pixels inside the rectangle will be left as-is. - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw 8px-wide rainbow filled rectangles down the left side of the display - for (int i = 0; i < 239; i+=8) { - qp_rect(display, 0, i, 7, i+7, i, 255, 255, true); - } - qp_flush(display); - } -} -``` - -#### ** Draw Circle ** - -```c -bool qp_circle(painter_device_t device, uint16_t x, uint16_t y, uint16_t radius, uint8_t hue, uint8_t sat, uint8_t val, bool filled); -``` - -The `qp_circle` can be used to draw circles on the screen with the supplied color, with or without a background fill. If not filled, any pixels inside the circle will be left as-is. - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw r=4 filled circles down the left side of the display - for (int i = 0; i < 239; i+=8) { - qp_circle(display, 4, 4+i, 4, i, 255, 255, true); - } - qp_flush(display); - } -} -``` - -#### ** Draw Ellipse ** - -```c -bool qp_ellipse(painter_device_t device, uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, uint8_t hue, uint8_t sat, uint8_t val, bool filled); -``` - -The `qp_ellipse` can be used to draw ellipses on the screen with the supplied color, with or without a background fill. If not filled, any pixels inside the ellipses will be left as-is. - -```c -void housekeeping_task_user(void) { - static uint32_t last_draw = 0; - if (timer_elapsed32(last_draw) > 33) { // Throttle to 30fps - last_draw = timer_read32(); - // Draw 16x8 filled ellipses down the left side of the display - for (int i = 0; i < 239; i+=8) { - qp_ellipse(display, 8, 4+i, 16, 8, i, 255, 255, true); - } - qp_flush(display); - } -} -``` - - - -### ** Image Functions ** - -Making an image available for use requires compiling it into your firmware. To do so, assuming you've created `my_image.qgf.c` and `my_image.qgf.h` as per the CLI examples above, you'd add the following to your `rules.mk`: - -```make -SRC += my_image.qgf.c -``` - -...and in your `keymap.c`, you'd add to the top of the file: -```c -#include "my_image.qgf.h" -``` - - - -#### ** Load Image ** - -```c -painter_image_handle_t qp_load_image_mem(const void *buffer); -``` - -The `qp_load_image_mem` function loads a QGF image from memory or flash. - -`qp_load_image_mem` returns a handle to the loaded image, which can then be used to draw to the screen using `qp_drawimage`, `qp_drawimage_recolor`, `qp_animate`, or `qp_animate_recolor`. If an image is no longer required, it can be unloaded by calling `qp_close_image` below. - -See the [CLI Commands](quantum_painter.md?id=quantum-painter-cli) for instructions on how to convert images to [QGF](quantum_painter_qgf.md). - -?> The total number of images available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_IMAGES` in the table above. If more images are required, the number should be increased in `config.h`. - -Image information is available through accessing the handle: - -| Property | Accessor | -|-------------|----------------------| -| Width | `image->width` | -| Height | `image->height` | -| Frame Count | `image->frame_count` | - -#### ** Unload Image ** - -```c -bool qp_close_image(painter_image_handle_t image); -``` - -The `qp_close_image` function releases resources related to the loading of the supplied image. - -#### ** Draw image ** - -```c -bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); -bool qp_drawimage_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); -``` - -The `qp_drawimage` and `qp_drawimage_recolor` functions draw the supplied image to the screen at the supplied location, with the latter function allowing for monochrome-based images to be recolored. - -```c -// Draw an image on the bottom-right of the 240x320 display on initialisation -static painter_image_handle_t my_image; -void keyboard_post_init_kb(void) { - my_image = qp_load_image_mem(gfx_my_image); - if (my_image != NULL) { - qp_drawimage(display, (239 - my_image->width), (319 - my_image->height), my_image); - } -} -``` - -#### ** Animate Image ** - -```c -deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); -deferred_token qp_animate_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); -``` - -The `qp_animate` and `qp_animate_recolor` functions draw the supplied image to the screen at the supplied location, with the latter function allowing for monochrome-based animations to be recolored. They also set up internal timing such that each frame is rendered at the correct time as per the animated image. - -Once an image has been set to animate, it will loop indefinitely until stopped, with no user intervention required. - -Both functions return a `deferred_token`, which can then be used to stop the animation, using `qp_stop_animation` below. - -```c -// Animate an image on the bottom-right of the 240x320 display on initialisation -static painter_image_handle_t my_image; -static deferred_token my_anim; -void keyboard_post_init_kb(void) { - my_image = qp_load_image_mem(gfx_my_image); - if (my_image != NULL) { - my_anim = qp_animate(display, (239 - my_image->width), (319 - my_image->height), my_image); - } -} -``` - -#### ** Stop Animation ** - -```c -void qp_stop_animation(deferred_token anim_token); -``` - -The `qp_stop_animation` function stops the previously-started animation. -```c -void housekeeping_task_user(void) { - if (some_random_stop_reason) { - qp_stop_animation(my_anim); - } -} -``` - - - -### ** Font Functions ** - -Making a font available for use requires compiling it into your firmware. To do so, assuming you've created `my_font.qff.c` and `my_font.qff.h` as per the CLI examples above, you'd add the following to your `rules.mk`: - -```make -SRC += noto11.qff.c -``` - -...and in your `keymap.c`, you'd add to the top of the file: -```c -#include "noto11.qff.h" -``` - - - -#### ** Load Font ** - -```c -painter_font_handle_t qp_load_font_mem(const void *buffer); -``` - -The `qp_load_font_mem` function loads a QFF font from memory or flash. - -`qp_load_font_mem` returns a handle to the loaded font, which can then be measured using `qp_textwidth`, or drawn to the screen using `qp_drawtext`, or `qp_drawtext_recolor`. If a font is no longer required, it can be unloaded by calling `qp_close_font` below. - -See the [CLI Commands](quantum_painter.md?id=quantum-painter-cli) for instructions on how to convert TTF fonts to [QFF](quantum_painter_qff.md). - -?> The total number of fonts available to load at any one time is controlled by the configurable option `QUANTUM_PAINTER_NUM_FONTS` in the table above. If more fonts are required, the number should be increased in `config.h`. - -Font information is available through accessing the handle: - -| Property | Accessor | -|-------------|----------------------| -| Line Height | `image->line_height` | - -#### ** Unload Font ** - -```c -bool qp_close_font(painter_font_handle_t font); -``` - -The `qp_close_font` function releases resources related to the loading of the supplied font. - -#### ** Measure Text ** - -```c -int16_t qp_textwidth(painter_font_handle_t font, const char *str); -``` - -The `qp_textwidth` function allows measurement of how many pixels wide the supplied string would result in, for the given font. - -#### ** Draw Text ** - -```c -int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str); -int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); -``` - -The `qp_drawtext` and `qp_drawtext_recolor` functions draw the supplied string to the screen at the given location using the font supplied, with the latter function allowing for monochrome-based fonts to be recolored. - -```c -// Draw a text message on the bottom-right of the 240x320 display on initialisation -static painter_font_handle_t my_font; -void keyboard_post_init_kb(void) { - my_font = qp_load_font_mem(font_noto11); - if (my_font != NULL) { - static const char *text = "Hello from QMK!"; - int16_t width = qp_textwidth(my_font, text); - qp_drawtext(display, (239 - width), (319 - my_font->line_height), my_font, text); - } -} -``` - - - -### ** Advanced Functions ** - - - -#### ** Get Geometry ** - -```c -void qp_get_geometry(painter_device_t device, uint16_t *width, uint16_t *height, painter_rotation_t *rotation, uint16_t *offset_x, uint16_t *offset_y); -``` - -The `qp_get_geometry` function allows external code to retrieve the current width, height, rotation, and drawing offsets. - -#### ** Set Viewport Offsets ** - -```c -void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y); -``` - -The `qp_set_viewport_offsets` function can be used to offset all subsequent drawing operations. For example, if a display controller is internally 240x320, but the display panel is 240x240 and has a Y offset of 80 pixels, you could invoke `qp_set_viewport_offsets(display, 0, 80);` and the drawing positioning would be corrected. - -#### ** Set Viewport ** - -```c -bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom); -``` - -The `qp_viewport` function controls where raw pixel data is written to. - -#### ** Stream Pixel Data ** - -```c -bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count); -``` - -The `qp_pixdata` function allows raw pixel data to be streamed to the display. It requires a native pixel count rather than the number of bytes to transfer, to ensure display panel data alignment is respected. E.g. for display panels using RGB565 internal format, sending 10 pixels will result in 20 bytes of transfer. - -!> Under normal circumstances, users will not need to manually call either `qp_viewport` or `qp_pixdata`. These allow for writing of raw pixel information, in the display panel's native format, to the area defined by the viewport. - - - - diff --git a/docs/quantum_painter_lvgl.md b/docs/quantum_painter_lvgl.md deleted file mode 100644 index 4d10160baf4b..000000000000 --- a/docs/quantum_painter_lvgl.md +++ /dev/null @@ -1,55 +0,0 @@ -# Quantum Painter LVGL Integration :id=lvgl - -LVGL (Light and Versatile Graphics Library) is an open-source graphics library providing everything you need to create an embedded GUI for your board with easy-to-use graphical elements. - -LVGL integrates with [Quantum Painter's](quantum_painter.md) API and drivers to render to the display, the hardware supported by Quantum Painter is also supported by LVGL. - -?> Keep in mind that enabling the LVGL integration has a big impact in firmware size, it is recommeded to use a supported MCU with >256 kB of flash space. - -To learn more about LVGL and how to use it please take a look at their [official documentation](https://docs.lvgl.io/8.2/intro/) - -## Enabling LVGL :id=lvgl-enabling -To enable LVGL to be built into your firmware, add the following to `rules.mk`: - -```make -QUANTUM_PAINTER_ENABLE = yes -QUANTUM_PAINTER_DRIVERS = ...... -QUANTUM_PAINTER_LVGL_INTEGRATION = yes -``` -To configure the Quantum Painter Display Drivers please read the [Quantum Painter Display Drivers](quantum_painter.md#quantum-painter-drivers) section. - -## Quantum Painter LVGL API :id=lvgl-api - -### Quantum Painter LVGL Attach :id=lvgl-api-init - -```c -bool qp_lvgl_attach(painter_device_t device); -``` - -The `qp_lvgl_attach` function is used to set up LVGL with the supplied display, and requires an already configured display. - -```c -static painter_device_t display; -void keyboard_post_init_kb(void) { - display = qp_make_.......; // Create the display - qp_init(display, QP_ROTATION_0); // Initialise the display - - if (qp_lvgl_attach(display)) { // Attach LVGL to the display - ...Your code to draw // Run LVGL specific code to draw - } -} -``` -To init. the display please read the [Display Initialisation](quantum_painter.md#quantum-painter-api-init) section. - -!> Attaching LVGL to a display means LVGL subsequently "owns" the display. Using standard Quantum Painter drawing operations with the display after LVGL attachment will likely result in display artifacts. -### Quantum Painter LVGL Detach :id=lvgl-api-init - -```c -void qp_lvgl_detach(void) -``` - -The `qp_lvgl_detach` function stops the internal LVGL ticks and releases resources related to it. - -## Enabling/Disabling LVGL features :id=lvgl-configuring - -You can overwrite LVGL specific features in your `lv_conf.h` file. diff --git a/docs/quantum_painter_qff.md b/docs/quantum_painter_qff.md deleted file mode 100644 index f62d59bdcb1b..000000000000 --- a/docs/quantum_painter_qff.md +++ /dev/null @@ -1,103 +0,0 @@ -# QMK Font Format :id=qmk-font-format - -QMK uses a font format _("Quantum Font Format" - QFF)_ specifically for resource-constrained systems. - -This format is capable of encoding 1-, 2-, 4-, and 8-bit-per-pixel greyscale- and palette-based images into a font. It also includes RLE for pixel data for some basic compression. - -All integer values are in little-endian format. - -The QFF is defined in terms of _blocks_ -- each _block_ contains a _header_ and an optional _blob_ of data. The _header_ contains the block's _typeid_, and the length of the _blob_ that follows. Each block type is denoted by a different _typeid_ has its own block definition below. All blocks are defined as packed structs, containing zero padding between fields. - -The general structure of the file is: - -* _Font descriptor block_ -* _ASCII glyph block_ (optional, only if ASCII glyphs are included) -* _Unicode glyph block_ (optional, only if Unicode glyphs are included) -* _Font palette block_ (optional, depending on frame format) -* _Font data block_ - -## Block Header :id=qff-block-header - -The block header is identical to [QGF's block header](quantum_painter_qgf.md#qgf-block-header), and is present for all blocks, including the font descriptor. - -## Font descriptor block :id=qff-font-descriptor - -* _typeid_ = 0x00 -* _length_ = 20 - -This block must be located at the start of the file contents, and can exist a maximum of once in an entire QGF file. It is always followed by either the _ASCII glyph table_ or the _Unicode glyph table_, depending on which glyphs are included in the font. - -_Block_ format: - -```c -typedef struct __attribute__((packed)) qff_font_descriptor_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x00, .neg_type_id = (~0x00), .length = 20 } - uint24_t magic; // constant, equal to 0x464651 ("QFF") - uint8_t qff_version; // constant, equal to 0x01 - uint32_t total_file_size; // total size of the entire file, starting at offset zero - uint32_t neg_total_file_size; // negated value of total_file_size, used for detecting parsing errors - uint8_t line_height; // glyph height in pixels - bool has_ascii_table; // whether the font has an ascii table of glyphs (0x20...0x7E) - uint16_t num_unicode_glyphs; // the number of glyphs in the unicode table -- no table specified if zero - uint8_t format; // frame format, see below. - uint8_t flags; // frame flags, see below. - uint8_t compression_scheme; // compression scheme, see below. - uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) -} qff_font_descriptor_v1_t; -// _Static_assert(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF"); -``` - -The values for `format`, `flags`, `compression_scheme`, and `transparency_index` match [QGF's frame descriptor block](quantum_painter_qgf.md#qgf-frame-descriptor), with the exception that the `delta` flag is ignored by QFF. - -## ASCII glyph table :id=qff-ascii-table - -* _typeid_ = 0x01 -* _length_ = 290 - -If the font contains ascii characters, the _ASCII glyph block_ must be located directly after the _font descriptor block_. - -```c -#define QFF_GLYPH_WIDTH_BITS 6 -#define QFF_GLYPH_WIDTH_MASK ((1<= 128 - length = marker - 128 - for i = 0 ... length-1 - c = READ_OCTET() - WRITE_OCTET(c) - - else - length = marker - c = READ_OCTET() - for i = 0 ... length-1 - WRITE_OCTET(c) - -``` diff --git a/docs/redirects.json b/docs/redirects.json deleted file mode 100644 index 651148c2c129..000000000000 --- a/docs/redirects.json +++ /dev/null @@ -1,52 +0,0 @@ -{ - "redirects": [ - { - "from": "adding_a_keyboard_to_qmk.html", - "to": "hardware_keyboard_guidelines.html" - }, - { - "from": "build_environment_setup.html", - "to": "getting_started_build_tools.html" - }, - { - "from": "dynamic_macros.html", - "to": "feature_dynamic_macros.html" - }, - { - "from": "feature_common_shortcuts.html", - "to": "feature_advanced_keycodes.html" - }, - { - "from": "glossary.html", - "to": "reference_glossary.html" - }, - { - "from": "key_lock.html", - "to": "feature_key_lock.html" - }, - { - "from": "make_instructions.html", - "to": "getting_started_make_guide.html" - }, - { - "from": "porting_your_keyboard_to_qmk.html", - "to": "hardware_avr.html" - }, - { - "from": "space_cadet_shift.html", - "to": "feature_space_cadet_shift.html" - }, - { - "from": "tap_dance.html", - "to": "feature_tap_dance.html" - }, - { - "from": "unicode.html", - "to": "feature_unicode.html" - }, - { - "from": "python_development.html", - "to": "cli_development.html" - } - ] -} diff --git a/docs/ref_functions.md b/docs/ref_functions.md deleted file mode 100644 index c82c5747c2b8..000000000000 --- a/docs/ref_functions.md +++ /dev/null @@ -1,123 +0,0 @@ -# List of Useful Core Functions To Make Your Keyboard Better - -There are a lot of hidden functions in QMK that are incredibly useful, or may add a bit of functionality that you've been wanting. Functions that are specific to certain features are not included here, as those will be on their respective feature page. - -## (OLKB) Tri Layers :id=olkb-tri-layers - -There are actually separate functions that you can use there, depending on what you're after. - -### `update_tri_layer(x, y, z)` - -The first is the `update_tri_layer(x, y, z)` function. This function check to see if layers `x` and `y` are both on. If they are both on, then it turns on layer `z`. Otherwise, if both `x` and `y` are not both on (either only one is, or neither is), then it turns off layer `z`. - -This function is useful if you want to create specific keys that have this functionality, but other layer keycodes won't do this. - -#### Example - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LOWER: - if (record->event.pressed) { - layer_on(_LOWER); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } else { - layer_off(_LOWER); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } - return false; - case RAISE: - if (record->event.pressed) { - layer_on(_RAISE); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } else { - layer_off(_RAISE); - update_tri_layer(_LOWER, _RAISE, _ADJUST); - } - return false; - } - return true; -} -``` - -### `update_tri_layer_state(state, x, y, z)` -The other function is `update_tri_layer_state(state, x, y, z)`. This function is meant to be called from the [`layer_state_set_*` functions](custom_quantum_functions.md#layer-change-code). This means that any time that you use a keycode to change the layer, this will be checked. So you could use `LT(layer, kc)` to change the layer and it will trigger the same layer check. - -There are a couple of caveats to this method: -1. You cannot access the `z` layer without having `x` and `y` layers on, since if you try to activate just layer `z`, it will run this code and turn off layer `z` before you could use it. -2. Because layers are processed from the highest number `z` should be a higher layer than `x` and `y` or you may not be able to access it. - -#### Example - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - return update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); -} -``` - -Alternatively, you don't have to immediately "return" the value. This is useful if you want to add multiple tri layers, or if you want to add additional effects. - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - state = update_tri_layer_state(state, _LOWER, _RAISE, _ADJUST); - state = update_tri_layer_state(state, _RAISE, _SYMB, _SPECIAL); - return state; -} -``` - -## Setting the Persistent Default Layer - -Do you want to set the default layer, so that it's retained even after you unplug the board? If so, this is the function for you. - -To use this, you would use `set_single_persistent_default_layer(layer)`. If you have a name defined for your layer, you can use that instead (such as _QWERTY, _DVORAK or _COLEMAK). - -This will set the default layer, update the persistent settings, and play a tune if you have [Audio](feature_audio.md) enabled on your board, and the default layer sounds set. - -To configure the default layer sounds, you would want to define this in your `config.h` file, like this: - -```c -#define DEFAULT_LAYER_SONGS { SONG(QWERTY_SOUND), \ - SONG(COLEMAK_SOUND), \ - SONG(DVORAK_SOUND) \ - } -``` - - -?> There are a large number of predefined songs in [quantum/audio/song_list.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/audio/song_list.h) that you can use. - -## Resetting the keyboard - -There is the `QK_REBOOT` or `QK_RBT` quantum keycode that you can use. But if you want to reset the board as part of a macro, rather than hitting a key separately, you can do that. - -And to do so, add `soft_reset_keyboard()` to your function or macro. - -## Reset to bootloader - -To reset to the bootloader use `QK_BOOTLOADER` or `QK_BOOT` keycode or `reset_keyboard()` function. - -## Wiping the EEPROM (Persistent Storage) - -If you're having issues with Audio, RGB Underglow, backlighting or keys acting weird, then you can reset the EEPROM (persistent setting storage). To force an EEPROM reset, use the [`EE_CLR` keycode](quantum_keycodes.md) or [Bootmagic Lite](feature_bootmagic.md) functionality. If neither of those are an option, then you can use a custom macro to do so. - -To wipe the EEPROM, run `eeconfig_init()` from your function or macro to reset most of the settings to default. - -## Tap random key - -If you want to send a random character to the host computer, you can use the `tap_random_base64()` function. This [pseudorandomly](https://en.wikipedia.org/wiki/Pseudorandom_number_generator) selects a number between 0 and 63, and then sends a key press based on that selection. (0–25 is `A`–`Z`, 26–51 is `a`–`z`, 52–61 is `0`–`9`, 62 is `+` and 63 is `/`). - -?> Needless to say, but this is _not_ a cryptographically secure method of generating random Base64 keys or passwords. - -## Software Timers - -It's possible to start timers and read values for time-specific events. Here's an example: - -```c -static uint16_t key_timer; -key_timer = timer_read(); - -if (timer_elapsed(key_timer) < 100) { - // do something if less than 100ms have passed -} else { - // do something if 100ms or more have passed -} -``` diff --git a/docs/reference_configurator_support.md b/docs/reference_configurator_support.md deleted file mode 100644 index db6cd80a20a4..000000000000 --- a/docs/reference_configurator_support.md +++ /dev/null @@ -1,195 +0,0 @@ -# Supporting Your Keyboard in QMK Configurator - -This page covers how to properly support keyboards in the [QMK Configurator](https://config.qmk.fm/). - - -## How the Configurator Understands Keyboards - -To understand how the Configurator understands keyboards, first one must understand layout macros. For this exercise, we're going to imagine a 17-key numpad PCB, which we're going to call `numpad`. - -``` -|---------------| -|NLk| / | * | - | -|---+---+---+---| -|7 |8 |9 | + | -|---+---+---| | -|4 |5 |6 | | -|---+---+---+---| -|1 |2 |3 |Ent| -|-------+---| | -|0 | . | | -|---------------| -``` - -?> For more on layout macros, see [Understanding QMK: Matrix Scanning](understanding_qmk.md?id=matrix-scanning) and [Understanding QMK: Matrix to Physical Layout Map](understanding_qmk.md?id=matrix-to-physical-layout-map). - -The Configurator's API reads the keyboard's `.h` file from `qmk_firmware/keyboards//.h`. For our numpad, this file would be `qmk_firmware/keyboards/numpad/numpad.h`: - -```c -#pragma once - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, KC_NO }, \ - { k30, k31, k32, k33 }, \ - { k40, KC_NO, k42, KC_NO } \ -} -``` - -QMK uses `KC_NO` to designate places in the switch matrix where there is no switch. Sometimes, `XXX`, `___` or `____` are used as shorthand to make this section easier to read if it needs to be debugged. This is usually defined near the beginning of the `.h` file: - -```c -#pragma once - -#define XXX KC_NO - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, XXX }, \ - { k30, k31, k32, k33 }, \ - { k40, XXX, k42, XXX } \ -} -``` - -!> This usage differs from that of keymap macros, which almost always use `XXXXXXX` (seven capital X's) for `KC_NO` and `_______` (seven underscores) for `KC_TRNS`. - -!> To prevent user confusion, using `KC_NO` is preferred. - -The layout macro tells the Configurator that our keyboard has 17 keys, arranged in five rows of four columns each. Our switch positions are named `k`, counting from 0. The names themselves actually don't matter, as long as they match between the top section, which receives the keycodes from the keymap, and the bottom half which designates where each key is in the matrix. - -To display our keyboard in a way that resembles the physical keyboard, we need to build a JSON file that tells the Configurator how to tie the physical locations and sizes of our keys to our switch matrix. - -## Building the JSON file - -To build the JSON file, the easiest way is to build the layout in [Keyboard Layout Editor](https://www.keyboard-layout-editor.com/) ("KLE"), from which we'll feed the Raw Data into a QMK tool that converts this data into a JSON the Configurator will read and use. Since KLE opens by default with a numpad layout, we're just going to remove the Getting Started instructions, and use what's left. - -Once the layout is as desired, move to the Raw Data tab in KLE, and copy the contents: - -``` -["Num Lock","/","*","-"], -["7\nHome","8\n↑","9\nPgUp",{h:2},"+"], -["4\n←","5","6\n→"], -["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"], -[{w:2},"0\nIns",".\nDel"] -``` - -To convert this data into our JSON, go to the [QMK KLE-JSON Converter](https://qmk.fm/converter/), paste the Raw Data into the Input field, and click the Convert button. After a moment, our JSON data will appear in the Output field. Copy the contents to a new text document, and name the document `info.json`, saving it in the same folder that contains `numpad.h`. - -Use the `keyboard_name` object to set the name of the keyboard. For instruction purposes, we will put each key's object on its own line. This is only to make the file more human-readable, and does not affect the Configurator's functionality. - -```json -{ - "keyboard_name": "Numpad", - "url": "", - "maintainer": "qmk", - "tags": { - "form_factor": "numpad" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label":"Num Lock", "x":0, "y":0}, - {"label":"/", "x":1, "y":0}, - {"label":"*", "x":2, "y":0}, - {"label":"-", "x":3, "y":0}, - {"label":"7", "x":0, "y":1}, - {"label":"8", "x":1, "y":1}, - {"label":"9", "x":2, "y":1}, - {"label":"+", "x":3, "y":1, "h":2}, - {"label":"4", "x":0, "y":2}, - {"label":"5", "x":1, "y":2}, - {"label":"6", "x":2, "y":2}, - {"label":"1", "x":0, "y":3}, - {"label":"2", "x":1, "y":3}, - {"label":"3", "x":2, "y":3}, - {"label":"Enter", "x":3, "y":3, "h":2}, - {"label":"0", "x":0, "y":4, "w":2}, - {"label":".", "x":2, "y":4} - ] - } - } -} -``` - -The `layouts` object contains the data that represents the physical layout of the keyboard. It has an object `LAYOUT`, which needs to match the name of our layout macro from `numpad.h`. The `LAYOUT` object itself has an object named `layout`, which contains one JSON object for each physical key on our keyboard, formatted as follows: - -``` - The name of the key. Not displayed in the Configurator. - | - | The key's X-axis location, in key units from the - | | keyboard's left edge. - | | - | | The key's Y-axis location, in key units from - | | | the keyboard's top (rear-facing) edge. - ↓ ↓ ↓ -{"label":"Num Lock", "x":0, "y":0}, -``` - -Some objects will also have `"w"` and `"h"` keys, which represent a key's width and height, respectively. - -?> For more on the `info.json` files, see [`info.json` Format](reference_info_json.md). - - -## How the Configurator Programs Keys - -The Configurator's API uses the layout macro and the JSON file we've given it to create a visual representation of the keyboard that has each visual object tied to a specific key, in sequence: - -key in layout macro | JSON object used -:---: | :---- -k00 | {"label":"Num Lock", "x":0, "y":0} -k01 | {"label":"/", "x":1, "y":0} -k02 | {"label":"*", "x":2, "y":0} -k03 | {"label":"-", "x":3, "y":0} -k10 | {"label":"7", "x":0, "y":1} -k11 | {"label":"8", "x":1, "y":1} -k12 | {"label":"9", "x":2, "y":1} -k13 | {"label":"+", "x":3, "y":1, "h":2} -k20 | {"label":"4", "x":0, "y":2} -k21 | {"label":"5", "x":1, "y":2} -k22 | {"label":"6", "x":2, "y":2} -k30 | {"label":"1", "x":0, "y":3} -k31 | {"label":"2", "x":1, "y":3} -k32 | {"label":"3", "x":2, "y":3} -k33 | {"label":"Enter", "x":3, "y":3, "h":2} -k40 | {"label":"0", "x":0, "y":4, "w":2} -k42 | {"label":".", "x":2, "y":4} - -When a user selects the top-left key in the Configurator, and assigns Num Lock to it, the Configurator builds a keymap file with `KC_NUM` as the first key, and so on as the keymap is built. The `label` keys are not used; they are only for the user's reference in identifying specific keys when debugging the `info.json` file. - - -## Issues and Hazards - -Currently, the Configurator does not support key rotation or non-rectangular key shapes like ISO Enter. Additionally, keys that are vertically-offset from their "row" — the arrow keys on 1800-layouts like the [TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/) being a prominent example — confuse the KLE-to-JSON Converter, if not adjusted for by the contributor of the `info.json` file. - -### Workarounds - -#### Non-rectangular keys - -For ISO Enter keys, QMK custom is to display it as a rectangular key, 1.25u wide and 2u high, aligned so its right edge is aligned with the right edge of the alphanumeric key block. - -![](https://i.imgur.com/JKngtTw.png) -*A 60% keyboard in standard ISO layout, as rendered by QMK Configurator.* - -#### Vertically-offset keys - -For vertically-offset keys, place them in KLE as if they were not offset, then edit the Y-values as needed in the converted JSON file - -![](https://i.imgur.com/fmDvDzR.png) -*An 1800-layout keyboard as rendered in Keyboard Layout Editor, without the vertical offset applied to the arrow keys.* - -![](https://i.imgur.com/8beYMBR.png) -*A Unix diff file, showing the changes needed to vertically-offset the arrow keys in our keyboard's JSON file.* diff --git a/docs/reference_glossary.md b/docs/reference_glossary.md deleted file mode 100644 index ace6b5f330bb..000000000000 --- a/docs/reference_glossary.md +++ /dev/null @@ -1,167 +0,0 @@ -# Glossary of QMK Terms - -## ARM -A line of 32-bit MCUs produced by a number of companies, such as Atmel, Cypress, Kinetis, NXP, ST, and TI. - -## AVR -A line of 8-bit MCUs produced by [Atmel](https://www.microchip.com/). AVR was the original platform that TMK supported. - -## AZERTY -The standard Français (French) keyboard layout. Named for the first 6 keys on the keyboard. - -## Backlight -A generic term for lighting on a keyboard. The backlight is typically, but not always, an array of LEDs that shine through keycaps and/or switches. - -## Bluetooth -A short range peer to peer wireless protocol. Most common wireless protocol for a keyboard. - -## Bootloader -A special program that is written to a protected area of your MCU that allows the MCU to upgrade its own firmware, typically over USB. - -## Bootmagic -A feature that allows for various keyboard behavior changes to happen on the fly, such as swapping or disabling common keys. - -## C -A low-level programming language suitable for system code. Most QMK code is written in C. - -## Colemak -An alternative keyboard layout that is gaining in popularity. - -## Compile -The process of turning human readable code into machine code your MCU can run. - -## Dvorak -An alternative keyboard layout developed by Dr. August Dvorak in the 1930's. A shortened form of the Dvorak Simplified Keyboard. - -## Dynamic Macro -A macro which has been recorded on the keyboard and which will be lost when the keyboard is unplugged or the computer rebooted. - -* [Dynamic Macro Documentation](feature_dynamic_macros.md) - -## Eclipse -An IDE that is popular with many C developers. - -* [Eclipse Setup Instructions](other_eclipse.md) - -## Firmware -The software that controls your MCU. - -## git -Versioning software used at the command line - -## GitHub -The website that hosts most of the QMK project. It provides integration with git, issue tracking, and other features that help us run QMK. - -## ISP -In-system programming, a method of programming an AVR chip using external hardware and the JTAG pins. - -## hid_listen -An interface for receiving debugging messages from your keyboard. You can view these messages using [QMK Flasher](https://github.com/qmk/qmk_flasher) or [PJRC's hid_listen](https://www.pjrc.com/teensy/hid_listen.html) - -## Keycode -A 2-byte number that represents a particular key. `0x00`-`0xFF` are used for [Basic Keycodes](keycodes_basic.md) while `0x100`-`0xFFFF` are used for [Quantum Keycodes](quantum_keycodes.md). - -## Key Down -An event that happens when a key is pressed down, but is completed before a key is released. - -## Key Up -An event that happens when a key is released. - -## Keymap -An array of keycodes mapped to a physical keyboard layout, which are processed on key presses and releases - -## Layer -An abstraction used to allow a key to serve multiple purposes. The highest active layer takes precedence. - -## Leader Key -A feature that allows you to tap the leader key followed by a sequence of 1, 2, or 3 keys to activate key presses or other quantum features. - -* [Leader Key Documentation](feature_leader_key.md) - -## LED -Light Emitting Diode, the most common device used for indicators on a keyboard. - -## Make -Software package that is used to compile all the source files. You run `make` with various options to compile your keyboard firmware. - -## Matrix -A wiring pattern of columns and rows that enables the MCU to detect keypresses with a fewer number of pins. The matrix often incorporates diodes to allow for NKRO. - -## Macro -A feature that lets you send multiple keypress events (hid reports) after having pressed only a single key. - -* [Macro Documentation](feature_macros.md) - -## MCU -Microcontrol Unit, the processor that powers your keyboard. - -## Modifier -A key that is held down while typing another key to modify the action of that key. Examples include Ctrl, Alt, and Shift. - -## Mousekeys -A feature that lets you control your mouse cursor and click from your keyboard. - -* [Mousekeys Documentation](feature_mouse_keys.md) - -## N-Key Rollover (NKRO) -A term that applies to keyboards that are capable of reporting any number of key-presses at once. - -## Oneshot Modifier -A modifier that acts as if it is held down until another key is released, so you can press the mod and then press the key, rather than holding the mod while pressing the key. Also known as a Sticky key or a Dead key. - -## ProMicro -A low cost AVR development board. Clones of this device are often found on ebay very inexpensively (under $5) but people often struggle with flashing their pro micros. - -## Pull Request -A request to submit code to QMK. We encourage all users to submit Pull Requests for their personal keymaps. - -## QWERTY -The standard English keyboard layout, and often a shortcut for other language's standard layouts. Named for the first 6 letters on the keyboard. - -## QWERTZ -The standard Deutsche (German) keyboard layout. Named for the first 6 letters on the keyboard. - -## Rollover -The term for pressing a key while a key is already held down. Variants include 2KRO, 6KRO, and NKRO. - -## Scancode -A 1 byte number that is sent as part of a HID report over USB that represents a single key. These numbers are documented in the [HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf) published by the [USB-IF](https://www.usb.org/). - -## Space Cadet Shift -A special set of shift keys which allow you to type various types of braces by tapping the left or right shift one or more times. - -* [Space Cadet Shift Documentation](feature_space_cadet.md) - -## Tap -Pressing and releasing a key. In some situations you will need to distinguish between a key down and a key up event, and Tap always refers to both at once. - -## Tap Dance -A feature that lets you assign multiple keycodes to the same key based on how many times you press it. - -* [Tap Dance Documentation](feature_tap_dance.md) - -## Teensy -A low-cost AVR development board that is commonly used for hand-wired builds. A teensy is often chosen despite costing a few dollars more due to its halfkay bootloader, which makes flashing very simple. - -## Underlight -A generic term for LEDs that light the underside of the board. These LEDs typically shine away from the bottom of the PCB and towards the surface the keyboard rests on. - -## Unicode -In the larger computer world Unicode is a set of encoding schemes for representing characters in any language. As it relates to QMK it means using various OS schemes to send unicode codepoints instead of scancodes. - -* [Unicode Documentation](feature_unicode.md) - -## Unit Testing -A framework for running automated tests against QMK. Unit testing helps us be confident that our changes do not break anything. - -* [Unit Testing Documentation](unit_testing.md) - -## USB -Universal Serial Bus, the most common wired interface for a keyboard. - -## USB Host (or simply Host) -The USB Host is your computer, or whatever device your keyboard is plugged into. - -# Couldn't Find the Term You're Looking For? - -[Open an issue](https://github.com/qmk/qmk_firmware/issues) with your question and the term in question could be added here. Better still, open a pull request with the definition. :) diff --git a/docs/reference_info_json.md b/docs/reference_info_json.md deleted file mode 100644 index b5c9b3be9966..000000000000 --- a/docs/reference_info_json.md +++ /dev/null @@ -1,369 +0,0 @@ -# `info.json` - -The information contained in `info.json` is combined with the `config.h` and `rules.mk` files, dynamically generating the necessary configuration for your keyboard at compile time. It is also used by the [QMK API](https://github.com/qmk/qmk_api), and contains the information [QMK Configurator](https://config.qmk.fm/) needs to display a representation of your keyboard. Its key/value pairs are ruled by the [`data/schemas/keyboard.jsonschema`](https://github.com/qmk/qmk_firmware/blob/master/data/schemas/keyboard.jsonschema) file. To learn more about the why and how of the schema file see the [Data Driven Configuration](https://docs.qmk.fm/#/data_driven_config) page. - -You can create `info.json` files at every level under `qmk_firmware/keyboards/`. These files are combined, with more specific files overriding keys in less specific files. This means you do not need to duplicate your metadata information. For example, `qmk_firmware/keyboards/clueboard/info.json` specifies `manufacturer` and `maintainer`, while `qmk_firmware/keyboards/clueboard/66/info.json` specifies more specific information about Clueboard 66%. - -## `info.json` Format - -The `info.json` file is a JSON formatted dictionary. The first six keys noted here must be defined in `info.json`, or your keyboard will not be accepted into the QMK repository. - -* `keyboard_name` - * A free-form text string describing the keyboard. - * Example: `Clueboard 66%` -* `manufacturer` - * A free-form text string describing the keyboard's manufacturer. - * Example: `Clueboard` -* `url` - * A URL to the keyboard's product page, [QMK.fm/keyboards](https://qmk.fm/keyboards) page, or other page describing information about the keyboard. - * Example: `https://clueboard.co` -* `maintainer` - * GitHub username of the maintainer, or `qmk` for community maintained boards. - * Example: `skullydazed` -* `usb` - * Configure USB VID, PID, and device version. See the [USB](#USB) section for more detail. -* `debounce` - * The amount of time in milliseconds to wait for debounce to happen. - * Default: `5` -* `diode_direction` - * The direction diodes face. See [`DIRECT_PINS` in the hardware configuration](https://docs.qmk.fm/#/config_options?id=hardware-options) for more details. -* `layout_aliases` - * A dictionary containing layout aliases. The key is the alias and the value is a layout in `layouts` it maps to. -* `layouts` - * Physical Layout representations. See the [Layout Format](#layout-format) section for more detail. -* `matrix_pins` - * Configure the pins corresponding to columns and rows, or direct pins. See the [Matrix Pins](#matrix-pins) section for more detail. -* `rgblight` - * Configure the [RGB Lighting feature](feature_rgblight.md). See the [RGB Lighting](#rgb-lighting) section for more detail. - - -?> For all the available keys and their allowed values refer back to the [`data/schemas/keyboard.jsonschema`](https://github.com/qmk/qmk_firmware/blob/master/data/schemas/keyboard.jsonschema) file. - -## Layout Format - -Within our `info.json` file the `layouts` portion of the dictionary contains several nested dictionaries. The outer layer consists of QMK layout macros, for example `LAYOUT_ansi` or `LAYOUT_iso`. - -* `layout` - * A list of Key Dictionaries describing the physical layout. See the next section for more details. - -### Key Dictionary Format - -Each Key Dictionary in a layout describes the physical properties of a key. If you are familiar with the Raw Data for you will find many of the concepts the same. We re-use the same key names and layout choices wherever possible, but unlike keyboard-layout-editor each key is stateless, inheriting no properties from the keys that came before it. - -All key positions and rotations are specified in relation to the top-left corner of the keyboard, and the top-left corner of each key. - -* `x` - * **Required**. The absolute position of the key in the horizontal axis, in Key Units. -* `y` - * **Required**. The absolute position of the key in the vertical axis, in Key Units. -* `w` - * The width of the key, in Key Units. - * Default: `1` -* `h` - * The height of the key, in Key Units. - * Default: `1` -* `label` - * What to name this position in the matrix. This should usually correspond to the keycode for the first layer of the default keymap. -* `matrix` - * A two item list describing the row and column location for this key. - * Example: `[0, 4]` - -## Matrix Pins - -Currently QMK supports connecting switches either directly to GPIO pins or via a switch matrix. At this time you can not combine these, they are mutually exclusive. - -### Switch Matrix - -Most keyboards use a switch matrix to connect keyswitches to the MCU. You can define your pin columns and rows to configure your switch matrix. When defining switch matrices you should also define your `diode_direction`. - -Example: - -```json -{ - "diode_direction": "COL2ROW", - "matrix_pins": { - "cols": ["F4", "E6", "B1", "D2"], - "rows": ["B0", "D3", "D5", "D4", "D6"] - } -} -``` - -### Direct Pins - -Direct pins are when you connect one side of the switch to GND and the other side to a GPIO pin on your MCU. No diode is required, but there is a 1:1 mapping between switches and pins. - -When specifying direct pins you need to arrange them in nested arrays. The outer array consists of rows, while the inner array uses text strings to identify the pins used in each row. You can use `null` to indicate an empty spot in the matrix. - -Notice that when using direct pins, `diode_direction` is left undefined. - -Example: - -```json -{ - "matrix_pins": { - "direct": [ - ["A10", "A9"], - ["A0", "B8"], - [null, "B11"], - ["B9", "A8"], - ["A7", "B1"], - [null, "B2"] - ] - } -} -``` - -### Additional Options - -* `input_pressed_state` - * This configures state of the GPIO pins when the key is pressed - `1` for high, `0` for low - * Default: `0` - -Example: - -```json - "matrix_pins": { - "input_pressed_state": 1, -}, -``` - -## Non-RGB LED Lighting - -This section controls basic 2-pin LEDs, which typically pass through keyswitches and are soldered into the PCB, or are placed in PCB sockets. -### Backlight - -Enable by setting - -```json - "features": { - "backlight": true - } -``` - -* `breathing` - * Enable backlight breathing, if supported -* `breathing_period` - * The length of one backlight “breath” in seconds -* `levels` - * The number of brightness levels (maximum 31, excluding off) -* `max_brightness` - * The maximum duty cycle of the backlight LED(s) (0-255) -* `pin` - * The pin that controls the backlight LED(s) -* `pins` - * Array of pins that controls the backlight LED(s) (See [Multiple Backlight Pins](feature_backlight.md#multiple-backlight-pins)) -* `on_state` - * The state of the indicator pins when the LED is "on" - `1` for high, `0` for low - * Default: `1` - -Example: - -```json -{ - "backlight": { - "breathing": true, - "breathing_period": 5, - "levels": 15, - "pin": "B7" - } -} -``` - -### LED Indicators - -Used for indicating Num Lock, Caps Lock, and Scroll Lock. May be soldered in-switch or in a dedicated area. - -* `num_lock` - * The pin that controls the `Num Lock` LED -* `caps_lock` - * The pin that controls the `Caps Lock` LED -* `scroll_lock` - * The pin that controls the `Scroll Lock` LED -* `compose` - * The pin that controls the `Compose` LED -* `kana` - * The pin that controls the `Kana` LED -* `on_state` - * The state of the indicator pins when the LED is "on" - `1` for high, `0` for low - * Default: `1` - -Example: - -```json -{ - "indicators": { - "num_lock": "B6", - "caps_lock": "D2", - "scroll_lock": "A3" - } -} - -``` - -## RGB Lighting - -This section controls the legacy WS2812 support in QMK. This should not be confused with the RGB Matrix feature, which can be used to control both WS2812 and ISSI RGB LEDs. - -The following items can be set. Not every value is required. - -* `led_count` - * The number of LEDs in your strip -* `pin` - * The GPIO pin that your LED strip is connected to -* `animations` - * A dictionary that lists enabled and disabled animations. See [RGB Light Animations](#rgb_light_animations) below. -* `sleep` - * Set to `true` to enable lighting during host sleep -* `split` - * Set to `true` to enable synchronization functionality between split halves -* `split_count` - * For split keyboards, the number of LEDs on each side - * Example `[ 10 , 10 ]` -* `max_brightness` - * What the maximum brightness (value) level is (0-255) -* `hue_steps` - * How many steps of adjustment to have for hue -* `saturation_steps` - * How many steps of adjustment to have for saturation -* `brightness_steps` - * How many steps of adjustment to have for brightness (value) - -Example: - -```json -{ - "rgblight": { - "led_count": 4, - "pin": "F6", - "hue_steps": 10, - "saturation_steps": 17, - "brightness_steps": 17, - "animations": { - "knight": true, - "rainbow_swirl": true - } - } -} -``` - -### RGBLight Animations - -The following animations can be enabled: - -|Key |Description | -|-----------------|--------------------------------------| -|`alternating` |Enable alternating animation mode. | -|`breathing` |Enable breathing animation mode. | -|`christmas` |Enable christmas animation mode. | -|`knight` |Enable knight animation mode. | -|`rainbow_mood` |Enable rainbow mood animation mode. | -|`rainbow_swirl` |Enable rainbow swirl animation mode. | -|`rgb_test` |Enable RGB test animation mode. | -|`snake` |Enable snake animation mode. | -|`static_gradient`|Enable static gradient mode. | -|`twinkle` |Enable twinkle animation mode. | - -## USB - -Every USB keyboard needs to have its USB parameters defined. At a minimum you need to set the Vendor ID, Product ID, and device version. - -Example: - -```json -{ - "usb": { - "vid": "0xC1ED", - "pid": "0x23B0", - "device_version": "1.0.0" - } -} -``` - -The device version is a BCD (binary coded decimal) value, in the format `MMmr`, so the below value would look like `0x0100` in the generated code. This also means the maximum valid values for each part are `99.9.9`, despite it being a hexadecimal value under the hood. - -## Encoders - -This section controls the basic [rotary encoder](feature_encoders.md) support. - -Enable by setting - -```json - "features": { - "encoder": true - } -``` - -The following items can be set. Not every value is required. - -* `pin_a` - * __Required__. A pad definition -* `pin_b` - * __Required__. B pad definition -* `resolution` - * How many pulses the encoder registers between each detent - -Examples: - -```json -{ - "encoder": { - "rotary": [ - { "pin_a": "B5", "pin_b": "A2" } - ] - } -} -``` - -```json -{ - "encoder": { - "rotary": [ - { "pin_a": "B5", "pin_b": "A2", "resolution": 4 } - { "pin_a": "B6", "pin_b": "A3", "resolution": 2 } - ] - } -} -``` - -## Secure - -The following options can be configured: - -|Key |Description | -|------------------|---------------------------------------------------------------------------------| -|`unlock_sequence` | Timeout for the user to perform the configured unlock sequence - `0` to disable | -|`unlock_timeout` | Timeout while unlocked before returning to locked - `0` to disable | -|`idle_timeout` | Array of matrix locations describing a sequential sequence of keypresses | - -Example: - -```json -{ - "secure": { - "unlock_sequence": [ [0,0], [0,1] ], - "unlock_timeout": 5000, - "idle_timeout": 60000 - } -} -``` - -## Bootmagic - -This section configures [Bootmagic Lite](feature_bootmagic.md) support. - -The following options can be configured: - -|Key |Description | -|---------|-----------------------------------------------------------------------------| -|`matrix` | A two item list describing the row and column location for the trigger key. | - -Example: - -```json -{ - "bootmagic": { - "enabled": true, - "matrix": [0, 0] - }, -} -``` diff --git a/docs/reference_keymap_extras.md b/docs/reference_keymap_extras.md deleted file mode 100644 index b70d505f1f2e..000000000000 --- a/docs/reference_keymap_extras.md +++ /dev/null @@ -1,92 +0,0 @@ -# Language-specific Keycodes - -Keyboards are able to support a wide range of languages. However, this support is not actually achieved within the keyboard itself - instead, it sends numerical codes, which the operating system maps to the appropriate characters depending on the user's configured keyboard layout. By default (and per the HID spec), this is the US ANSI layout. For example, when a Swedish person presses the key with the `å` character printed on it, the keyboard is *actually* sending the keycode for `[`. - -Obviously, this can get confusing, so QMK provides language-specific keycode aliases for many keyboard layouts. These won't do much on their own - you still have to set the matching keyboard layout in your OS settings. Think of them more as keycap labels for your keymap. - -Simply `#include` one of the keycode headers below at the top of your `keymap.c`, and assign the keycodes defined in the header in place of the `KC_` prefixed ones. - -## Sendstring Support - -By default, `SEND_STRING()` assumes a US ANSI keyboard layout is set. If you are using a different layout, you can include one of the Sendstring LUT headers below in your `keymap.c` to override the lookup tables used for mapping ASCII characters to keycodes. You do not need to include the corresponding `keymap_*.h` header, as it is implicit when including the Sendstring header. - -An important thing to note here is that `SEND_STRING()` only operates on [ASCII text](https://en.wikipedia.org/wiki/ASCII#Character_set). This means that you cannot pass it a string containing Unicode characters - this unfortunately includes accented characters that may be present in your desired layout. -Many layouts make certain characters, such as Grave or Tilde, available only as [dead keys](https://en.wikipedia.org/wiki/Dead_key), so you must add a space immediately after it in the string you want to send, to prevent it from potentially combining with the next character. -Certain other layouts have no Sendstring header as they do not use a Latin-derived alphabet (for example Greek and Russian), and thus there is no way to input most of the ASCII character set. - -## Header Files - -These headers are located in [`quantum/keymap_extras/`](https://github.com/qmk/qmk_firmware/tree/master/quantum/keymap_extras). - -|Layout |Keycodes Header |Sendstring LUT Header | -|---------------------------------|---------------------------------|------------------------------------| -|Canadian Multilingual (CSA) |`keymap_canadian_multilingual.h` |`sendstring_canadian_multilingual.h`| -|Croatian |`keymap_croatian.h` |`sendstring_croatian.h` | -|Czech |`keymap_czech.h` |`sendstring_czech.h` | -|Danish |`keymap_danish.h` |`sendstring_danish.h` | -|Dutch (Belgium) |`keymap_belgian.h` |`sendstring_belgian.h` | -|English (Ireland) |`keymap_irish.h` | | -|English (UK) |`keymap_uk.h` |`sendstring_uk.h` | -|English (US Extended) |`keymap_us_extended.h` | | -|English (US International) |`keymap_us_international.h` |`sendstring_us_international.h` | -|English (US International, Linux)|`keymap_us_international_linux.h`| | -|Estonian |`keymap_estonian.h` |`sendstring_estonian.h` | -|Finnish |`keymap_finnish.h` |`sendstring_finnish.h` | -|French |`keymap_french.h` |`sendstring_french.h` | -|French (AFNOR) |`keymap_french_afnor.h` |`sendstring_french_afnor.h` | -|French (BÉPO) |`keymap_bepo.h` |`sendstring_bepo.h` | -|French (Belgium) |`keymap_belgian.h` |`sendstring_belgian.h` | -|French (Switzerland) |`keymap_swiss_fr.h` |`sendstring_swiss_fr.h` | -|French (macOS, ISO) |`keymap_french_mac_iso.h` |`sendstring_french_mac_iso.h` | -|German |`keymap_german.h` |`sendstring_german.h` | -|German (Switzerland) |`keymap_swiss_de.h` |`sendstring_swiss_de.h` | -|German (macOS) |`keymap_german_mac_iso.h` |`sendstring_german_mac_iso.h` | -|German (Neo2) |`keymap_neo2.h` | | -|Greek |`keymap_greek.h` | | -|Hebrew |`keymap_hebrew.h` | | -|Hungarian |`keymap_hungarian.h` |`sendstring_hungarian.h` | -|Icelandic |`keymap_icelandic.h` |`sendstring_icelandic.h` | -|Italian |`keymap_italian.h` |`sendstring_italian.h` | -|Italian (macOS, ANSI) |`keymap_italian_mac_ansi.h` |`sendstring_italian_mac_ansi.h` | -|Italian (macOS, ISO) |`keymap_italian_mac_iso.h` |`sendstring_italian_mac_iso.h` | -|Japanese |`keymap_japanese.h` |`sendstring_japanese.h` | -|Korean |`keymap_korean.h` | | -|Latvian |`keymap_latvian.h` |`sendstring_latvian.h` | -|Lithuanian (ĄŽERTY) |`keymap_lithuanian_azerty.h` |`sendstring_lithuanian_azerty.h` | -|Lithuanian (QWERTY) |`keymap_lithuanian_qwerty.h` |`sendstring_lithuanian_qwerty.h` | -|Norwegian |`keymap_norwegian.h` |`sendstring_norwegian.h` | -|Polish |`keymap_polish.h` | | -|Portuguese |`keymap_portuguese.h` |`sendstring_portuguese.h` | -|Portuguese (macOS, ISO) |`keymap_portuguese_mac_iso.h` |`sendstring_portuguese_mac_iso.h` | -|Portuguese (Brazil) |`keymap_brazilian_abnt2.h` |`sendstring_brazilian_abnt2.h` | -|Romanian |`keymap_romanian.h` |`sendstring_romanian.h` | -|Russian |`keymap_russian.h` | | -|Serbian |`keymap_serbian.h` | | -|Serbian (Latin) |`keymap_serbian_latin.h` |`sendstring_serbian_latin.h` | -|Slovak |`keymap_slovak.h` |`sendstring_slovak.h` | -|Slovenian |`keymap_slovenian.h` |`sendstring_slovenian.h` | -|Spanish |`keymap_spanish.h` |`sendstring_spanish.h` | -|Spanish (Dvorak) |`keymap_spanish_dvorak.h` |`sendstring_spanish_dvorak.h` | -|Swedish |`keymap_swedish.h` |`sendstring_swedish.h` | -|Swedish (macOS, ANSI) |`keymap_swedish_mac_ansi.h` | | -|Swedish (macOS, ISO) |`keymap_swedish_mac_iso.h` | | -|Swedish Pro (macOS, ANSI) |`keymap_swedish_pro_mac_ansi.h` | | -|Swedish Pro (macOS, ISO) |`keymap_swedish_pro_mac_iso.h` | | -|Turkish (F) |`keymap_turkish_f.h` |`sendstring_turkish_f.h` | -|Turkish (Q) |`keymap_turkish_q.h` |`sendstring_turkish_q.h` | -|Ukrainian |`keymap_ukrainian.h` | | - -There are also a few which are not quite language-specific, but useful if you are not using a QWERTY layout: - -|Layout |Keycodes Header |Sendstring LUT Header | -|-------------------|----------------------------|--------------------------------| -|Colemak |`keymap_colemak.h` |`sendstring_colemak.h` | -|Dvorak |`keymap_dvorak.h` |`sendstring_dvorak.h` | -|Dvorak (French) |`keymap_dvorak_fr.h` |`sendstring_dvorak_fr.h` | -|Dvorak (Programmer)|`keymap_dvorak_programmer.h`|`sendstring_dvorak_programmer.h`| -|Norman |`keymap_norman.h` |`sendstring_norman.h` | -|Plover |`keymap_plover.h` | | -|Plover (Dvorak) |`keymap_plover_dvorak.h` | | -|Steno |`keymap_steno.h` | | -|Workman |`keymap_workman.h` |`sendstring_workman.h` | -|Workman (ZXCVM) |`keymap_workman_zxcvm.h` |`sendstring_workman_zxcvm.h` | diff --git a/docs/serial_driver.md b/docs/serial_driver.md deleted file mode 100644 index c4b42f38ddd2..000000000000 --- a/docs/serial_driver.md +++ /dev/null @@ -1,383 +0,0 @@ -# 'serial' Driver - -The serial driver powers the [Split Keyboard](feature_split_keyboard.md) feature. Several implementations are available, depending on the platform of your split keyboard. Note that none of the drivers support split keyboards with more than two halves. - -| Driver | AVR | ARM | Connection between halves | -| --------------------------------------- | ------------------ | ------------------ | --------------------------------------------------------------------------------------------- | -| [Bitbang](#bitbang) | :heavy_check_mark: | :heavy_check_mark: | Single wire communication. One wire is used for reception and transmission. | -| [USART Half-duplex](#usart-half-duplex) | | :heavy_check_mark: | Efficient single wire communication. One wire is used for reception and transmission. | -| [USART Full-duplex](#usart-full-duplex) | | :heavy_check_mark: | Efficient two wire communication. Two distinct wires are used for reception and transmission. | - -?> Serial in this context should be read as **sending information one bit at a time**, rather than implementing UART/USART/RS485/RS232 standards. - -
- -## Bitbang - -This is the Default driver, the absence of configuration assumes this driver. It works by [bit banging](https://en.wikipedia.org/wiki/Bit_banging) a GPIO pin using the CPU. It is therefore not as efficient as a dedicated hardware peripheral, which the Half-duplex and Full-duplex drivers use. - -!> On ARM platforms the bitbang driver causes connection issues when using it together with the bitbang WS2812 driver. Choosing alternate drivers for both serial and WS2812 (instead of bitbang) is strongly recommended. - -### Pin configuration - -``` - LEFT RIGHT -+-------+ SERIAL +-------+ -| SSP |-----------------| SSP | -| | VDD | | -| |-----------------| | -| | GND | | -| |-----------------| | -+-------+ +-------+ -``` - -One GPIO pin is needed for the bitbang driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SOFT_SERIAL_PIN` (SSP) in the configuration. A simple TRS or USB cable provides enough conductors for this driver to work. - -### Setup - -To use the bitbang driver follow these steps to activate it. - -1. Change the `SERIAL_DRIVER` to `bitbang` in your keyboards `rules.mk` file: - -```make -SERIAL_DRIVER = bitbang -``` - -2. Configure the GPIO pin of your keyboard via the `config.h` file: - -```c -#define SOFT_SERIAL_PIN D0 // or D1, D2, D3, E6 -``` - -3. On ARM platforms you must turn on ChibiOS `PAL_USE_CALLBACKS` feature: - -* In `halconf.h` add the line `#define PAL_USE_CALLBACKS TRUE`. - -
- -## USART Half-duplex - -Targeting ARM boards based on ChibiOS, where communication is offloaded to a USART hardware device that supports Half-duplex operation. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible. - -### Pin configuration - -``` - LEFT RIGHT -+-------+ | | +-------+ -| | R R | | -| | | SERIAL | | | -| TX |-----------------| TX | -| | VDD | | -| |-----------------| | -| | GND | | -| |-----------------| | -+-------+ +-------+ -``` - -Only one GPIO pin is needed for the Half-duplex driver, as only one wire is used for receiving and transmitting data. This pin is referred to as the `SERIAL_USART_TX_PIN` in the configuration. Take care that the pin you chose can act as the TX pin of the USART peripheral. A simple TRS or USB cable provides enough conductors for this driver to work. As the split connection is configured to work in open-drain mode, an **external pull-up resistor is needed to keep the line high**. Resistor values of 1.5kΩ to 8.2kΩ are known to work. - -### Setup - -To use the Half-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1. - -1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file: - -```make -SERIAL_DRIVER = usart -``` - -2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file: - -```make -SERIAL_DRIVER = vendor -``` - -3. Configure the hardware of your keyboard via the `config.h` file: - -```c -#define SERIAL_USART_TX_PIN B6 // The GPIO pin that is used split communication. -``` - -For STM32 MCUs several GPIO configuration options can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus). - -```c -#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below. -#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 -``` - -4. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem). - -
- -## USART Full-duplex - -Targeting ARM boards based on ChibiOS where communication is offloaded to an USART hardware device. The advantages over bitbanging are fast, accurate timings and reduced CPU usage. Therefore it is advised to choose this driver or the Full-duplex driver whenever possible. Due to its internal design it is slightly more efficient then the Half-duplex driver, but it should be primarily chosen if Half-duplex operation is not supported by the USART peripheral. - -### Pin configuration - -``` - LEFT RIGHT -+-------+ +-------+ -| | SERIAL | | -| TX |-----------------| RX | -| | SERIAL | | -| RX |-----------------| TX | -| | VDD | | -| |-----------------| | -| | GND | | -| |-----------------| | -+-------+ +-------+ -``` - -Two GPIO pins are needed for the Full-duplex driver, as two distinct wires are used for receiving and transmitting data. The pin transmitting data is the `TX` pin and refereed to as the `SERIAL_USART_TX_PIN`, the pin receiving data is the `RX` pin and refereed to as the `SERIAL_USART_RX_PIN` in this configuration. Please note that `TX` pin of the master half has to be connected with the `RX` pin of the slave half and the `RX` pin of the master half has to be connected with the `TX` pin of the slave half! Usually this pin swap has to be done outside of the MCU e.g. with cables or on the PCB. Some MCUs like the STM32F303 used on the Proton-C allow this pin swap directly inside the MCU. A simple TRRS or USB cable provides enough conductors for this driver to work. - -To use this driver the usart peripherals `TX` and `RX` pins must be configured with the correct Alternate-functions. If you are using a Proton-C everything is already setup, same is true for STM32F103 MCUs. For MCUs which are using a modern flexible GPIO configuration you have to specify these by setting `SERIAL_USART_TX_PAL_MODE` and `SERIAL_USART_RX_PAL_MODE`. Refer to the corresponding datasheets of your MCU or find those settings in the section ["Alternate Functions for selected STM32 MCUs"](#alternate-functions-for-selected-stm32-mcus). - -### Setup - -To use the Full-duplex driver follow these steps to activate it. If you target the Raspberry Pi RP2040 PIO implementation skip step 1. - -1. Change the `SERIAL_DRIVER` to `usart` in your keyboards `rules.mk` file: - -```make -SERIAL_DRIVER = usart -``` - -2. (RP2040 PIO only!) Change the `SERIAL_DRIVER` to `vendor` in your keyboards `rules.mk` file: - -```make -SERIAL_DRIVER = vendor -``` - -3. Configure the hardware of your keyboard via the `config.h` file: - -```c -#define SERIAL_USART_FULL_DUPLEX // Enable full duplex operation mode. -#define SERIAL_USART_TX_PIN B6 // USART TX pin -#define SERIAL_USART_RX_PIN B7 // USART RX pin -``` - -For STM32 MCUs several GPIO configuration options, including the ability for `TX` to `RX` pin swapping, can be changed as well. See the section ["Alternate Functions for selected STM32 MCUs"](alternate-functions-for-selected-stm32-mcus). - -```c -#define SERIAL_USART_PIN_SWAP // Swap TX and RX pins if keyboard is master halve. (Only available on some MCUs) -#define USART1_REMAP // Remap USART TX and RX pins on STM32F103 MCUs, see table below. -#define SERIAL_USART_TX_PAL_MODE 7 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 7 -``` - -1. Decide either for `SERIAL`, `SIO` or `PIO` subsystem, see the section ["Choosing a driver subsystem"](#choosing-a-driver-subsystem). - -
- -## Choosing a driver subsystem - -### The `SERIAL` driver - -The `SERIAL` Subsystem is supported for the majority of ChibiOS MCUs and should be used whenever supported. Follow these steps in order to activate it: - -1. In your keyboards `halconf.h` add: - -```c -#define HAL_USE_SERIAL TRUE -``` - -2. In your keyboards `mcuconf.h`: activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS. - -Just below `#include_next ` add: - -```c -#include_next - -#undef STM32_SERIAL_USE_USARTn -#define STM32_SERIAL_USE_USARTn TRUE -``` - -Where 'n' matches the peripheral number of your selected USART on the MCU. - -3. In you keyboards `config.h`: override the default USART `SERIAL` driver if you use a USART peripheral that does not belong to the default selected `SD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SD3`. - -```c - #define SERIAL_USART_DRIVER SD3 - ``` - -### The `SIO` driver - -The `SIO` Subsystem was added to ChibiOS with the 21.11 release and is only supported on selected MCUs. It should only be chosen when the `SERIAL` subsystem is not supported by your MCU. - -Follow these steps in order to activate it: - -1. In your keyboards `halconf.h` add: - -```c -#define HAL_USE_SIO TRUE -``` - -2. In your keyboards `mcuconf.h:` activate the USART peripheral that is used on your MCU. The shown example is for an STM32 MCU, so this will not work on MCUs by other manufacturers. You can find the correct names in the `mcuconf.h` files of your MCU that ship with ChibiOS. - -Just below `#include_next ` add: - -```c -#include_next - -#undef STM32_SIO_USE_USARTn -#define STM32_SIO_USE_USARTn TRUE -``` - -Where 'n' matches the peripheral number of your selected USART on the MCU. - -3. In you keyboards `config.h`: override the default USART `SIO` driver if you use a USART peripheral that does not belong to the default selected `SIOD1` driver. For instance, if you selected `STM32_SERIAL_USE_USART3` the matching driver would be `SIOD3`. - -```c - #define SERIAL_USART_DRIVER SIOD3 - ``` - -### The `PIO` driver - -The `PIO` subsystem is a Raspberry Pi RP2040 specific implementation, using the integrated PIO peripheral and is therefore only available on this MCU. Because of the flexible nature of the PIO peripherals, **any** GPIO pin can be used as a `TX` or `RX` pin. Half-duplex and Full-duplex operation is fully supported. The Half-duplex operation mode uses the built-in pull-ups and GPIO manipulation on the RP2040 to drive the line high by default. An external pull-up is therefore not necessary. - -Configure the hardware via your config.h: -```c -#define SERIAL_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the Serial implementation uses the PIO0 peripheral -``` - -The Serial PIO program uses 2 state machines, 13 instructions and the complete interrupt handler of the PIO peripheral it is running on. - -
- -## Advanced Configuration - -There are several advanced configuration options that can be defined in your keyboards `config.h` file: - -### Baudrate - -If you're having issues or need a higher baudrate with serial communication, you can change the baudrate which in turn controls the communication speed for serial. You want to lower the baudrate if you experience failed transactions. - -```c -#define SELECT_SOFT_SERIAL_SPEED {#} -``` - -| Speed | Bitbang | Half-duplex and Full-duplex | -| ----- | -------------------------- | --------------------------- | -| `0` | 189000 baud (experimental) | 460800 baud | -| `1` | 137000 baud (default) | 230400 baud (default) | -| `2` | 75000 baud | 115200 baud | -| `3` | 39000 baud | 57600 baud | -| `4` | 26000 baud | 38400 baud | -| `5` | 20000 baud | 19200 baud | - -Alternatively you can specify the baudrate directly by defining `SERIAL_USART_SPEED`. - -### Timeout - -This is the default time window in milliseconds in which a successful communication has to complete. Usually you don't want to change this value. But you can do so anyways by defining an alternate one in your keyboards `config.h` file: - -```c -#define SERIAL_USART_TIMEOUT 20 // USART driver timeout. default 20 -``` - -
- -## Troubleshooting - -If you're having issues withe serial communication, you can enable debug messages that will give you insights which part of the communication failed. The enable these messages add to your keyboards `config.h` file: - -```c -#define SERIAL_DEBUG -``` - -?> The messages will be printed out to the `CONSOLE` output. For additional information, refer to [Debugging/Troubleshooting QMK](faq_debug.md). - -## Alternate Functions for selected STM32 MCUs - -Pins for USART Peripherals with - -### STM32F303 / Proton-C [Datasheet](https://www.st.com/resource/en/datasheet/stm32f303cc.pdf) - -Pin Swap available: :heavy_check_mark: - -| Pin | Function | Mode | -| ---------- | -------- | ---- | -| **USART1** | | | -| PA9 | TX | AF7 | -| PA10 | RX | AF7 | -| PB6 | TX | AF7 | -| PB7 | RX | AF7 | -| PC4 | TX | AF7 | -| PC5 | RX | AF7 | -| PE0 | TX | AF7 | -| PE1 | RX | AF7 | -| **USART2** | | | -| PA2 | TX | AF7 | -| PA3 | RX | AF7 | -| PA14 | TX | AF7 | -| PA15 | RX | AF7 | -| PB3 | TX | AF7 | -| PB4 | RX | AF7 | -| PD5 | TX | AF7 | -| PD6 | RX | AF7 | -| **USART3** | | | -| PB10 | TX | AF7 | -| PB11 | RX | AF7 | -| PC10 | TX | AF7 | -| PC11 | RX | AF7 | -| PD8 | TX | AF7 | -| PD9 | RX | AF7 | - -### STM32F072 [Datasheet](https://www.st.com/resource/en/datasheet/stm32f072c8.pdf) - -Pin Swap available: :heavy_check_mark: - -| Pin | Function | Mode | -| ------ | -------- | ---- | -| USART1 | | | -| PA9 | TX | AF1 | -| PA10 | RX | AF1 | -| PB6 | TX | AF0 | -| PB7 | RX | AF0 | -| USART2 | | | -| PA2 | TX | AF1 | -| PA3 | RX | AF1 | -| PA14 | TX | AF1 | -| PA15 | RX | AF1 | -| USART3 | | | -| PB10 | TX | AF4 | -| PB11 | RX | AF4 | -| PC4 | TX | AF1 | -| PC5 | RX | AF1 | -| PC10 | TX | AF1 | -| PC11 | RX | AF1 | -| PD8 | TX | AF0 | -| PD9 | RX | AF0 | -| USART4 | | | -| PA0 | TX | AF4 | -| PA1 | RX | AF4 | - -### STM32F103 Medium Density (C8-CB) [Datasheet](https://www.st.com/resource/en/datasheet/stm32f103c8.pdf) - -Pin Swap available: N/A - -TX Pin is always Alternate Function Push-Pull, RX Pin is always regular input pin for any USART peripheral. **For STM32F103 no additional Alternate Function configuration is necessary. QMK is already configured.** - -Pin remapping: - -The pins of USART Peripherals use default Pins that can be remapped to use other pins using the AFIO registers. Default pins are marked **bold**. Add the appropriate defines to your config.h file. - -| Pin | Function | Mode | USART_REMAP | -| ---------- | -------- | ---- | ------------------- | -| **USART1** | | | | -| **PA9** | TX | AFPP | | -| **PA10** | RX | IN | | -| PB6 | TX | AFPP | USART1_REMAP | -| PB7 | RX | IN | USART1_REMAP | -| **USART2** | | | | -| **PA2** | TX | AFPP | | -| **PA3** | RX | IN | | -| PD5 | TX | AFPP | USART2_REMAP | -| PD6 | RX | IN | USART2_REMAP | -| **USART3** | | | | -| **PB10** | TX | AFPP | | -| **PB11** | RX | IN | | -| PC10 | TX | AFPP | USART3_PARTIALREMAP | -| PC11 | RX | IN | USART3_PARTIALREMAP | -| PD8 | TX | AFPP | USART3_FULLREMAP | -| PD9 | RX | IN | USART3_FULLREMAP | diff --git a/docs/spi_driver.md b/docs/spi_driver.md deleted file mode 100644 index a27a3a13d084..000000000000 --- a/docs/spi_driver.md +++ /dev/null @@ -1,150 +0,0 @@ -# SPI Master Driver - -The SPI Master drivers used in QMK have a set of common functions to allow portability between MCUs. - -## AVR Configuration - -No special setup is required - just connect the `SS`, `SCK`, `MOSI` and `MISO` pins of your SPI devices to the matching pins on the MCU: - -|MCU |`SS`|`SCK`|`MOSI`|`MISO`| -|-----------------|----|-----|------|------| -|ATmega16/32U2/4 |`B0`|`B1` |`B2` |`B3` | -|AT90USB64/128/162|`B0`|`B1` |`B2` |`B3` | -|ATmega32A |`B4`|`B7` |`B5` |`B6` | -|ATmega328/P |`B2`|`B5` |`B3` |`B4` | - -You may use more than one slave select pin, not just the `SS` pin. This is useful when you have multiple devices connected and need to communicate with them individually. -`SPI_SS_PIN` can be passed to `spi_start()` to refer to `SS`. - -## ChibiOS/ARM Configuration - -You'll need to determine which pins can be used for SPI -- as an example, STM32 parts generally have multiple SPI peripherals, labeled SPI1, SPI2, SPI3 etc. - -To enable SPI, modify your board's `halconf.h` to enable SPI: - -```c -#define HAL_USE_SPI TRUE -#define SPI_USE_WAIT TRUE -#define SPI_SELECT_MODE SPI_SELECT_MODE_PAD -``` - -Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: - -```c -#undef STM32_SPI_USE_SPI2 -#define STM32_SPI_USE_SPI2 TRUE -``` - -Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. - -|`config.h` Override|Description |Default| -|-------------------|-------------------------------------------------------------|-------| -|`SPI_DRIVER` |SPI peripheral to use - SPI1 -> `SPID1`, SPI2 -> `SPID2` etc.|`SPID2`| -|`SPI_SCK_PIN` |The pin to use for SCK |`B13` | -|`SPI_SCK_PAL_MODE` |The alternate function mode for SCK |`5` | -|`SPI_MOSI_PIN` |The pin to use for MOSI |`B15` | -|`SPI_MOSI_PAL_MODE`|The alternate function mode for MOSI |`5` | -|`SPI_MISO_PIN` |The pin to use for MISO |`B14` | -|`SPI_MISO_PAL_MODE`|The alternate function mode for MISO |`5` | - -As per the AVR configuration, you may choose any other standard GPIO as a slave select pin, which should be supplied to `spi_start()`. - -## Functions - -### `void spi_init(void)` - -Initialize the SPI driver. This function must be called only once, before any of the below functions can be called. - ---- - -### `bool spi_start(pin_t slavePin, bool lsbFirst, uint8_t mode, uint16_t divisor)` - -Start an SPI transaction. - -#### Arguments - - - `pin_t slavePin` - The QMK pin to assert as the slave select pin, eg. `B4`. - - `bool lsbFirst` - Determines the endianness of the transmission. If `true`, the least significant bit of each byte is sent first. - - `uint8_t mode` - The SPI mode to use: - - |Mode|Clock Polarity |Clock Phase | - |----|--------------------|-----------------------| - |`0` |Leading edge rising |Sample on leading edge | - |`1` |Leading edge rising |Sample on trailing edge| - |`2` |Leading edge falling|Sample on leading edge | - |`3` |Leading edge falling|Sample on trailing edge| - - - `uint16_t divisor` - The SPI clock divisor, will be rounded up to the nearest power of two. This number can be calculated by dividing the MCU's clock speed by the desired SPI clock speed. For example, an MCU running at 8 MHz wanting to talk to an SPI device at 4 MHz would set the divisor to `2`. - -#### Return Value - -`false` if the supplied parameters are invalid or the SPI peripheral is already in use, or `true`. - ---- - -### `spi_status_t spi_write(uint8_t data)` - -Write a byte to the selected SPI device. - -#### Arguments - - - `uint8_t data` - The byte to write. - -#### Return Value - -`SPI_STATUS_TIMEOUT` if the timeout period elapses, or `SPI_STATUS_SUCCESS`. - ---- - -### `spi_status_t spi_read(void)` - -Read a byte from the selected SPI device. - -#### Return Value - -`SPI_STATUS_TIMEOUT` if the timeout period elapses, or the byte read from the device. - ---- - -### `spi_status_t spi_transmit(const uint8_t *data, uint16_t length)` - -Send multiple bytes to the selected SPI device. - -#### Arguments - - - `const uint8_t *data` - A pointer to the data to write from. - - `uint16_t length` - The number of bytes to write. Take care not to overrun the length of `data`. - -#### Return Value - -`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`. - ---- - -### `spi_status_t spi_receive(uint8_t *data, uint16_t length)` - -Receive multiple bytes from the selected SPI device. - -#### Arguments - - - `uint8_t *data` - A pointer to the buffer to read into. - - `uint16_t length` - The number of bytes to read. Take care not to overrun the length of `data`. - -#### Return Value - -`SPI_STATUS_TIMEOUT` if the timeout period elapses, `SPI_STATUS_ERROR` if some other error occurs, otherwise `SPI_STATUS_SUCCESS`. - ---- - -### `void spi_stop(void)` - -End the current SPI transaction. This will deassert the slave select pin and reset the endianness, mode and divisor configured by `spi_start()`. diff --git a/docs/squeezing_avr.md b/docs/squeezing_avr.md deleted file mode 100644 index ce9e43cdaea1..000000000000 --- a/docs/squeezing_avr.md +++ /dev/null @@ -1,201 +0,0 @@ -# Squeezing the most out of AVR - -AVR is severely resource-constrained, and as QMK continues to grow, it is approaching a point where support for AVR may need to be moved to legacy status as newer development is unable to fit into those constraints. - -However, if you need to reduce the compiled size of your firmware, there are a number of options to do so. - -## `rules.mk` Settings -First and foremost is enabling link time optimization. To do so, add this to your rules.mk: -```make -LTO_ENABLE = yes -``` -This will cause the final step to take longer, but should get you a smaller compiled size. This also disables Action Functions, and Action Macros, both of which are deprecated. -This will get you the most savings, in most situations. - -From there, disabling extraneous systems will help -- e.g.: -```make -CONSOLE_ENABLE = no -COMMAND_ENABLE = no -MOUSEKEY_ENABLE = no -EXTRAKEY_ENABLE = no -``` -This disables some of the functionality that you may not need. But note that extrakeys disables stuff like the media keys and system volume control. - -If that isn't enough to get your firmware down to size, then there are some additional features that you can disable: -```make -SPACE_CADET_ENABLE = no -GRAVE_ESC_ENABLE = no -MAGIC_ENABLE = no -``` -These features are enabled by default, but may not be needed. Double check to make sure, though. -Largest in size is "magic" -- the QMK magic keycodes -- which control things like NKRO toggling, GUI and ALT/CTRL swapping, etc. Disabling it will disable those functions. - -If you use `sprintf` or `snprintf` functions you can save around ~400 Bytes by enabling this option. -```make -AVR_USE_MINIMAL_PRINTF = yes -``` - -This will include smaller implementations from AVRs libc into your Firmware. They are [not fully featured](https://www.nongnu.org/avr-libc/user-manual/group__avr__stdio.html#gaa3b98c0d17b35642c0f3e4649092b9f1), for instance zero padding and field width specifiers are not supported. So if you use `sprintf` or `snprintf` like this: -```c -sprintf(wpm_str, "%03d", get_current_wpm()); -snprintf(keylog_str, sizeof(keylog_str), "%dx%d, k%2d : %c"); -``` - -you will still need the standard implementation. - -## `config.h` Settings - -If you've done all of that, and you don't want to disable features like RGB, Audio, OLEDs, etc, there are some additional options that you can add to your config.h that can help. - -Starting with Lock Key support. If you have a Cherry MX Lock switch (lucky you!), you don't want to do this. But chances are, you don't. In that case, add this to your `config.h`: -```c -#undef LOCKING_SUPPORT_ENABLE -#undef LOCKING_RESYNC_ENABLE -``` -Oneshots. If you're not using these, you can disable the feature by adding this to your `config.h`: -```c -#define NO_ACTION_ONESHOT -``` -The same with tapping keys (mod tap, layer tap, etc) -```c -#define NO_ACTION_TAPPING -``` -## Audio Settings - -If you're using the Audio feature, by default that includes the music mode feature. This tranlates matrix positions into notes. It's neat for sure, but most likely, you're not using it. You can disable it by adding this to your `config.h`: -```c -#define NO_MUSIC_MODE -``` -And by adding this to your `rules.mk` -```make -MUSIC_ENABLE = no -``` - -## Layers - -There are also some options for layers, that can reduce the firmware size. All of these settings are for your `config.h`. - -You can limit the number of layers that the firmware uses -- if you're using less than 8 layers in total: -```c -#define LAYER_STATE_8BIT -``` -or if you require up to 16 layers instead: -```c -#define LAYER_STATE_16BIT -``` -Or if you're not using layers at all, you can outright remove the functionality altogether: -```c -#define NO_ACTION_LAYER -``` - - -## OLED tweaks - -One place you can save a bunch of space here is by not using `sprintf` or `snprintf`. This function call takes up ~1.5kB of firmware space, and can be rewritten. For instance, WPM uses this a lot. - -You can convert this: -```c - // OLD CODE - char wpm_str[4] = {0}; - sprintf(wpm_str, "WPM: %03d", get_current_wpm()); - oled_write(wpm_str, ' '), false); -``` -into this: -```c - // NEW CODE - oled_write_P(PSTR("WPM: "), false); - oled_write(get_u8_str(get_current_wpm(), ' '), false); -``` -which outputs `WPM: 5`. Or this: -```c - // NEW CODE - oled_write_P(PSTR("WPM: "), false); - oled_write(get_u8_str(get_current_wpm(), '0'), false); -``` -which outputs `WPM: 005`. - -## RGB Settings - -If you're using RGB on your board, both RGB Light (Underglow) and RGB Matrix (per key RGB) now require defines to enable different animations -- some keyboards enable a lot of animations by default, so you can generally gain back some space by disabling specific animations if you don't use them. For RGB Light you can disable these in your keymap's `config.h`: -```c -#undef RGBLIGHT_ANIMATIONS -#undef RGBLIGHT_EFFECT_BREATHING -#undef RGBLIGHT_EFFECT_RAINBOW_MOOD -#undef RGBLIGHT_EFFECT_RAINBOW_SWIRL -#undef RGBLIGHT_EFFECT_SNAKE -#undef RGBLIGHT_EFFECT_KNIGHT -#undef RGBLIGHT_EFFECT_CHRISTMAS -#undef RGBLIGHT_EFFECT_STATIC_GRADIENT -#undef RGBLIGHT_EFFECT_RGB_TEST -#undef RGBLIGHT_EFFECT_ALTERNATING -#undef RGBLIGHT_EFFECT_TWINKLE -``` - -For RGB Matrix, these need to be explicitly enabled as well. To disable any that were enabled by the keyboard, add one or more of these to your keymap's `config.h`: -```c -#undef ENABLE_RGB_MATRIX_ALPHAS_MODS -#undef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN -#undef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT -#undef ENABLE_RGB_MATRIX_BREATHING -#undef ENABLE_RGB_MATRIX_BAND_SAT -#undef ENABLE_RGB_MATRIX_BAND_VAL -#undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT -#undef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL -#undef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT -#undef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL -#undef ENABLE_RGB_MATRIX_CYCLE_ALL -#undef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT -#undef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN -#undef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON -#undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN -#undef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL -#undef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL -#undef ENABLE_RGB_MATRIX_CYCLE_SPIRAL -#undef ENABLE_RGB_MATRIX_DUAL_BEACON -#undef ENABLE_RGB_MATRIX_RAINBOW_BEACON -#undef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS -#undef ENABLE_RGB_MATRIX_RAINDROPS -#undef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS -#undef ENABLE_RGB_MATRIX_HUE_BREATHING -#undef ENABLE_RGB_MATRIX_HUE_PENDULUM -#undef ENABLE_RGB_MATRIX_HUE_WAVE -#undef ENABLE_RGB_MATRIX_PIXEL_FRACTAL -#undef ENABLE_RGB_MATRIX_PIXEL_FLOW -#undef ENABLE_RGB_MATRIX_PIXEL_RAIN - -#undef ENABLE_RGB_MATRIX_TYPING_HEATMAP -#undef ENABLE_RGB_MATRIX_DIGITAL_RAIN - -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS -#undef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS -#undef ENABLE_RGB_MATRIX_SPLASH -#undef ENABLE_RGB_MATRIX_MULTISPLASH -#undef ENABLE_RGB_MATRIX_SOLID_SPLASH -#undef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH -``` - -# Final Thoughts - -If you've done all of this, and your firmware is still too large, then it's time. It's time to consider making the switch to ARM. Unfortunately, right now is the worst possible time for that, due to the silicon shortage, and supply chain issues. Getting an ARM chip is difficult, at best, and significantly overpriced, at worst. - -- Drashna - -That said, there are a number of Pro Micro replacements with ARM controllers: -* [Proton C](https://qmk.fm/proton-c/) (out of stock) -* [Bonsai C](https://github.com/customMK/Bonsai-C) (Open Source, DIY/PCBA) -* [STeMCell](https://github.com/megamind4089/STeMCell) (Open Source, DIY/PCBA) -* [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040) -* [SparkFun Pro Micro - RP2040](https://www.sparkfun.com/products/18288) -* [Blok](https://boardsource.xyz/store/628b95b494dfa308a6581622) -* [Elite-Pi](https://keeb.io/products/elite-pi-usb-c-pro-micro-replacement-rp2040) -* [0xCB Helios](https://keeb.supply/products/0xcb-helios) ([Open Source](https://github.com/0xCB-dev/0xCB-Helios), DIY/PCBA/Shop) -* [Liatris](https://splitkb.com/products/liatris) -* [Michi](https://github.com/ci-bus/michi-promicro-rp2040) - -There are other, non-Pro Micro compatible boards out there. The most popular being: -* [WeAct Blackpill F411](https://www.aliexpress.com/item/1005001456186625.html) (~$6 USD) diff --git a/docs/support.md b/docs/support.md deleted file mode 100644 index 938d9daf7849..000000000000 --- a/docs/support.md +++ /dev/null @@ -1,17 +0,0 @@ -# Getting Help - -There are a lot of resources for getting help with QMK. - -Please read our [Code of Conduct](https://qmk.fm/coc/) before participating in any of our community spaces. - -## Realtime Chat - -If you need help with something, the best place to get quick support is going to be on our [Discord Server](https://discord.gg/Uq7gcHh). There is usually somebody online, and there are a bunch of very helpful people there. - -## OLKB Subreddit - -The official QMK forum is [/r/olkb](https://reddit.com/r/olkb) on [reddit.com](https://reddit.com). - -## GitHub Issues - -You can open an [issue on GitHub](https://github.com/qmk/qmk_firmware/issues). This is especially handy when your issue will require long-term discussion or debugging. diff --git a/docs/support_deprecation_policy.md b/docs/support_deprecation_policy.md deleted file mode 100644 index f7107dfc89c2..000000000000 --- a/docs/support_deprecation_policy.md +++ /dev/null @@ -1,44 +0,0 @@ -# Feature support policies - -## System Constraints - -In general, feature development is encouraged to support as many hardware configurations as possible. Depending on system constraints this may not always be achievable, and is usually bound by microcontroller flash and RAM capabilities. - -The most frequently-hit constraint is the amount of code that can be flashed onto an ATmega32U4 -- users almost always need to pick and choose included functionality due to the size constraints. - -!> [Squeezing AVR](https://docs.qmk.fm/#/squeezing_avr) has some steps that users can take in order to minimise the overall firmware size, which in some cases enables the ability for users to include other desired features. - -## Deprecation & Removal Policy - -QMK Firmware strives for innovation wherever possible. With ongoing feature development and other improvements made to the codebase, sometimes the retirement of outdated, under-utilised, or limited-value functionality is selected for deprecation and subsequent removal. - -The intent behind feature deprecation is to maintain and/or improve quality. As a result, perpetually supporting under-utilised features would negatively impact the QMK team's ability to improve other areas of QMK Firmware. - -There may be several motivations behind the deprecation or removal of functionality (keeping in mind that this list is not exhaustive): - -* Better alternatives have already been implemented -* Lack of adherence to standards -* Poor support from code owners or upstream maintainers -* Poor design -* Hardware constraints -* Minimal use within the QMK Firmware repository -* Copyright disputes -* Bit-rot - -When a feature is selected for deprecation, future changes to that area will cease to be developed by the QMK team, and Pull Requests submitted against those areas will be declined. - -?> As QMK does not gather metrics from its users, the only way the QMK team can gauge the level of usage is to refer to the main QMK Firmware repository -- searching through forks is not practical due to the sheer number of them. - -### How much advance notice will be given? - -Disregarding emergencies or other high-risk concerns, deprecation of large features or entire subsystems within QMK will be communicated on the `develop` branch at least one breaking changes cycle (3 months) before removal. Advance notice may be extended for higher impact features, and is at the discretion of the QMK team. - -Smaller features may be removed within a breaking changes cycle, and will generally be based on the level of use within the repository. Features with minimal use may be selected for removal at any time on the `develop` branch. - -Third-party software libraries leveraged by QMK are generally forked to mitigate disappearance upstream. If the upstream repository is removed, it will generally be replaced when practical, or dependent features will be removed as per the normal deprecation policy. - -### How will deprecation be communicated? - -Every breaking changes merge from `develop` into `master` is accompanied by a changelog document -- intended and completed deprecations will be communicated here. - -In addition, wherever possible warnings will be issued during firmware compilation when deprecated features are still being used. diff --git a/docs/sw.js b/docs/sw.js deleted file mode 100644 index 1e4aaeb76213..000000000000 --- a/docs/sw.js +++ /dev/null @@ -1,83 +0,0 @@ -/* =========================================================== - * docsify sw.js - * =========================================================== - * Copyright 2016 @huxpro - * Licensed under Apache 2.0 - * Register service worker. - * ========================================================== */ - -const RUNTIME = 'docsify' -const HOSTNAME_WHITELIST = [ - self.location.hostname, - 'fonts.gstatic.com', - 'fonts.googleapis.com', - 'unpkg.com' -] - -// The Util Function to hack URLs of intercepted requests -const getFixedUrl = (req) => { - var now = Date.now() - var url = new URL(req.url) - - // 1. fixed http URL - // Just keep syncing with location.protocol - // fetch(httpURL) belongs to active mixed content. - // And fetch(httpRequest) is not supported yet. - url.protocol = self.location.protocol - - // 2. add query for caching-busting. - // Github Pages served with Cache-Control: max-age=600 - // max-age on mutable content is error-prone, with SW life of bugs can even extend. - // Until cache mode of Fetch API landed, we have to workaround cache-busting with query string. - // Cache-Control-Bug: https://bugs.chromium.org/p/chromium/issues/detail?id=453190 - if (url.hostname === self.location.hostname) { - url.search += (url.search ? '&' : '?') + 'cache-bust=' + now - } - return url.href -} - -/** - * @Lifecycle Activate - * New one activated when old isnt being used. - * - * waitUntil(): activating ====> activated - */ -self.addEventListener('activate', event => { - event.waitUntil(self.clients.claim()) -}) - -/** - * @Functional Fetch - * All network requests are being intercepted here. - * - * void respondWith(Promise r) - */ -self.addEventListener('fetch', event => { - // Skip some of cross-origin requests, like those for Google Analytics. - if (HOSTNAME_WHITELIST.indexOf(new URL(event.request.url).hostname) > -1) { - // Stale-while-revalidate - // similar to HTTP's stale-while-revalidate: https://www.mnot.net/blog/2007/12/12/stale - // Upgrade from Jake's to Surma's: https://gist.github.com/surma/eb441223daaedf880801ad80006389f1 - const cached = caches.match(event.request) - const fixedUrl = getFixedUrl(event.request) - const fetched = fetch(fixedUrl, { cache: 'no-store' }) - const fetchedCopy = fetched.then(resp => resp.clone()) - - // Call respondWith() with whatever we get first. - // If the fetch fails (e.g disconnected), wait for the cache. - // If there’s nothing in cache, wait for the fetch. - // If neither yields a response, return offline pages. - event.respondWith( - Promise.race([fetched.catch(_ => cached), cached]) - .then(resp => resp || fetched) - .catch(_ => { /* eat any errors */ }) - ) - - // Update the cache with the version we fetched (only for ok status) - event.waitUntil( - Promise.all([fetchedCopy, caches.open(RUNTIME)]) - .then(([response, cache]) => response.ok && cache.put(event.request, response)) - .catch(_ => { /* eat any errors */ }) - ) - } -}) diff --git a/docs/syllabus.md b/docs/syllabus.md deleted file mode 100644 index f5cdea21820e..000000000000 --- a/docs/syllabus.md +++ /dev/null @@ -1,72 +0,0 @@ -# QMK Syllabus - -This page helps you build up your QMK knowledge by introducing the basics first and guiding you to understanding all the concepts you need to know to be proficient with QMK. - -# Beginning Topics - -If you read nothing else you should read the documents in this section. After reading the [Tutorial](newbs.md) you should be able to create a basic keymap, compile it, and flash it to your keyboard. The remaining documents will flesh out your knowledge of these basics. - -* **Learn How To Use QMK Tools** - * [Tutorial](newbs.md) - * [CLI](cli.md) - * [GIT](newbs_git_best_practices.md) -* **Learn About Keymaps** - * [Layers](feature_layers.md) - * [Keycodes](keycodes.md) - * The full list of keycodes you can use. Note that some may require knowledge found in the Intermediate or Advanced Topics. -* **Configuring IDEs** - Optional - * [Eclipse](other_eclipse.md) - * [VS Code](other_vscode.md) - -# Intermediate Topics - -These topics start to dig into some of the features that QMK supports. You don't have to read all of these documents, but some of the documents in the Advanced Topics section won't make sense if you skip over some of these. - -* **Learn How To Configure Features** - - * [Audio](feature_audio.md) - * Lighting - * [Backlight](feature_backlight.md) - * [LED Matrix](feature_led_matrix.md) - * [RGB Lighting](feature_rgblight.md) - * [RGB Matrix](feature_rgb_matrix.md) - * [Tap-Hold Configuration](tap_hold.md) - * [Squeezing Space from AVR](squeezing_avr.md) -* **Learn More About Keymaps** - * [Keymaps](keymap.md) - * [Custom Functions and Keycodes](custom_quantum_functions.md) - * Macros - * [Dynamic Macros](feature_dynamic_macros.md) - * [Compiled Macros](feature_macros.md) - * [Tap Dance](feature_tap_dance.md) - * [Combos](feature_combo.md) - * [Userspace](feature_userspace.md) - * [Key Overrides](feature_key_overrides.md) - -# Advanced Topics - -Everything below here requires a lot of foundational knowledge. Besides being able to create keymaps using advanced features you should be familiar with using both `config.h` and `rules.mk` to configure options for your keyboard. - -* **Maintaining Keyboards Within QMK** - * [Handwiring a Keyboard](hand_wire.md) - * [Keyboard Guidelines](hardware_keyboard_guidelines.md) - * [info.json Reference](reference_info_json.md) - * [Debounce API](feature_debounce_type.md) -* **Advanced Features** - * [Unicode](feature_unicode.md) - * [API](api_overview.md) - * [Bootmagic Lite](feature_bootmagic.md) -* **Hardware** - * [How Keyboards Work](how_keyboards_work.md) - * [How A Keyboard Matrix Works](how_a_matrix_works.md) - * [Split Keyboards](feature_split_keyboard.md) - * [Stenography](feature_stenography.md) - * [Pointing Devices](feature_pointing_device.md) -* **Core Development** - * [Coding Conventions](coding_conventions_c.md) - * [Compatible Microcontrollers](compatible_microcontrollers.md) - * [Custom Matrix](custom_matrix.md) - * [Understanding QMK](understanding_qmk.md) -* **CLI Development** - * [Coding Conventions](coding_conventions_python.md) - * [CLI Development Overview](cli_development.md) diff --git a/docs/tap_hold.md b/docs/tap_hold.md deleted file mode 100644 index c50acdb84d86..000000000000 --- a/docs/tap_hold.md +++ /dev/null @@ -1,475 +0,0 @@ -# Tap-Hold Configuration Options - -While Tap-Hold options are fantastic, they are not without their issues. We have tried to configure them with reasonable defaults, but that may still cause issues for some people. - -These options let you modify the behavior of the Tap-Hold keys. - -## Tapping Term - -The crux of all of the following features is the tapping term setting. This determines what is a tap and what is a hold. The exact timing for this to feel natural can vary from keyboard to keyboard, from switch to switch, and from key to key. - -?> `DYNAMIC_TAPPING_TERM_ENABLE` enables three special keys that can help you quickly find a comfortable tapping term for you. See "Dynamic Tapping Term" for more details. - -You can set the global time for this by adding the following setting to your `config.h`: - -```c -#define TAPPING_TERM 200 -``` - -This setting is defined in milliseconds and defaults to 200ms. This is a good average for the majority of people. - -For more granular control of this feature, you can add the following to your `config.h`: -```c -#define TAPPING_TERM_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return TAPPING_TERM + 1250; - case LT(1, KC_GRV): - return 130; - default: - return TAPPING_TERM; - } -} -``` - -### Dynamic Tapping Term :id=dynamic-tapping-term - -`DYNAMIC_TAPPING_TERM_ENABLE` is a feature you can enable in `rules.mk` that lets you use three special keys in your keymap to configure the tapping term on the fly. - -| Key | Aliases | Description | -|-------------------------------|---------|-------------------------------------------------------------------------------------------| -|`QK_DYNAMIC_TAPPING_TERM_PRINT`|`DT_PRNT`| Types the current tapping term, in milliseconds | -|`QK_DYNAMIC_TAPPING_TERM_UP` |`DT_UP` | Increases the current tapping term by `DYNAMIC_TAPPING_TERM_INCREMENT`ms (5ms by default) | -|`QK_DYNAMIC_TAPPING_TERM_DOWN` |`DT_DOWN`| Decreases the current tapping term by `DYNAMIC_TAPPING_TERM_INCREMENT`ms (5ms by default) | - -Set the tapping term as usual with `#define TAPPING_TERM ` in `config.h` and add `DYNAMIC_TAPPING_TERM_ENABLE = yes` in `rules.mk`. Then, place the above three keys somewhere in your keymap and flash the new firmware onto your board. - -Now, you can try using your dual-role keys, such as layer-taps and mod-taps, and use `DT_DOWN` and `DT_UP` to adjust the tapping term immediately. If you find that you frequently trigger the modifier of your mod-tap(s) by accident, for example, that's a sign that your tapping term may be too low so tap `DT_UP` a few times to increase the tapping term until that no longer happens. On the flip side, if you get superfluous characters when you actually intended to momentarily activate a layer, tap `DT_DOWN` to lower the tapping term. Do note that these keys affect the *global* tapping term, you cannot change the tapping term of a specific key on the fly. - -Once you're satisfied with the current tapping term value, open `config.h` and replace whatever value you first wrote for the tapping term by the output of the `DT_PRNT` key. - -It's important to update `TAPPING_TERM` with the new value because the adjustments made using `DT_UP` and `DT_DOWN` are not persistent. - -The value by which the tapping term increases or decreases when you tap `DT_UP` and `DT_DOWN` can be configured in `config.h` with `#define DYNAMIC_TAPPING_TERM_INCREMENT `. Note that the tapping term is *not* modified when holding down the tap term keys so if you need to, for example, decrease the current tapping term by 50ms, you cannot just press down and hold `DT_DOWN`; you will have to tap it 10 times in a row with the default increment of 5ms. - -If you need more flexibility, nothing prevents you from defining your own custom keys to dynamically change the tapping term. - -```c -enum custom_dynamic_tapping_term_keys = { - DT_UP_50 = SAFE_RANGE, - DT_DOWN_50, - DT_UP_X2, - DT_DOWN_X2, -} - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case DT_UP_50: - if (record->event.pressed) { - g_tapping_term += 50; - } - break; - case DT_DOWN_50: - if (record->event.pressed) { - g_tapping_term -= 50; - } - break; - case DT_UP_X2: - if (record->event.pressed) { - g_tapping_term *= 2; - } - break; - case DT_DOWN_X2: - if (record->event.pressed) { - g_tapping_term /= 2; - } - break; - } - return true; -}; -``` - -In order for this feature to be effective if you use per-key tapping terms, you need to make a few changes to the syntax of the `get_tapping_term` function. All you need to do is replace every occurrence of `TAPPING_TERM` in the `get_tapping_term` function by lowercase `g_tapping_term`. If you don't do that, you will still see the value typed by `DT_PRNT` go up and down as you configure the tapping term on the fly but you won't feel those changes as they don't get applied. If you can go as low as 10ms and still easily trigger the tap function of a dual-role key, that's a sign that you forgot to make the necessary changes to your `get_tapping_term` function. - -For instance, here's how the example `get_tapping_term` shown earlier should look after the transformation: - -```c -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return g_tapping_term + 1250; - case LT(1, KC_GRV): - return 130; - default: - return g_tapping_term; - } -} -``` - -The reason is that `TAPPING_TERM` is a macro that expands to a constant integer and thus cannot be changed at runtime whereas `g_tapping_term` is a variable whose value can be changed at runtime. If you want, you can temporarily enable `DYNAMIC_TAPPING_TERM_ENABLE` to find a suitable tapping term value and then disable that feature and revert back to using the classic syntax for per-key tapping term settings. In case you need to access the tapping term from elsewhere in your code, you can use the `GET_TAPPING_TERM(keycode, record)` macro. This macro will expand to whatever is the appropriate access pattern given the current configuration. - -## Tap-Or-Hold Decision Modes - -The code which decides between the tap and hold actions of dual-role keys supports three different modes, in increasing order of preference for the hold action: - -1. The default mode selects the hold action only if the dual-role key is held down longer than the tapping term. In this mode pressing other keys while the dual-role key is held down does not influence the tap-or-hold decision. In other words, this mode ignores interrupts. - -2. The “permissive hold” mode, in addition to the default behavior, immediately selects the hold action when another key is tapped (pressed and then released) while the dual-role key is held down, even if this happens earlier than the tapping term. If another key is just pressed, but then the dual-role key is released before that other key (and earlier than the tapping term), this mode will still select the tap action. - -3. The “hold on other key press” mode, in addition to the default behavior, immediately selects the hold action when another key is pressed while the dual-role key is held down, even if this happens earlier than the tapping term. - -Note that until the tap-or-hold decision completes (which happens when either the dual-role key is released, or the tapping term has expired, or the extra condition for the selected decision mode is satisfied), key events are delayed and not transmitted to the host immediately. The default mode gives the most delay (if the dual-role key is held down, this mode always waits for the whole tapping term), and the other modes may give less delay when other keys are pressed, because the hold action may be selected earlier. - -### Comparison :id=comparison - -To better illustrate the tap-or-hold decision modes, let us compare the expected output of each decision mode in a handful of tapping scenarios involving a mod-tap key (`LSFT_T(KC_A)`) and a regular key (`KC_B`) with the `TAPPING_TERM` set to 200ms. - -Note: "`kc` held" in the "Physical key event" column means that the key wasn't physically released yet at this point in time. - -#### Distinct taps (AABB) :id=distinct-taps - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 199 | `LSFT_T(KC_A)` up | a | a | a | -| 210 | `KC_B` down | ab | ab | ab | -| 220 | `KC_B` up | ab | ab | ab | - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 200 | `LSFT_T(KC_A)` held|Shift| Shift | Shift | -| 201 | `LSFT_T(KC_A)` up |Shift| Shift | Shift | -| 205 | `KC_B` down | b | b | b | -| 210 | `KC_B` up | b | b | b | - -#### Nested tap (ABBA) :id=nested-tap - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 110 | `KC_B` down | | | B | -| 120 | `KC_B` up | | B | B | -| 199 | `LSFT_T(KC_A)` up | ab | B | B | - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 110 | `KC_B` down | | | B | -| 120 | `KC_B` up | | B | B | -| 200 | `LSFT_T(KC_A)` held| B | B | B | -| 210 | `LSFT_T(KC_A)` up | B | B | B | - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 200 | `LSFT_T(KC_A)` held|Shift| Shift | Shift | -| 205 | `KC_B` down | B | B | B | -| 210 | `KC_B` up | B | B | B | -| 220 | `LSFT_T(KC_A)` up | B | B | B | - -#### Rolling keys (ABAB) :id=rolling-keys - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 110 | `KC_B` down | | | B | -| 130 | `LSFT_T(KC_A)` up | ab | ab | B | -| 140 | `KC_B` up | ab | ab | B | - -| Time | Physical key event | Default | `PERMISSIVE_HOLD` | `HOLD_ON_OTHER_KEY_PRESS` | -|------|--------------------|----------------|-------------------|----------------------------| -| 0 | `LSFT_T(KC_A)` down| | | | -| 110 | `KC_B` down | | | B | -| 200 | `LSFT_T(KC_A)` held| B | B | B | -| 205 | `LSFT_T(KC_A)` up | B | B | B | -| 210 | `KC_B` up | B | B | B | - -### Default Mode -Example sequence 1 (the `L` key is also mapped to `KC_RGHT` on layer 2): - -``` - TAPPING_TERM - +---------------|--------------------+ - | +-------------|-------+ | - | | LT(2, KC_A) | | | - | +-------------|-------+ | - | | +--------------+ | - | | | KC_L | | - | | +--------------+ | - +---------------|--------------------+ -``` -The above sequence would send a `KC_RGHT`, since `LT(2, KC_A)` is held longer than the `TAPPING_TERM`. - ---- - -Example sequence 2 (the `L` key is also mapped to `KC_RGHT` on layer 2): - -``` - TAPPING_TERM - +-----------------------------|------+ - | +---------------+ | | - | | LT(2, KC_A) | | | - | +---------------+ | | - | +--------------+ | | - | | KC_L | | | - | +--------------+ | | - +-----------------------------|------+ -``` -The above sequence will not send `KC_RGHT` but `KC_A` `KC_L` instead, since `LT(2, KC_A)` is not held longer than the `TAPPING_TERM`. - ---- - -Example sequence 3 (Mod Tap): - -``` - TAPPING_TERM - +---------------------------|--------+ - | +-------------+ | | - | | SFT_T(KC_A) | | | - | +-------------+ | | - | +--------------+ | | - | | KC_X | | | - | +--------------+ | | - +---------------------------|--------+ -``` -In the above sequence, `SFT_T(KC_A)` has been released before the end of its `TAPPING_TERM` and as such will be interpreted as `KC_A`, -followed by any key event that happened after the initial press of `SFT_T(KC_A)`. In this instance, the output would be `KC_A` `KC_X`. - -### Permissive Hold - -The “permissive hold” mode can be enabled for all dual-role keys by adding the corresponding option to `config.h`: - -```c -#define PERMISSIVE_HOLD -``` - -This makes tap and hold keys (like Layer Tap) work better for fast typists, or for high `TAPPING_TERM` settings. - -If you press a dual-role key, tap another key (press and release) and then release the dual-role key, all within the tapping term, by default the dual-role key will perform its tap action. If the `PERMISSIVE_HOLD` option is enabled, the dual-role key will perform its hold action instead. - -An example of a sequence that is affected by the “permissive hold” mode: - -- `LT(2, KC_A)` Down -- `KC_L` Down (the `L` key is also mapped to `KC_RGHT` on layer 2) -- `KC_L` Up -- `LT(2, KC_A)` Up - -``` - TAPPING_TERM - +---------------------------|--------+ - | +----------------------+ | | - | | LT(2, KC_A) | | | - | +----------------------+ | | - | +--------------+ | | - | | KC_L | | | - | +--------------+ | | - +---------------------------|--------+ -``` - -Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `PERMISSIVE_HOLD` option enabled, the Layer Tap key is considered as a layer switch if another key is tapped, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2). We could describe this sequence as a “nested tap” (the modified key's key down and key up events are “nested” between the dual-role key's key down and key up events). - -However, this slightly different sequence will not be affected by the “permissive hold” mode: - -- `LT(2, KC_A)` Down -- `KC_L` Down (the `L` key is also mapped to `KC_RGHT` on layer 2) -- `LT(2, KC_A)` Up -- `KC_L` Up - -``` - TAPPING_TERM - +---------------------------|--------+ - | +-------------+ | | - | | LT(2, KC_A) | | | - | +-------------+ | | - | +--------------+ | | - | | KC_L | | | - | +--------------+ | | - +---------------------------|--------+ -``` - -In the sequence above the dual-role key is released before the other key is released, and if that happens within the tapping term, the “permissive hold” mode will still choose the tap action for the dual-role key, and the sequence will be registered as `al` by the host. We could describe this as a “rolling press” (the two keys' key down and key up events behave as if you were rolling a ball across the two keys, first pressing each key down in sequence and then releasing them in the same order). - -?> The `PERMISSIVE_HOLD` option is not noticeable if you also enable `HOLD_ON_OTHER_KEY_PRESS` because the latter option considers both the “nested tap” and “rolling press” sequences like shown above as a hold action, not the tap action. `HOLD_ON_OTHER_KEY_PRESS` makes the Tap-Or-Hold decision earlier in the chain of key events, thus taking a precedence over `PERMISSIVE_HOLD`. - -For more granular control of this feature, you can add the following to your `config.h`: - -```c -#define PERMISSIVE_HOLD_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(1, KC_BSPC): - // Immediately select the hold action when another key is tapped. - return true; - default: - // Do not select the hold action when another key is tapped. - return false; - } -} -``` - -### Hold On Other Key Press - -The “hold on other key press” mode can be enabled for all dual-role keys by adding the corresponding option to `config.h`: - -```c -#define HOLD_ON_OTHER_KEY_PRESS -``` - -This mode makes tap and hold keys (like Layer Tap) work better for fast typists, or for high `TAPPING_TERM` settings. Compared to the “permissive hold” mode, this mode selects the hold action in more cases. - -If you press a dual-role key, press another key, and then release the dual-role key, all within the tapping term, by default the dual-role key will perform its tap action. If the `HOLD_ON_OTHER_KEY_PRESS` option is enabled, the dual-role key will perform its hold action instead. - -An example of a sequence that is affected by the “hold on other key press” mode, but not by the “permissive hold” mode: - -- `LT(2, KC_A)` Down -- `KC_L` Down (the `L` key is also mapped to `KC_RGHT` on layer 2) -- `LT(2, KC_A)` Up -- `KC_L` Up - -``` - TAPPING_TERM - +---------------------------|--------+ - | +-------------+ | | - | | LT(2, KC_A) | | | - | +-------------+ | | - | +--------------+ | | - | | KC_L | | | - | +--------------+ | | - +---------------------------|--------+ -``` - -Normally, if you do all this within the `TAPPING_TERM` (default: 200ms), this will be registered as `al` by the firmware and host system. With the `HOLD_ON_OTHER_KEY_PRESS` option enabled, the Layer Tap key is considered as a layer switch if another key is pressed, and the above sequence would be registered as `KC_RGHT` (the mapping of `L` on layer 2). - -For more granular control of this feature, you can add the following to your `config.h`: - -```c -#define HOLD_ON_OTHER_KEY_PRESS_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(1, KC_BSPC): - // Immediately select the hold action when another key is pressed. - return true; - default: - // Do not select the hold action when another key is pressed. - return false; - } -} -``` - -## Quick Tap Term - -When the user holds a key after tapping it, the tapping function is repeated by default, rather than activating the hold function. This allows keeping the ability to auto-repeat the tapping function of a dual-role key. `QUICK_TAP_TERM` enables fine tuning of that ability. If set to `0`, it will remove the auto-repeat ability and activate the hold function instead. - -`QUICK_TAP_TERM` is set to `TAPPING_TERM` by default, which is the maximum allowed value for `QUICK_TAP_TERM`. To override its value (in milliseconds) add the following to your `config.h`: - -```c -#define QUICK_TAP_TERM 120 -``` - -Example: - -- `SFT_T(KC_A)` Down -- `SFT_T(KC_A)` Up -- `SFT_T(KC_A)` Down -- (wait until tapping term expires...) - -With default settings, `a` will be sent on the first release, then `a` will be sent on the second press allowing the computer to trigger its auto repeat function until the key is released. - -With `QUICK_TAP_TERM` configured, the timing between `SFT_T(KC_A)` up and `SFT_T(KC_A)` down must be within `QUICK_TAP_TERM` to trigger auto repeat. Otherwise the second press will be sent as a Shift. If `QUICK_TAP_TERM` is set to `0`, the second press will always be sent as a Shift, effectively disabling auto-repeat. - -!> `QUICK_TAP_TERM` timing will also impact anything that uses tapping toggles (Such as the `TT` layer keycode, and the One Shot Tap Toggle). - -For more granular control of this feature, you can add the following to your `config.h`: - -```c -#define QUICK_TAP_TERM_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case SFT_T(KC_SPC): - return QUICK_TAP_TERM - 20; - default: - return QUICK_TAP_TERM; - } -} -``` - -?> If `QUICK_TAP_TERM` is set higher than `TAPPING_TERM`, it will default to `TAPPING_TERM`. - -## Retro Tapping - -To enable `retro tapping`, add the following to your `config.h`: - -```c -#define RETRO_TAPPING -``` - -Holding and releasing a dual-function key without pressing another key will result in nothing happening. With retro tapping enabled, releasing the key without pressing another will send the original keycode even if it is outside the tapping term. - -For instance, holding and releasing `LT(2, KC_SPC)` without hitting another key will result in nothing happening. With this enabled, it will send `KC_SPC` instead. - -``` - TAPPING_TERM - +-----------------|------------------+ - | +---------------|-------+ | - | | LT(2, KC_SPC) | | | - | +---------------|-------+ | - | | | - | | | - | | | - +-----------------|------------------+ -``` - -For more granular control of this feature, you can add the following to your `config.h`: - -```c -#define RETRO_TAPPING_PER_KEY -``` - -You can then add the following function to your keymap: - -```c -bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(2, KC_SPC): - return true; - default: - return false; - } -} -``` - -### Retro Shift - -[Auto Shift,](feature_auto_shift.md) has its own version of `retro tapping` called `retro shift`. It is extremely similar to `retro tapping`, but holding the key past `AUTO_SHIFT_TIMEOUT` results in the value it sends being shifted. Other configurations also affect it differently; see [here](feature_auto_shift.md#retro-shift) for more information. - -## Why do we include the key record for the per key functions? - -One thing that you may notice is that we include the key record for all of the "per key" functions, and may be wondering why we do that. - -Well, it's simple really: customization. But specifically, it depends on how your keyboard is wired up. For instance, if each row is actually using a row in the keyboard's matrix, then it may be simpler to use `if (record->event.row == 3)` instead of checking a whole bunch of keycodes. Which is especially good for those people using the Tap Hold type keys on the home row. So you could fine-tune those to not interfere with your normal typing. - -## Why are there no `*_kb` or `*_user` functions?! - -Unlike many of the other functions here, there isn't a need (or even reason) to have a quantum or keyboard-level function. Only user-level functions are useful here, so no need to mark them as such. diff --git a/docs/translating.md b/docs/translating.md deleted file mode 100644 index 4365817590d0..000000000000 --- a/docs/translating.md +++ /dev/null @@ -1,55 +0,0 @@ -# Translating the QMK Docs - -All files in the root folder (`docs/`) should be in English - all other languages should be in subfolders with the ISO 639-1 language codes, followed by `-` and the country code where relevant. [A list of common ones can be found here](https://www.andiamo.co.uk/resources/iso-language-codes/). If this folder doesn't exist, you may create it. Each of the translated files should have the same name as the English version, so things can fall back successfully. - -A `_summary.md` file should exist in this folder with a list of links to each file, with a translated name, and link preceded by the language folder: - -```markdown - * [QMK简介](zh-cn/getting_started_introduction.md) -``` - -All links to other docs pages must also be prefixed with the language folder. If the link is to a specific part of the page (ie. a certain heading), you must use the English ID for the heading, like so: - -```markdown -[建立你的环境](zh-cn/newbs-getting-started.md#set-up-your-environment) - -## 建立你的环境 :id=set-up-your-environment -``` - -Once you've finished translating a new language, you'll also need to modify the following files: - -* [`docs/_langs.md`](https://github.com/qmk/qmk_firmware/blob/master/docs/_langs.md) - Each line should contain a country flag as a [GitHub emoji shortcode](https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#country-flag) followed by the name represented in its own language: - - ```markdown - - [:cn: 中文](/zh-cn/) - ``` - -* [`docs/index.html`](https://github.com/qmk/qmk_firmware/blob/master/docs/index.html) - Both `placeholder` and `noData` objects should have a dictionary entry for the language folder in a string: - - ```js - '/zh-cn/': '没有结果!', - ``` - - The `nameLink` object, for setting the "QMK Firmware" heading link in the sidebar, must also be added to: - - ```js - '/zh-cn/': '/#/zh-cn/', - ``` - - And make sure to add the language folder in the `fallbackLanguages` list, so it will properly fall back to English instead of 404ing: - - ```js - fallbackLanguages: [ - // ... - 'zh-cn', - // ... - ], - ``` - -## Previewing the Translations - -See [Previewing the Documentation](contributing.md#previewing-the-documentation) for how to set up a local instance of the docs - you should be able to select your new language from the "Translations" menu at the top-right. - -Once you're happy with your work, feel free to open a pull request! diff --git a/docs/uart_driver.md b/docs/uart_driver.md deleted file mode 100644 index 340b64818920..000000000000 --- a/docs/uart_driver.md +++ /dev/null @@ -1,116 +0,0 @@ -# UART Driver - -The UART drivers used in QMK have a set of common functions to allow portability between MCUs. - -Currently, this driver does not support enabling hardware flow control (the `RTS` and `CTS` pins) if available, but may do so in future. - -## AVR Configuration - -No special setup is required - just connect the `RX` and `TX` pins of your UART device to the opposite pins on the MCU: - -|MCU |`TX`|`RX`|`CTS`|`RTS`| -|-------------|----|----|-----|-----| -|ATmega16/32U2|`D3`|`D2`|`D7` |`D6` | -|ATmega16/32U4|`D3`|`D2`|`D5` |`B7` | -|AT90USB64/128|`D3`|`D2`|*n/a*|*n/a*| -|ATmega32A |`D1`|`D0`|*n/a*|*n/a*| -|ATmega328/P |`D1`|`D0`|*n/a*|*n/a*| - -## ChibiOS/ARM Configuration - -You'll need to determine which pins can be used for UART -- as an example, STM32 parts generally have multiple UART peripherals, labeled USART1, USART2, USART3 etc. - -To enable UART, modify your board's `halconf.h` to enable the serial driver: - -```c -#define HAL_USE_SERIAL TRUE -``` - -Then, modify your board's `mcuconf.h` to enable the peripheral you've chosen, for example: - -```c -#undef STM32_SERIAL_USE_USART2 -#define STM32_SERIAL_USE_USART2 TRUE -``` - -Configuration-wise, you'll need to set up the peripheral as per your MCU's datasheet -- the defaults match the pins for a Proton-C, i.e. STM32F303. - -|`config.h` override |Description |Default Value| -|--------------------------|---------------------------------------------------------------|-------------| -|`#define SERIAL_DRIVER` |USART peripheral to use - USART1 -> `SD1`, USART2 -> `SD2` etc.|`SD1` | -|`#define SD1_TX_PIN` |The pin to use for TX |`A9` | -|`#define SD1_TX_PAL_MODE` |The alternate function mode for TX |`7` | -|`#define SD1_RX_PIN` |The pin to use for RX |`A10` | -|`#define SD1_RX_PAL_MODE` |The alternate function mode for RX |`7` | -|`#define SD1_CTS_PIN` |The pin to use for CTS |`A11` | -|`#define SD1_CTS_PAL_MODE`|The alternate function mode for CTS |`7` | -|`#define SD1_RTS_PIN` |The pin to use for RTS |`A12` | -|`#define SD1_RTS_PAL_MODE`|The alternate function mode for RTS |`7` | - -## Functions - -### `void uart_init(uint32_t baud)` - -Initialize the UART driver. This function must be called only once, before any of the below functions can be called. - -#### Arguments - - - `uint32_t baud` - The baud rate to transmit and receive at. This may depend on the device you are communicating with. Common values are 1200, 2400, 4800, 9600, 19200, 38400, 57600, and 115200. - ---- - -### `void uart_write(uint8_t data)` - -Transmit a single byte. - -#### Arguments - - - `uint8_t data` - The byte to write. - ---- - -### `uint8_t uart_read(void)` - -Receive a single byte. - -#### Return Value - -The byte read from the receive buffer. This function will block if the buffer is empty (ie. no data to read). - ---- - -### `void uart_transmit(const uint8_t *data, uint16_t length)` - -Transmit multiple bytes. - -#### Arguments - - - `const uint8_t *data` - A pointer to the data to write from. - - `uint16_t length` - The number of bytes to write. Take care not to overrun the length of `data`. - ---- - -### `void uart_receive(char *data, uint16_t length)` - -Receive multiple bytes. - -#### Arguments - - - `uint8_t *data` - A pointer to the buffer to read into. - - `uint16_t length` - The number of bytes to read. Take care not to overrun the length of `data`. - ---- - -### `bool uart_available(void)` - -Return whether the receive buffer contains data. Call this function to determine if `uart_read()` will return data immediately. - -#### Return Value - -`true` if the receive buffer length is non-zero. diff --git a/docs/understanding_qmk.md b/docs/understanding_qmk.md deleted file mode 100644 index 7cb46bd8cf2e..000000000000 --- a/docs/understanding_qmk.md +++ /dev/null @@ -1,198 +0,0 @@ -# Understanding QMK's Code - -This document attempts to explain how the QMK firmware works from a very high level. It assumes you understand basic programming concepts but does not (except where needed to demonstrate) assume familiarity with C. It assumes that you have a basic understanding of the following documents: - -* [Introduction](getting_started_introduction.md) -* [How Keyboards Work](how_keyboards_work.md) -* [FAQ](faq_general.md) - -## Startup - -You can think of QMK as no different from any other computer program. It is started and performs its tasks, but this program never finishes. Like other C programs, the entry point is the `main()` function. For QMK, the `main()` function is found in [`quantum/main.c`](https://github.com/qmk/qmk_firmware/blob/0.15.13/quantum/main.c#L55). - -If you browse through the `main()` function you'll find that it starts by initializing any hardware that has been configured (including USB to the host). The most common platform for QMK is `lufa`, which runs on AVR processors such as the atmega32u4. When compiled for that platform, it will invoke for example `platform_setup()` in [`platforms/avr/platform.c`](https://github.com/qmk/qmk_firmware/blob/0.15.13/platforms/avr/platform.c#L19) and `protocol_setup()` in [`tmk_core/protocol/lufa/lufa.c`](https://github.com/qmk/qmk_firmware/blob/0.15.13/tmk_core/protocol/lufa/lufa.c#L1066). It will use other implementations when compiled for other platforms like `chibios` and `vusb`. At first glance, it can look like a lot of functionality but most of the time the code will be disabled by `#define`s. - -The `main()` function will then start the core part of the program with a [`while (true)`](https://github.com/qmk/qmk_firmware/blob/0.15.13/quantum/main.c#L63). This is [The Main Loop](#the-main-loop). - -## The Main Loop - -This section of code is called "The Main Loop" because it's responsible for looping over the same set of instructions forever, without ever reaching the end. This is where QMK dispatches out to the functions responsible for making the keyboard do everything it is supposed to do. - -The main loop will call [`protocol_task()`](https://github.com/qmk/qmk_firmware/blob/0.15.13/quantum/main.c#L38), which in turn will call `keyboard_task()` in [`quantum/keyboard.c`](https://github.com/qmk/qmk_firmware/blob/0.15.13/quantum/keyboard.c#L377). This is where all the keyboard specific functionality is dispatched, and it is responsible for detecting changes in the matrix and turning status LEDs on and off. - -Within `keyboard_task()` you'll find code to handle: - -* [Matrix Scanning](#matrix-scanning) -* Mouse Handling -* Keyboard status LEDs (Caps Lock, Num Lock, Scroll Lock) - -#### Matrix Scanning - -Matrix scanning is the core function of a keyboard firmware. It is the process of detecting which keys are currently pressed, and your keyboard runs this function many times a second. It's no exaggeration to say that 99% of your firmware's CPU time is spent on matrix scanning. - -While there are different strategies for doing the actual matrix detection, they are out of scope for this document. It is sufficient to treat matrix scanning as a black box, you ask for the matrix's current state and get back a datastructure that looks like this: - - -``` -{ - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -That datastructure is a direct representation of the matrix for a 5 row by 4 column numpad. When a key is pressed that key's position within the matrix will be returned as `1` instead of `0`. - -Matrix Scanning runs many times per second. The exact rate varies but typically it runs at least 10 times per second to avoid perceptible lag. - -##### Matrix to Physical Layout Map - -Once we know the state of every switch on our keyboard we have to map that to a keycode. In QMK this is done by making use of C macros to allow us to separate the definition of the physical layout from the definition of keycodes. - -At the keyboard level we define a C macro (typically named `LAYOUT()`) which maps our keyboard's matrix to physical keys. Sometimes the matrix does not have a switch in every location, and we can use this macro to pre-populate those with KC_NO, making the keymap definition easier to work with. Here's an example `LAYOUT()` macro for a numpad: - -```c -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ -) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, KC_NO }, \ - { k30, k31, k32, k33 }, \ - { k40, KC_NO, k42, KC_NO } \ -} -``` - -Notice how the second block of our `LAYOUT()` macro matches the Matrix Scanning array above? This macro is what will map the matrix scanning array to keycodes. However, if you look at a 17 key numpad you'll notice that it has 3 places where the matrix could have a switch but doesn't, due to larger keys. We have populated those spaces with `KC_NO` so that our keymap definition doesn't have to. - -You can also use this macro to handle unusual matrix layouts, for example the [Alice](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/sneakbox/aliceclone/aliceclone.h#L24). Explaining that is outside the scope of this document. - -##### Keycode Assignment - -At the keymap level we make use of our `LAYOUT()` macro above to map keycodes to physical locations to matrix locations. It looks like this: - -```c -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - [0] = LAYOUT( - KC_NUM, KC_PSLS, KC_PAST, KC_PMNS, - KC_P7, KC_P8, KC_P9, KC_PPLS, - KC_P4, KC_P5, KC_P6, - KC_P1, KC_P2, KC_P3, KC_PENT, - KC_P0, KC_PDOT - ) -} -``` - -Notice how all of these arguments match up with the first half of the `LAYOUT()` macro from the last section? This is how we take a keycode and map it to our Matrix Scan from earlier. - -##### State Change Detection - -The matrix scanning described above tells us the state of the matrix at a given moment, but your computer only wants to know about changes, it doesn't care about the current state. QMK stores the results from the last matrix scan and compares the results from this matrix to determine when a key has been pressed or released. - -Let's look at an example. We'll hop into the middle of a keyboard scanning loop to find that our previous scan looks like this: - -``` -{ - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -And when our current scan completes it will look like this: - -``` -{ - {1,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0}, - {0,0,0,0} -} -``` - -Comparing against our keymap we can see that the pressed key is `KC_NUM`. From here we dispatch to the `process_record` set of functions. - - - -##### Process Record - -The `process_record()` function itself is deceptively simple, but hidden within is a gateway to overriding functionality at various levels of QMK. The chain of events is listed below, using cluecard whenever we need to look at the keyboard/keymap level functions. Depending on options set in `rules.mk` or elsewhere, only a subset of the functions below will be included in final firmware. - -* [`void action_exec(keyevent_t event)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/action.c#L78-L140) - * [`void pre_process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L204) - * [`bool pre_process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/27119fa77e8a1b95fff80718d3db4f3e32849298/quantum/quantum.c#L117) - * [`bool pre_process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/27119fa77e8a1b95fff80718d3db4f3e32849298/quantum/quantum.c#L121) - * [`bool process_combo(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_combo.c#L521) - * [`void process_record(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/action.c#L254) - * [`bool process_record_quantum(keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L224) - * [Map this record to a keycode](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L225) - * [`void velocikey_accelerate(void)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/velocikey.c#L27) - * [`void update_wpm(uint16_t keycode)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/wpm.c#L109) - * [`void preprocess_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_tap_dance.c#L118) - * [`bool process_key_lock(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_key_lock.c#L64) - * [`bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_dynamic_macro.c#L160) - * [`bool process_clicky(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_clicky.c#L84) - * [`bool process_haptic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_haptic.c#L87) - * [`bool process_record_via(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/via.c#L160) - * [`bool process_record_kb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/planck/ez/ez.c#L271) - * [`bool process_record_user(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/keyboards/planck/keymaps/default/keymap.c#L183) - * [`bool process_secure(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_secure.c#L23) - * [`bool process_sequencer(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_sequencer.c#L19) - * [`bool process_midi(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_midi.c#L75) - * [`bool process_audio(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_audio.c#L18) - * [`bool process_backlight(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_backlight.c#L25) - * [`bool process_steno(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_steno.c#L159) - * [`bool process_music(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_music.c#L103) - * [`bool process_key_override(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/5a1b857dea45a17698f6baa7dd1b7a7ea907fb0a/quantum/process_keycode/process_key_override.c#L397) - * [`bool process_tap_dance(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_tap_dance.c#L135) - * [`bool process_caps_word(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_caps_word.c#L17) - * [`bool process_unicode_common(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicode_common.c#L290) - calls one of: - * [`bool process_unicode(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicode.c#L21) - * [`bool process_unicodemap(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_unicodemap.c#L42) - * [`bool process_ucis(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_ucis.c#L70) - * [`bool process_leader(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_leader.c#L48) - * [`bool process_auto_shift(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_auto_shift.c#L353) - * [`bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_dynamic_tapping_term.c#L35) - * [`bool process_space_cadet(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_space_cadet.c#L123) - * [`bool process_magic(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_magic.c#L40) - * [`bool process_grave_esc(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_grave_esc.c#L23) - * [`bool process_rgb(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_rgb.c#L53) - * [`bool process_joystick(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_joystick.c#L9) - * [`bool process_programmable_button(uint16_t keycode, keyrecord_t *record)`](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/process_keycode/process_programmable_button.c#L21) - * [Identify and process Quantum-specific keycodes](https://github.com/qmk/qmk_firmware/blob/325da02e57fe7374e77b82cb00360ba45167e25c/quantum/quantum.c#L343) - -At any step during this chain of events a function (such as `process_record_kb()`) can `return false` to halt all further processing. - -After this is called, `post_process_record()` is called, which can be used to handle additional cleanup that needs to be run after the keycode is normally handled. - -* [`void post_process_record(keyrecord_t *record)`]() - * [`void post_process_record_quantum(keyrecord_t *record)`]() - * [Map this record to a keycode]() - * [`void post_process_clicky(uint16_t keycode, keyrecord_t *record)`]() - * [`void post_process_record_kb(uint16_t keycode, keyrecord_t *record)`]() - * [`void post_process_record_user(uint16_t keycode, keyrecord_t *record)`]() - - diff --git a/docs/unit_testing.md b/docs/unit_testing.md deleted file mode 100644 index 47a105579643..000000000000 --- a/docs/unit_testing.md +++ /dev/null @@ -1,76 +0,0 @@ -# Unit Testing - -If you are new to unit testing, then you can find many good resources on internet. However most of it is scattered around in small pieces here and there, and there's also many different opinions, so I won't give any recommendations. - -Instead I recommend these two books, explaining two different styles of Unit Testing in detail. - -* "Test Driven Development: By Example: Kent Beck" -* "Growing Object-Oriented Software, Guided By Tests: Steve Freeman, Nat Pryce" - -If you prefer videos there are Uncle Bob's [Clean Coders Videos](https://cleancoders.com/), which unfortunately cost quite a bit, especially if you want to watch many of them. But James Shore has a free [Let's Play](https://www.jamesshore.com/Blog/Lets-Play) video series. - -## Google Test and Google Mock -It's possible to Unit Test your code using [Google Test](https://github.com/google/googletest). The Google Test framework also includes another component for writing testing mocks and stubs, called "Google Mock". For information how to write the actual tests, please refer to the documentation on that site. - -## Use of C++ - -Note that Google Test and therefore any test has to be written in C++, even if the rest of the QMK codebases is written in C. This should hopefully not be a problem even if you don't know any C++, since there's quite clear documentation and examples of the required C++ features, and you can write the rest of the test code almost as you would write normal C. Note that some compiler errors which you might get can look quite scary, but just read carefully what it says, and you should be ok. - -One thing to remember, is that you have to append `extern "C"` around all of your C file includes. - -## Adding Tests for New or Existing Features - -If you want to unit test a feature, take a look at some of the existing tests, for example those in the `quantum/sequencer/tests` folder. Then follow the steps below to create a similar structure. - -1. If it doesn't already exist, add a test subfolder to the folder containing the feature. -2. Create a `testlist.mk` and a `rules.mk` file in that folder. -3. Include those files from the root folder `testlist.mk`and `build_test.mk` respectively. -4. Add a new name for your testgroup to the `testlist.mk` file. Each group defined there will be a separate executable. And that's how you can support mocking out different parts. Note that it's worth adding some common prefix, just like it's done for the existing tests. The reason for that is that the make command allows substring filtering, so this way you can easily run a subset of the tests. -5. Define the source files and required options in the `rules.mk` file. - * `_SRC` for source files - * `_DEFS` for additional defines - * `_INC` for additional include folders -6. Write the tests in a new cpp file inside the test folder you created. That file has to be one of the files included from the `rules.mk` file. - -Note how there's several different tests, each mocking out a separate part. Also note that each of them only compiles the very minimum that's needed for the tests. It's recommend that you try to do the same. For a relevant video check out [Matt Hargett "Advanced Unit Testing in C & C++](https://www.youtube.com/watch?v=Wmy6g-aVgZI) - -## Running the Tests - -To run all the tests in the codebase, type `make test:all`. You can also run test matching a substring by typing `make test:matchingsubstring` Note that the tests are always compiled with the native compiler of your platform, so they are also run like any other program on your computer. - -## Debugging the Tests - -If there are problems with the tests, you can find the executable in the `./build/test` folder. You should be able to run those with GDB or a similar debugger. - -To forward any [debug messages](unit_testing.md#debug-api) to `stderr`, the tests can run with `DEBUG=1`. For example - -``` -make test:all DEBUG=1 -``` - -Alternatively, add `CONSOLE_ENABLE=yes` to the tests `rules.mk`. - -## Full Integration Tests - -It's not yet possible to do a full integration test, where you would compile the whole firmware and define a keymap that you are going to test. However there are plans for doing that, because writing tests that way would probably be easier, at least for people that are not used to unit testing. - -In that model you would emulate the input, and expect a certain output from the emulated keyboard. - -# Tracing Variables :id=tracing-variables - -Sometimes you might wonder why a variable gets changed and where, and this can be quite tricky to track down without having a debugger. It's of course possible to manually add print statements to track it, but you can also enable the variable trace feature. This works for both variables that are changed by the code, and when the variable is changed by some memory corruption. - -To take the feature into use add `VARIABLE_TRACE=x` to the end of you make command. `x` represents the number of variables you want to trace, which is usually 1. - -Then at a suitable place in the code, call `ADD_TRACED_VARIABLE`, to begin the tracing. For example to trace all the layer changes, you can do this -```c -void matrix_init_user(void) { - ADD_TRACED_VARIABLE("layer", &layer_state, sizeof(layer_state)); -} -``` - -This will add a traced variable named "layer" (the name is just for your information), which tracks the memory location of `layer_state`. It tracks 4 bytes (the size of `layer_state`), so any modification to the variable will be reported. By default you can not specify a size bigger than 4, but you can change it by adding `MAX_VARIABLE_TRACE_SIZE=x` to the end of the make command line. - -In order to actually detect changes to the variables you should call `VERIFY_TRACED_VARIABLES` around the code that you think that modifies the variable. If a variable is modified it will tell you between which two `VERIFY_TRACED_VARIABLES` calls the modification happened. You can then add more calls to track it down further. I don't recommend spamming the codebase with calls. It's better to start with a few, and then keep adding them in a binary search fashion. You can also delete the ones you don't need, as each call need to store the file name and line number in the ROM, so you can run out of memory if you add too many calls. - -Also remember to delete all the tracing code once you have found the bug, as you wouldn't want to create a pull request with tracing code. diff --git a/docs/usb_nkro.txt b/docs/usb_nkro.txt deleted file mode 100644 index d9f1d1229214..000000000000 --- a/docs/usb_nkro.txt +++ /dev/null @@ -1,160 +0,0 @@ -USB NKRO MEMO -============= -2010/12/09 - - -References ----------- -USB - boot mode, NKRO, compatibility, etc... - http://geekhack.org/showthread.php?t=13162 -NKey Rollover - Overview, Testing Methodology, and Results - http://geekhack.org/showwiki.php?title=NKey+Rollover+-+Overview+Testing+Methodology+and+Results -dfj's NKRO(2010/06) - http://geekhack.org/showpost.php?p=191195&postcount=251 - http://geekhack.org/showthread.php?p=204389#post204389 - - -Terminology ---------- -NKRO -ghost -matrix -mechanical with diodes -membrane - - -OS Support Status ------------------ -USB NKRO is possible *without* a custom driver. -At least following OS's supports. - Windows7 64bit - WindowsXP - Windows2000 SP4 - Ubuntu10.4(Linux 2.6) - MacOSX(To be tested) - - -Custom Driver for USB NKRO --------------------------- -NOT NEEDED -at least when using following report formats on Windows, Linux or MacOSX. - - -USB NKRO methods ----------------- -1. Virtual keyboards - Keyboard can increase its KRO by using virtual keyboards with Standard or Extended report. - If the keyboard has 2 virtual keyboard with Standard report(6KRO), it gets 12KRO. - Using this method means the keyboard is a composite device. - -2. Extended report - It needs large report size for this method to achieve NKRO. - If a keyboard has 101keys, it needs 103byte report. It seems to be inefficient. - -3. Bitmap report - If the keyboard has less than 128keys, 16byte report will be enough for NKRO. - The 16byte report seems to be reasonable cost to get NKRO. - - -Report Format -------------- -Other report formats than followings are possible, though these format are typical one. - -1. Standard 8bytes - modifiers(bitmap) 1byte - reserved 1byte(not used) - keys(array) 1byte*6 -Standard report can send 6keys plus 8modifiers simultaneously. -Standard report is used by most keyboards in the marketplace. -Standard report is identical to boot protocol report. -Standard report is hard to suffer from compatibility problems. - -2. Extended standard 16,32,64bytes - modifiers(bitmap) 1byte - reserved 1byte(not used) - keys(array) 1byte*(14,32,62) -Extended report can send N-keys by using N+2bytes. -Extended report is expected to be compatible with boot protocol. - -3. Bitmap 16,32,64bytes - keys(bitmap) (16,32)bytes -Bitmap report can send at most 128keys by 16bytes and 256keys by 32bytes. -Bitmap report can achieve USB NKRO efficiently in terms of report size. -Bitmap report needs a deliberation for boot protocol implementation. -Bitmap report descriptor sample: - 0x05, 0x01, // Usage Page (Generic Desktop), - 0x09, 0x06, // Usage (Keyboard), - 0xA1, 0x01, // Collection (Application), - // bitmap of modifiers - 0x75, 0x01, // Report Size (1), - 0x95, 0x08, // Report Count (8), - 0x05, 0x07, // Usage Page (Key Codes), - 0x19, 0xE0, // Usage Minimum (224), - 0x29, 0xE7, // Usage Maximum (231), - 0x15, 0x00, // Logical Minimum (0), - 0x25, 0x01, // Logical Maximum (1), - 0x81, 0x02, // Input (Data, Variable, Absolute), ;Modifier byte - // LED output report - 0x95, 0x05, // Report Count (5), - 0x75, 0x01, // Report Size (1), - 0x05, 0x08, // Usage Page (LEDs), - 0x19, 0x01, // Usage Minimum (1), - 0x29, 0x05, // Usage Maximum (5), - 0x91, 0x02, // Output (Data, Variable, Absolute), - 0x95, 0x01, // Report Count (1), - 0x75, 0x03, // Report Size (3), - 0x91, 0x03, // Output (Constant), - // bitmap of keys - 0x95, (REPORT_BYTES-1)*8, // Report Count (), - 0x75, 0x01, // Report Size (1), - 0x15, 0x00, // Logical Minimum (0), - 0x25, 0x01, // Logical Maximum(1), - 0x05, 0x07, // Usage Page (Key Codes), - 0x19, 0x00, // Usage Minimum (0), - 0x29, (REPORT_BYTES-1)*8-1, // Usage Maximum (), - 0x81, 0x02, // Input (Data, Variable, Absolute), - 0xc0 // End Collection -where REPORT_BYTES is a report size in bytes. - - -Considerations --------------- -Compatibility - boot protocol - minor/old system - Some BIOS doesn't send SET_PROTOCOL request, a keyboard can't switch to boot protocol mode. - This may cause a problem on a keyboard which uses other report than Standard. -Reactivity - USB polling time - OS/Driver processing time - - -Windows Problem ---------------- -1. Windows accepts only 6keys in case of Standard report. - It should be able to send 6keys plus 8modifiers. -2. Windows accepts only 10keys in case of 16bytes Extended report. - It should be able to send 14keys plus 8modifiers. -3. Windows accepts only 18keys in case of 32bytes Extended report. - It should be able to send 30keys plus 8modifiers. -If keys are pressed in excess of the number, wrong keys are registered on Windows. - -This problem will be reportedly fixed soon.(2010/12/05) - http://forums.anandtech.com/showpost.php?p=30873364&postcount=17 - - -Tools for testing NKRO ----------------------- -Browser App: -http://www.microsoft.com/appliedsciences/content/projects/KeyboardGhostingDemo.aspx -http://random.xem.us/rollover.html - -Windows: -AquaKeyTest.exe http://geekhack.org/showthread.php?t=6643 - -Linux: -xkeycaps -xev -showkeys - -EOF diff --git a/docs/ws2812_driver.md b/docs/ws2812_driver.md deleted file mode 100644 index f8cad20ce0c0..000000000000 --- a/docs/ws2812_driver.md +++ /dev/null @@ -1,189 +0,0 @@ -# WS2812 Driver -This driver powers the [RGB Lighting](feature_rgblight.md) and [RGB Matrix](feature_rgb_matrix.md) features. - -Currently QMK supports the following addressable LEDs (however, the white LED in RGBW variants is not supported): - - WS2811, WS2812, WS2812B, WS2812C, etc. - SK6812, SK6812MINI, SK6805 - -These LEDs are called "addressable" because instead of using a wire per color, each LED contains a small microchip that understands a special protocol sent over a single wire. The chip passes on the remaining data to the next LED, allowing them to be chained together. In this way, you can easily control the color of the individual LEDs. - -## Supported Driver Types - -| | AVR | ARM | -| -------- | ------------------ | ------------------ | -| bit bang | :heavy_check_mark: | :heavy_check_mark: | -| I2C | :heavy_check_mark: | | -| SPI | | :heavy_check_mark: | -| PWM | | :heavy_check_mark: | -| PIO | | :heavy_check_mark: | - -## Driver configuration - -### All drivers - -Different versions of the addressable LEDs have differing requirements for the TRST period between frames. -The default setting is 280 µs, which should work for most cases, but this can be overridden in your config.h. e.g.: - -```c -#define WS2812_TRST_US 80 -``` - -#### Byte Order - -Some variants of the WS2812 may have their color components in a different physical or logical order. For example, the WS2812B-2020 has physically swapped red and green LEDs, which causes the wrong color to be displayed, because the default order of the bytes sent over the wire is defined as GRB. -In this case, you can change the byte order by defining `WS2812_BYTE_ORDER` as one of the following values: - -| Byte order | Known devices | -| --------------------------------- | ----------------------------- | -| `WS2812_BYTE_ORDER_GRB` (default) | Most WS2812's, SK6812, SK6805 | -| `WS2812_BYTE_ORDER_RGB` | WS2812B-2020 | -| `WS2812_BYTE_ORDER_BGR` | TM1812 | - - -### Bitbang -Default driver, the absence of configuration assumes this driver. To configure it, add this to your rules.mk: - -```make -WS2812_DRIVER = bitbang -``` - -!> This driver is not hardware accelerated and may not be performant on heavily loaded systems. - -#### Adjusting bit timings - -The WS2812 LED communication topology depends on a serialized timed window. Different versions of the addressable LEDs have differing requirements for the timing parameters, for instance, of the SK6812. -You can tune these parameters through the definition of the following macros: - -| Macro | Default | AVR | ARM | -| --------------- | ---------------------------- | ------------------ | ------------------ | -| `WS2812_TIMING` | `1250` | :heavy_check_mark: | :heavy_check_mark: | -| `WS2812_T0H` | `350` | :heavy_check_mark: | :heavy_check_mark: | -| `WS2812_T0L` | `WS2812_TIMING - WS2812_T0H` | | :heavy_check_mark: | -| `WS2812_T1H` | `900` | :heavy_check_mark: | :heavy_check_mark: | -| `WS2812_T1L` | `WS2812_TIMING - WS2812_T1H` | | :heavy_check_mark: | - -### I2C -Targeting boards where WS2812 support is offloaded to a 2nd MCU. Currently the driver is limited to AVR given the known consumers are ps2avrGB/BMC. To configure it, add this to your rules.mk: - -```make -WS2812_DRIVER = i2c -``` - -Configure the hardware via your config.h: -```c -#define WS2812_I2C_ADDRESS 0xB0 // default: 0xB0 -#define WS2812_I2C_TIMEOUT 100 // default: 100 -``` - -### SPI -Targeting STM32 boards where WS2812 support is offloaded to an SPI hardware device. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. `WS2812_DI_PIN` for this driver is the configured SPI MOSI pin. Due to the nature of repurposing SPI to drive the LEDs, the other SPI pins, MISO and SCK, **must** remain unused. To configure it, add this to your rules.mk: - -```make -WS2812_DRIVER = spi -``` - -Configure the hardware via your config.h: -```c -#define WS2812_SPI SPID1 // default: SPID1 -#define WS2812_SPI_MOSI_PAL_MODE 5 // MOSI pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5 -#define WS2812_SPI_SCK_PIN B3 // Required for F072, may be for others -- SCK pin, see the respective datasheet for the appropriate values for your MCU. default: unspecified -#define WS2812_SPI_SCK_PAL_MODE 5 // SCK pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5 -``` - -You must also turn on the SPI feature in your halconf.h and mcuconf.h - -#### Circular Buffer Mode -Some boards may flicker while in the normal buffer mode. To fix this issue, circular buffer mode may be used to rectify the issue. - -By default, the circular buffer mode is disabled. - -To enable this alternative buffer mode, place this into your `config.h` file: -```c -#define WS2812_SPI_USE_CIRCULAR_BUFFER -``` - -#### Setting baudrate with divisor -To adjust the baudrate at which the SPI peripheral is configured, users will need to derive the target baudrate from the clock tree provided by STM32CubeMX. - -Only divisors of 2, 4, 8, 16, 32, 64, 128 and 256 are supported by hardware. - -| Define | Default | Description | -| -------------------- | ------- | ----------------------------------- | -| `WS2812_SPI_DIVISOR` | `16` | SPI source clock peripheral divisor | - -#### Testing Notes - -While not an exhaustive list, the following table provides the scenarios that have been partially validated: - -| | SPI1 | SPI2 | SPI3 | -| ---- | ------------------------------------------- | --------------------------------------- | --------------------- | -| f072 | ? | B15 :heavy_check_mark: (needs SCK: B13) | N/A | -| f103 | A7 :heavy_check_mark: | B15 :heavy_check_mark: | N/A | -| f303 | A7 :heavy_check_mark: B5 :heavy_check_mark: | B15 :heavy_check_mark: | B5 :heavy_check_mark: | - -*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* - -### PWM - -Targeting STM32 boards where WS2812 support is offloaded to an PWM timer and DMA stream. The advantage is that the use of DMA offloads processing of the WS2812 protocol from the MCU. To configure it, add this to your rules.mk: - -```make -WS2812_DRIVER = pwm -``` - -Configure the hardware via your config.h: -```c -#define WS2812_PWM_DRIVER PWMD2 // default: PWMD2 -#define WS2812_PWM_CHANNEL 2 // default: 2 -#define WS2812_PWM_PAL_MODE 2 // Pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 2 -//#define WS2812_PWM_COMPLEMENTARY_OUTPUT // Define for a complementary timer output (TIMx_CHyN); omit for a normal timer output (TIMx_CHy). -#define WS2812_DMA_STREAM STM32_DMA1_STREAM2 // DMA Stream for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. -#define WS2812_DMA_CHANNEL 2 // DMA Channel for TIMx_UP, see the respective reference manual for the appropriate values for your MCU. -#define WS2812_DMAMUX_ID STM32_DMAMUX1_TIM2_UP // DMAMUX configuration for TIMx_UP -- only required if your MCU has a DMAMUX peripheral, see the respective reference manual for the appropriate values for your MCU. -``` - -Note that using a complementary timer output (TIMx_CHyN) is possible only for advanced-control timers (TIM1, TIM8, TIM20 on STM32), and the `STM32_PWM_USE_ADVANCED` option in mcuconf.h must be set to `TRUE`. Complementary outputs of general-purpose timers are not supported due to ChibiOS limitations. - -You must also turn on the PWM feature in your halconf.h and mcuconf.h - -#### Testing Notes - -While not an exhaustive list, the following table provides the scenarios that have been partially validated: - -| | Status | -| --------- | ------------------ | -| f072 | ? | -| f103 | :heavy_check_mark: | -| f303 | :heavy_check_mark: | -| f401/f411 | :heavy_check_mark: | - -*Other supported ChibiOS boards and/or pins may function, it will be highly chip and configuration dependent.* - -### PIO - -Targeting Raspberry Pi RP2040 boards only where WS2812 support is offloaded to an dedicated PIO implementation. This offloads processing of the WS2812 protocol from the MCU to a dedicated PIO program using DMA transfers. - -To configure it, add this to your rules.mk: - -```make -WS2812_DRIVER = vendor -``` - -Configure the hardware via your config.h: -```c -#define WS2812_PIO_USE_PIO1 // Force the usage of PIO1 peripheral, by default the WS2812 implementation uses the PIO0 peripheral -``` - -The WS2812 PIO programm uses 1 state machine, 6 instructions and one DMA interrupt handler callback. Due to the implementation the time resolution for this drivers is 50ns, any value not specified in this interval will be rounded to the next matching interval. - -### Push Pull and Open Drain Configuration -The default configuration is a push pull on the defined pin. -This can be configured for bitbang, PWM and SPI. - -Note: This only applies to STM32 boards. - - To configure the `WS2812_DI_PIN` to open drain configuration add this to your config.h file: -```c -#define WS2812_EXTERNAL_PULLUP -``` diff --git a/docs/zh-cn/README.md b/docs/zh-cn/README.md deleted file mode 100644 index 93dfbf1eefea..000000000000 --- a/docs/zh-cn/README.md +++ /dev/null @@ -1,42 +0,0 @@ -# Quantum Mechanical Keyboard固件 - - - -## 什么是 QMK 固件? - -QMK (*Quantum Mechanical Keyboard*) 是一个社区维护的用于开发计算机输入设备的开源软件。社区专注像键盘,鼠标,MIDI设备的各种电子输入设备。社区内的核心小组成员维护[QMK固件](https://github.com/qmk/qmk_firmware),[QMK配置器](https://config.qmk.fm)(QMK Configurator),[QMK工具箱](https://github.com/qmk/qmk_toolbox)(QMK Toolbox),[qmk.fm](https://qmk.fm),并与各位社区成员维护这份文档。 - -## 如何入门 - -
- -?> **基础方式** [QMK配置器](zh-cn/newbs_building_firmware_configurator.md)
-用户友好的图形界面工具,无需具备编程知识基础。 - -?> **进阶方式** [基于源代码](zh-cn/newbs.md)
-功能更强大,但门槛较高。 - -
- -## 个性化定制 - -QMK提供了很多功能,对应着很多可供浏览的配套文档。大部分功能都是通过修改[键映射](zh-cn/keymap.md)及[键码](zh-cn/keycodes.md)实现的。 - -## 需要帮助? - -请查阅[寻求帮助页面](zh-cn/support.md)以了解如何获取QMK使用方法的帮助。 - -## 回馈社区 - -有多种回馈社区的方法,最简单的方法是开始使用QMK并向你的朋友们推荐它。 - -* 可以在我们的论坛及聊天室进行互助: - * [/r/olkb](https://www.reddit.com/r/olkb/) - * [Discord服务器](https://discord.gg/Uq7gcHh) -* 点击页面下方的“Edit This Page”,可以对文档提供贡献。 -* [将这份文档翻译为你的语言](zh-cn/translating.md) -* [上报bug](https://github.com/qmk/qmk_firmware/issues/new/choose) -* [发起Pull Request](zh-cn/contributing.md) diff --git a/docs/zh-cn/_summary.md b/docs/zh-cn/_summary.md deleted file mode 100644 index 0fc92e33d3ae..000000000000 --- a/docs/zh-cn/_summary.md +++ /dev/null @@ -1,192 +0,0 @@ - -* 新手教程 - * [介绍](zh-cn/newbs.md) - * [入门](zh-cn/newbs_getting_started.md) - * [构建第一个固件](zh-cn/newbs_building_firmware.md) - * [刷写固件](zh-cn/newbs_flashing.md) - * [寻求帮助](zh-cn/support.md) - * [其它资源](zh-cn/newbs_learn_more_resources.md) - * [QMK大纲](zh-cn/syllabus.md) - -* FAQ - * [常规FAQ](zh-cn/faq_general.md) - * [构建/编译QMK](zh-cn/faq_build.md) - * [QMK问题排查](zh-cn/faq_misc.md) - * [调试QMK](zh-cn/faq_debug.md) - * [键映射FAQ](zh-cn/faq_keymap.md) - * [充分利用AVR的存储空间](zh-cn/squeezing_avr.md) - * [术语表](zh-cn/reference_glossary.md) - -* 配置器(Configurator) - * [总览](zh-cn/newbs_building_firmware_configurator.md) - * [入门](zh-cn/configurator_step_by_step.md) - * [问题排查](zh-cn/configurator_troubleshooting.md) - * [框架](zh-cn/configurator_architecture.md) - * QMK API - * [总览](zh-cn/api_overview.md) - * [API文档](zh-cn/api_docs.md) - * [键盘支持](zh-cn/reference_configurator_support.md) - * [添加默认键映射](zh-cn/configurator_default_keymaps.md) - -* CLI - * [总览](zh-cn/cli.md) - * [配置](zh-cn/cli_configuration.md) - * [命令](zh-cn/cli_commands.md) - * [Tab补全](zh-cn/cli_tab_complete.md) - -* 使用QMK - * 导览 - * [功能定制](zh-cn/custom_quantum_functions.md) - * [利用Zadig安装驱动](zh-cn/driver_installation_zadig.md) - * [极简式制作](zh-cn/easy_maker.md) - * [键映射总览](zh-cn/keymap.md) - * 开发环境 - * [Docker指南](zh-cn/getting_started_docker.md) - * 刷写(Flashing) - * [刷写](zh-cn/flashing.md) - * [刷写ATmega32A (ps2avrgb)](zh-cn/flashing_bootloadhid.md) - * IDE - * [在Eclipse中使用QMK](zh-cn/other_eclipse.md) - * [在VSCode中使用QMK](zh-cn/other_vscode.md) - * Git最佳实践 - * [介绍](zh-cn/newbs_git_best_practices.md) - * [你自己的副本](zh-cn/newbs_git_using_your_master_branch.md) - * [冲突合并](zh-cn/newbs_git_resolving_merge_conflicts.md) - * [基于你的分支修复](zh-cn/newbs_git_resynchronize_a_branch.md) - * 键盘组装 - * [飞线指南](zh-cn/hand_wire.md) - * [ISP刷写指南](zh-cn/isp_flashing_guide.md) - - * 键码入门 - * [键码汇总](zh-cn/keycodes.md) - * [基础键码](zh-cn/keycodes_basic.md) - * [语言特定的键码](zh-cn/reference_keymap_extras.md) - * [修饰键](zh-cn/feature_advanced_keycodes.md) - * [原子键码](zh-cn/quantum_keycodes.md) - * [Magic键码](zh-cn/keycodes_magic.md) - - * 键码进阶 - * [指令](zh-cn/feature_command.md) - * [动态宏](zh-cn/feature_dynamic_macros.md) - * [Grave Escape](zh-cn/feature_grave_esc.md) - * [前导键](zh-cn/feature_leader_key.md) - * [Mod-Tap](zh-cn/mod_tap.md) - * [宏](zh-cn/feature_macros.md) - * [鼠标键](zh-cn/feature_mouse_keys.md) - * [Repeat Key](zh-cn/feature_repeat_key.md) - * [Space Cadet Shift](zh-cn/feature_space_cadet.md) - * [US ANSI上档键值](zh-cn/keycodes_us_ansi_shifted.md) - - * 软件特性 - * [自动Shift](zh-cn/feature_auto_shift.md) - * [组合键](zh-cn/feature_combo.md) - * [防抖API](zh-cn/feature_debounce_type.md) - * [按键锁定](zh-cn/feature_key_lock.md) - * [按键重定义](zh-cn/feature_key_overrides.md) - * [层](zh-cn/feature_layers.md) - * [粘滞键](zh-cn/one_shot_keys.md) - * [光标设备](zh-cn/feature_pointing_device.md) - * [原生HID](zh-cn/feature_rawhid.md) - * [Sequencer](zh-cn/feature_sequencer.md) - * [换手](zh-cn/feature_swap_hands.md) - * [一键多用](zh-cn/feature_tap_dance.md) - * [点按配置](zh-cn/tap_hold.md) - * [Unicode](zh-cn/feature_unicode.md) - * [用户空间](zh-cn/feature_userspace.md) - * [WPM计算](zh-cn/feature_wpm.md) - - * 硬件特性 - * 显示 - * [HD44780 LCD控制器](zh-cn/feature_hd44780.md) - * [ST7565 LCD驱动](zh-cn/feature_st7565.md) - * [OLED驱动](zh-cn/feature_oled_driver.md) - * 灯效 - * [背光](zh-cn/feature_backlight.md) - * [LED矩阵](zh-cn/feature_led_matrix.md) - * [RGB灯光](zh-cn/feature_rgblight.md) - * [RGB矩阵](zh-cn/feature_rgb_matrix.md) - * [音频](zh-cn/feature_audio.md) - * [蓝牙](zh-cn/feature_bluetooth.md) - * [Bootmagic Lite](zh-cn/feature_bootmagic.md) - * [自定义矩阵](zh-cn/custom_matrix.md) - * [Digitizer](zh-cn/feature_digitizer.md) - * [拨动开关(DIP Switch)](zh-cn/feature_dip_switch.md) - * [编码器(旋钮)](zh-cn/feature_encoders.md) - * [触摸反馈](zh-cn/feature_haptic_feedback.md) - * [摇杆](zh-cn/feature_joystick.md) - * [LED指示](zh-cn/feature_led_indicators.md) - * [MIDI](zh-cn/feature_midi.md) - * [Proton C转换](zh-cn/proton_c_conversion.md) - * [PS/2鼠标](zh-cn/feature_ps2_mouse.md) - * [分体式键盘](zh-cn/feature_split_keyboard.md) - * [速记](zh-cn/feature_stenography.md) - * [热敏打印机](zh-cn/feature_thermal_printer.md) - * [Velocikey](zh-cn/feature_velocikey.md) - -* QMK开发 - * [PR Checklist](zh-cn/pr_checklist.md) - * 打破兼容的改动 - * [总览](zh-cn/breaking_changes.md) - * [我的PR已打上标记](zh-cn/breaking_changes_instructions.md) - * [近期的变更日志(Changelog)](zh-cn/ChangeLog/20210529.md "QMK v0.13.0 - 2021 May 29") - * [更早期的不兼容改动](zh-cn/breaking_changes_history.md) - - * C语言开发 - * [ARM调试指引](zh-cn/arm_debugging.md) - * [AVR处理器](zh-cn/hardware_avr.md) - * [C编码规范](zh-cn/coding_conventions_c.md) - * [兼容的微处理器](zh-cn/compatible_microcontrollers.md) - * [驱动](zh-cn/hardware_drivers.md) - * [ADC驱动](zh-cn/adc_driver.md) - * [Audio驱动](zh-cn/audio_driver.md) - * [I2C驱动](zh-cn/i2c_driver.md) - * [SPI驱动](zh-cn/spi_driver.md) - * [WS2812驱动](zh-cn/ws2812_driver.md) - * [EEPROM驱动](zh-cn/eeprom_driver.md) - * [串口驱动](zh-cn/serial_driver.md) - * [UART驱动](zh-cn/uart_driver.md) - * [操控GPIO](zh-cn/gpio_control.md) - * [键盘开发指引](zh-cn/hardware_keyboard_guidelines.md) - - * Python开发 - * [编码规范](zh-cn/coding_conventions_python.md) - * [QMK CLI开发](zh-cn/cli_development.md) - - * 配置器开发 - * QMK API - * [开发环境](zh-cn/api_development_environment.md) - * [架构总览](zh-cn/api_development_overview.md) - - * 硬件平台开发 - * Arm/ChibiOS - * [选择MCU](zh-cn/platformdev_selecting_arm_mcu.md) - * [启动引导](zh-cn/platformdev_chibios_earlyinit.md) - - * QMK参考信息 - * [参与到QMK](zh-cn/contributing.md) - * [翻译QMK文档](zh-cn/translating.md) - * [配置](zh-cn/config_options.md) - * [数据驱动配置](zh-cn/data_driven_config.md) - * [Make指引](zh-cn/getting_started_make_guide.md) - * [编写文档的最佳实践](zh-cn/documentation_best_practices.md) - * [文档模板](zh-cn/documentation_templates.md) - * [贡献配列到社区](zh-cn/feature_layouts.md) - * [单元测试](zh-cn/unit_testing.md) - * [常用函数](zh-cn/ref_functions.md) - * [info.json参考资料](zh-cn/reference_info_json.md) - - * 深入了解 - * [键盘工作原理](zh-cn/how_keyboards_work.md) - * [键盘矩阵原理](zh-cn/how_a_matrix_works.md) - * [了解QMK](zh-cn/understanding_qmk.md) - - * QMK内部细节 (编辑中) - * [定义](zh-cn/internals/defines.md) - * [输入回调的注册](zh-cn/internals/input_callback_reg.md) - * [Midi设备](zh-cn/internals/midi_device.md) - * [Midi设备驱动流程](zh-cn/internals/midi_device_setup_process.md) - * [Midi辅助功能](zh-cn/internals/midi_util.md) - * [发送函数](zh-cn/internals/send_functions.md) - * [Sysex工具](zh-cn/internals/sysex_tools.md) - - diff --git a/docs/zh-cn/api_docs.md b/docs/zh-cn/api_docs.md deleted file mode 100644 index 03ee6ab13e35..000000000000 --- a/docs/zh-cn/api_docs.md +++ /dev/null @@ -1,73 +0,0 @@ -# QMK API - - - -本章节详述了QMK API的使用方法,若您是应用开发者,使用这套API可以实现[QMK](https://qmk.fm)键盘固件的编译支持。 - -## 总览 - -本服务提供了一套用于编译自定义键映射的异步API,通过POST方式发送JSON参数到API,定期检查执行状态,待固件编译完成后,即可下载生成的固件文件和固件的源文件(如果需要的话)。 - -#### 荷载JSON参数示例: - -```json -{ - "keyboard": "clueboard/66/rev2", - "keymap": "my_awesome_keymap", - "layout": "LAYOUT_all", - "layers": [ - ["KC_GRV","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_GRV","KC_BSPC","KC_PGUP","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_PGDN","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_NUHS","KC_ENT","KC_LSFT","KC_NUBS","KC_Z","KC_X","KC_C","KC_V","KC_B","KC_N","KC_M","KC_COMM","KC_DOT","KC_SLSH","KC_RO","KC_RSFT","KC_UP","KC_LCTL","KC_LGUI","KC_LALT","KC_MHEN","KC_SPC","KC_SPC","KC_HENK","KC_RALT","KC_RCTL","MO(1)","KC_LEFT","KC_DOWN","KC_RIGHT"], - ["KC_ESC","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_TRNS","KC_DEL","BL_STEP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","_______","KC_TRNS","KC_PSCR","KC_SCRL","KC_PAUS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_PGUP","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_LEFT","KC_PGDN","KC_RGHT"], - ["KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","QK_BOOT","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(2)","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","KC_TRNS","MO(1)","KC_TRNS","KC_TRNS","KC_TRNS"] - ] -} -``` - -如上可见,荷载参数里有用于生成固件文件的所有键盘信息。每一个层定义都包含了与键盘 `LAYOUT` 宏定义一致的QMK键码列表数据,若该键盘有多个支持的 `LAYOUT` 宏定义,也可以指定使用的是哪一个。 - -## 提交一个编译job - -若要将键映射配置编译成固件文件,仅需将JSON参数通过POST发送至 `/v1/compile` 节点。下面的示例中我们假设JSON荷载参数已存放在 `json_data` 文件中。 - -``` -$ curl -H "Content-Type: application/json" -X POST -d "$(< json_data)" https://api.qmk.fm/v1/compile -{ - "enqueued": true, - "job_id": "ea1514b3-bdfc-4a7b-9b5c-08752684f7f6" -} -``` - -## 检查状态 - -键映射配置提交后,可以简单地通过 HTTP GET 请求来查询job状态: - -``` -$ curl https://api.qmk.fm/v1/compile/ea1514b3-bdfc-4a7b-9b5c-08752684f7f6 -{ - "created_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "enqueued_at": "Sat, 19 Aug 2017 21:39:12 GMT", - "id": "f5f9b992-73b4-479b-8236-df1deb37c163", - "status": "running", - "result": null -} -``` - -这份信息告诉我们编译job已经提交到队列中且正在执行。job的状态有5种: - -* **failed(失败)**: 编译服务出现问题。 -* **finished(完成)**: 编译已完成,`result` 字段中保存了编译结果。 -* **queued(排队中)**: 键映射job在等待可用的编译服务器。 -* **running(执行中)**: 编译进行中,应当很快就会结束。 -* **unknown(未知)**: 出现了较严重的错误,请给我们[提交一个bug](https://github.com/qmk/qmk_compiler/issues). - -## 确认编译产出 - -编译job完成后请查看 `result` 字段,该字段下保存了如下信息项的哈希表数据: - -* `firmware_binary_url`: 用于刷写的固件文件URL列表 -* `firmware_keymap_url`: `keymap.c` 文件URL列表 -* `firmware_source_url`: 完整的固件源代码URL列表 -* `output`: 编译job的stdout及stderr输出信息,所有错误信息都会在这里。 diff --git a/docs/zh-cn/api_overview.md b/docs/zh-cn/api_overview.md deleted file mode 100644 index a07cfb742738..000000000000 --- a/docs/zh-cn/api_overview.md +++ /dev/null @@ -1,20 +0,0 @@ -# QMK API - - - -QMK API提供了一套可用于Web及GUI工具可用的异步API,用于实现将任何[QMK](https://qmk.fm/)支持的键盘的键映射方案进行编译。已有的键映射模板支持所有的QMK键码并且不需要额外的C代码需求。键盘的维护团队可以提供新的模板来启用更多功能的支持。 - -## App开发者 - -若您是一位意愿将这套API引入您的程序中的移动端App开发者,请参阅[API使用指引](zh-cn/api_docs.md)。 - -## 键盘维护团队 - -若您希望强化您维护的键盘方案在QMK编译API中的支持,请参阅[键盘支持](zh-cn/reference_configurator_support.md)。 - -## 后端开发者 - -若您对这套API系统本身感兴趣,请参阅[开发环境](zh-cn/api_development_environment.md)搭建环境并继续深入探索[架构总览](zh-cn/api_development_overview.md)。 diff --git a/docs/zh-cn/cli.md b/docs/zh-cn/cli.md deleted file mode 100644 index 22c2db92c85b..000000000000 --- a/docs/zh-cn/cli.md +++ /dev/null @@ -1,43 +0,0 @@ -# QMK CLI :id=qmk-cli - - - -## 总览 :id=overview - -QMK CLI可以让构建QMK键盘的过程更轻松一些,我们已提供的一批指令可用于简化及流式化地处理一些常见工作,如获取并编译QMK固件,创建新的键映射等。 - -### 依赖项 :id=requirements - -QMK依赖Python 3.6或更高版本。我们已经尽力缩减依赖项,但在[`requirements.txt`](https://github.com/qmk/qmk_firmware/blob/master/requirements.txt)中的依赖项是需安装的包。在安装QMK CLI时这些依赖项也会自动完成安装。 - -### 通过 Homebrew 安装(macOS 及部分 Linux) :id=install-using-homebrew - -若已安装[Homebrew](https://brew.sh),可以按如下方法安装QMK: - -``` -brew install qmk/qmk/qmk -export QMK_HOME='~/qmk_firmware' # 可选,指定 `qmk_firmware` 的路径 -qmk setup # 拉取 `qmk/qmk_firmware` 并选择性地配置构建环境 -``` - -### 通过 pip 安装 :id=install-using-easy_install-or-pip - -未在以上列出的操作系统可以手动安装QMK。首先确认已安装Python 3.6(或更高版本)及 pip,然后通过如下指令安装QMK: - -``` -python3 -m pip install qmk -export QMK_HOME='~/qmk_firmware' # 可选,指定 `qmk_firmware` 的路径 -qmk setup # 拉取 `qmk/qmk_firmware` 并选择性地配置构建环境 -``` - -### 其它操作系统的安装包 :id=packaging-for-other-operating-systems - -我们正在寻求可以制作维护更多操作系统下可用的 `qmk` 安装包的开发者,若您愿意为您的操作系统制作安装包,请遵循如下指引: - -* 当该系统下的最佳实践与本指引冲突时,请遵循系统的最佳实践方案 - * 但请在注释中列明此处违反这份指引的原因 -* 在 virtualenv 下安装 -* 指引用户去设置 `QMK_HOME` 环境变量,使得固件源文件拉取路径不再是默认的 `~/qmk_firmware` diff --git a/docs/zh-cn/cli_commands.md b/docs/zh-cn/cli_commands.md deleted file mode 100644 index ed36ed975bbc..000000000000 --- a/docs/zh-cn/cli_commands.md +++ /dev/null @@ -1,503 +0,0 @@ -# QMK CLI 命令 - - - -# 用户命令 - -## `qmk compile` - -该命令用于在指定目录下编译固件,可用于构建导出的JSON数据,代码库中的键映射,或是当前目录下的键盘。 - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**用于配置器导出的数据时**: - -``` -qmk compile [-c] -``` - -**用于键映射时**: - -``` -qmk compile [-c] [-e =] [-j ] -kb -km -``` - -**在键盘目录下时**: - -须在存在默认键映射的键盘目录下执行,或是在键盘的键映射子目录下,否则须指定参数 `--keymap ` -``` -qmk compile -``` - -**构建所有支持该键映射的键盘时**: - -``` -qmk compile -kb all -km -``` - -**示例**: -``` -$ qmk config compile.keymap=default -$ cd ~/qmk_firmware/keyboards/planck/rev6 -$ qmk compile -Ψ Compiling keymap with make planck/rev6:default -... -``` -指定键映射参数时 - -``` -$ cd ~/qmk_firmware/keyboards/clueboard/66/rev4 -$ qmk compile -km 66_iso -Ψ Compiling keymap with make clueboard/66/rev4:66_iso -... -``` -位于键盘目录下时 - -``` -$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak -$ qmk compile -Ψ Compiling keymap with make gh60/satan:colemak -... -``` - -**在配列目录下时**: - -必须是在 `qmk_firmware/layouts/` 下的键映射目录下。 -``` -qmk compile -kb -``` - -**示例**: -``` -$ cd ~/qmk_firmware/layouts/community/60_ansi/mechmerlin-ansi -$ qmk compile -kb dz60 -Ψ Compiling keymap with make dz60:mechmerlin-ansi -... -``` - -**并行编译**: - -在编译时添加 `-j`/`--parallel` 开关可能有助于加快编译速度。 -``` -qmk compile -j -kb -``` -`num_jobs` 用于指定并行的job上限,将其设置为0可以实现无限制的并行编译。 -``` -qmk compile -j 0 -kb -``` - -## `qmk flash` :id=qmk-flash - -该命令与 `qmk compile` 类似,但额外地可以指定bootloader。bootloader参数是可选的,默认会指定为 `:flash`。可通过 `-bl ` 来指定bootloader。请查阅[刷写固件](zh-cn/flashing.md)指引以深入了解可用的bootloader信息。 - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**用于配置器导出的数据时**: - -``` -qmk flash [-bl ] [-c] [-e =] [-j ] -``` - -**用于键映射时**: - -``` -qmk flash -kb -km [-bl ] [-c] [-e =] [-j ] -``` - -**列出所有bootloader** - -``` -qmk flash -b -``` - -## `qmk config` - -该命令用于配置QMK功能,完整的 `qmk config` 文档参见[CLI配置](zh-cn/cli_configuration.md)。 - -**使用方法**: - -``` -qmk config [-ro] [config_token1] [config_token2] [...] [config_tokenN] -``` - -## `qmk cd` - -该命令会启动一个新的 shell 会话并定位到 `qmk_firmware` 所在目录。 - -须留意如果你已经位于 `QMK_HOME` 下的某个位置(比如 `keyboards/` 目录中),该指令不会生效。 - -若要退回到原来的 shell 会话,只需要执行 `exit`。 - -**使用方法**: - -``` -qmk cd -``` - -## `qmk console` - -该命令用于连接键盘终端并展示调试信息。仅当键盘固件通过 `CONSOLE_ENABLE=yes` 编译时有效。 - -**用法**: - -``` -qmk console [-d :[:]] [-l] [-n] [-t] [-w ] -``` - -**示例**: - -连接到所有可用的键盘并输出终端信息: - -``` -qmk console -``` - -列出所有设备: - -``` -qmk console -l -``` - -仅输出 clueboard/66/rev3 键盘的信息: - -``` -qmk console -d C1ED:2370 -``` - -仅输出第二把 clueboard/66/rev3 键盘的信息: - -``` -qmk console -d C1ED:2370:2 -``` - -输出时间戳及VID:PID以替代键盘名: - -``` -qmk console -n -t -``` - -屏蔽bootloader的消息: - -``` -qmk console --no-bootloaders -``` - -## `qmk doctor` - -该命令用以检查你的开发环境并对发现的潜在的构建及刷写问题进行提醒,如果您乐意,它也可以修复其中大部分问题。 - -**用法**: - -``` -qmk doctor [-y] [-n] -``` - -**示例**: - -检查开发环境中的问题并提示是否修复: - - qmk doctor - -检查开发环境中的问题并自动进行修复: - - qmk doctor -y - -检查开发环境中的问题,仅生成报告: - - qmk doctor -n - -## `qmk format-json` - -将JSON文件格式化为(尽量)便于阅读的形式。会自动分辨JSON结构类型(info.json还是keymap.json),必要时也可以通过 `--format` 指定。 - -**用法**: - -``` -qmk format-json [-f FORMAT] -``` - -## `qmk info` - -展示QMK中的键盘及键映射信息,该命令用来获取键盘信息,输出配列,展示底层按键矩阵,及格式化地输出键映射JSON数据。 - -**用法**: - -``` -qmk info [-f FORMAT] [-m] [-l] [-km KEYMAP] [-kb KEYBOARD] -``` - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**示例**: - -输出键盘的基础信息: - - qmk info -kb planck/rev5 - -输出键盘的矩阵信息: - - qmk info -kb ergodox_ez -m - -输出键盘的键映射JSON数据: - - qmk info -kb clueboard/california -km default - -## `qmk json2c` - -从QMK配置器导出的数据中生成 keymap.c 文件 -Creates a keymap.c from a QMK Configurator export. - -**用法**: - -``` -qmk json2c [-o OUTPUT] filename -``` - -## `qmk c2json` - -从 keymap.c 文件中生成 keymap.json -**注意:** 解析C代码文件并不容易,该命令有可能无法对你的键映射文件生效,不使用C预处理代码有时可以解决问题。 - -**用法**: - -``` -qmk c2json -km KEYMAP -kb KEYBOARD [-q] [--no-cpp] [-o OUTPUT] filename -``` - -## `qmk lint` - -检查键盘及键映射数据并提示出常见错误与问题,以及不符合模板规范的地方。 - -**用法**: - -``` -qmk lint [-km KEYMAP] [-kb KEYBOARD] [--strict] -``` - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**示例**: - -基本的lint检查: - - qmk lint -kb rominronin/katana60/rev2 - -## `qmk list-keyboards` - -该命令可以列出 `qmk_firmware` 中所有的键盘 - -**用法**: - -``` -qmk list-keyboards -``` - -## `qmk list-keymaps` - -该命令可以列出指定键盘(及指定版本)下的所有键映射。 - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**用法**: - -``` -qmk list-keymaps -kb planck/ez -``` - -## `qmk new-keyboard` - -该命令可基于现有模板创建出新的键盘定义。 - -对于未给出的参数,会提示你输入,若未传入 `-u` 参数且 .gitconfig 中设置了 `user.name`,则会提示你使用该值作为默认用户名。 - -**用法**: - -``` -qmk new-keyboard [-kb KEYBOARD] [-t {avr,ps2avrgb}] -u USERNAME -``` - -## `qmk new-keymap` - -该命令可基于键盘已有的默认键映射创建新的键映射。 - -该命令会尝试感知目录路径,当你在键盘或键映射目录下执行时,KEYBOARD及KEYMAP参数将被自动填入。 - -**用法**: - -``` -qmk new-keymap [-kb KEYBOARD] [-km KEYMAP] -``` - -## `qmk clean` - -该命令会清理 `.build` 目录,若传入 `--all` 开关,在 `qmk_firmware` 下的所有.hex及.bin文件也会一并删除。 - -**用法**: - -``` -qmk clean [-a] -``` - ---- - -# 面向开发者的命令 - -## `qmk format-text` - -该命令会重新格式化并统一文件的换行符。 - -代码库下所有的文件须使用Unix换行符(LF)。 -若你在**Windows**下进行开发,必须确保文件中的换行符是正确的,才能让你的PR被允许合入。 - -``` -qmk format-text -``` - -## `qmk format-c` - -该命令会使用clang-format来格式化C代码。 - -不带参数地执行该命令以用来格式化核心代码相关的改动,默认会通过 `git diff` 来检查 `origin/master`, 可以通过 `-b <分支名>` 来改变检查的分支。 - -带着 `-a` 开关执行命令会格式化所有的核心代码,也可以在命令行中传入文件名来指定格式化某个文件。 - -**用以处理指定文件时**: - -``` -qmk format-c [file1] [file2] [...] [fileN] -``` - -**用以处理所有的核心代码时**: - -``` -qmk format-c -a -``` - -**用以处理 origin/master 下的所有改动时**: - -``` -qmk format-c -``` - -**用以处理指定分支下的所有改动时**: - -``` -qmk format-c -b branch_name -``` - -## `qmk generate-compilation-database` - -**用法**: - -``` -qmk generate-compilation-database [-kb KEYBOARD] [-km KEYMAP] -``` - -创建新 `compile_commands.json` 文件。 - -你的IDE/编辑器是否使用了“编程语言本地服务器”(language server)且 _总是_ 无法找到全部的包含文件(include files)?是不是很讨厌红色的波浪线?想不想让你的编辑器看得懂 `#include QMK_KEYBOARD_H`?你需要的是一个[编译数据库](https://clang.llvm.org/docs/JSONCompilationDatabase.html)!而 QMK 可以帮助你构建出一个。 - -该命令需要知道你在构建的是哪个键盘及键映射,它使用与 `qmk compile` 命令一样的选项:参数、当前目录以及配置文件。 - -**示例:** - -``` -$ cd ~/qmk_firmware/keyboards/gh60/satan/keymaps/colemak -$ qmk generate-compilation-database -Ψ Making clean -Ψ Gathering build instructions from make -n gh60/satan:colemak -Ψ Found 50 compile commands -Ψ Writing build database to /Users/you/src/qmk_firmware/compile_commands.json -``` - -现在可以打开你的开发环境并享受没有波浪线的日子了。 - -## `qmk docs` - -该命令会在本地启动一个HTTP服务,从而你可以浏览及改进文档,默认端口号为8936,使用 `-b`/`--browser` 开关可以让该命令自动通过默认浏览器打开链接地址。 - -**用法**: - -``` -qmk docs [-b] [-p PORT] -``` - -## `qmk generate-docs` - -该命令可以在本地生成QMK文档,用以文档的常规浏览使用,或进行文档改进工作。可以使用类似[serve](https://www.npmjs.com/package/serve)这样的工具来浏览生成的文档文件。 - -**用法**: - -``` -qmk generate-docs -``` - -## `qmk generate-rgb-breathe-table` - -该命令可以生成用于[RGB灯光](zh-cn/feature_rgblight.md)的呼吸效果的查询表(LUT)头文件。将该文件命名为 `rgblight_breathe_table.h` 并放入键盘或键映射目录下,可以覆盖替换 `quantum/rgblight/` 下的默认LUT。 - -**用法**: - -``` -qmk generate-rgb-breathe-table [-q] [-o OUTPUT] [-m MAX] [-c CENTER] -``` - -## `qmk kle2json` - -该命令可以将KLE原始数据转换成QMK配置器的JSON数据,可接受的输入可以是文件绝对路径,或当前目录下的文件名。若 `info.json` 文件存在,默认不会进行覆盖,通过指定 `-f` 或 `--force` 开关可以允许覆盖。 - -**用法**: - -``` -qmk kle2json [-f] -``` - -**示例**: - -``` -$ qmk kle2json kle.txt -☒ File info.json already exists, use -f or --force to overwrite. -``` - -``` -$ qmk kle2json -f kle.txt -f -Ψ Wrote out to info.json -``` - -## `qmk format-python` - -该命令可以对 `qmk_firmware` 下的python代码进行格式化。 - -**用法**: - -``` -qmk format-python -``` - -## `qmk pytest` - -该命令会执行python测试框架,在你更改了python代码后,应确保该命令可以成功执行。 - -**用法**: - -``` -qmk pytest -``` - -**示例**: - -执行全部的测试套件: - - qmk pytest - -执行指定的测试用例组: - - qmk pytest -t qmk.tests.test_cli_commands - -执行单个测试用例: - - qmk pytest -t qmk.tests.test_cli_commands.test_c2json - qmk pytest -t qmk.tests.test_qmk_path diff --git a/docs/zh-cn/cli_configuration.md b/docs/zh-cn/cli_configuration.md deleted file mode 100644 index d3bca4a33836..000000000000 --- a/docs/zh-cn/cli_configuration.md +++ /dev/null @@ -1,126 +0,0 @@ -# QMK CLI 配置 - - - -本文详述了 `qmk config` 功能及作用。 - -# 介绍 - -QMK CLI的配置系统是一套键/值(key/value)数据系统,每个键由一个子指令和一个参数名组成,通过点号(英文句号)分隔。这使得配置项可以简单直接地映射到命令行参数上。 - -## 简单示例 - -作为一个示例,对于指令 `qmk compile --keyboard clueboard/66/rev4 --keymap default` - -其存在两个命令行参数,可以通过如下方式从配置中读取: - -* `compile.keyboard` -* `compile.keymap` - -可以这样设置: - -``` -$ qmk config compile.keyboard=clueboard/66/rev4 compile.keymap=default -compile.keyboard: None -> clueboard/66/rev4 -compile.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -现在每次执行 `qmk compile` 时都不需要指定键盘及键映射参数了。 - -## 设置用户级的默认配置 - -当你需要在多个命令中使用一致的配置项时,比如很多命令都需要的 `--keyboard` 参数,相比于每次执行命令都去指定该参数值,你可以直接设置用户级的配置值,即可将该配置用于所有的命令。 - -示例: - -``` -$ qmk config user.keyboard=clueboard/66/rev4 user.keymap=default -user.keyboard: None -> clueboard/66/rev4 -user.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# CLI文档 (`qmk config`) - -`qmk config` 命令可以管理配置数据。当不带额外参数执行时,会输出所有已有配置。存在参数时这些参数将被视为配置项参数,其格式须满足如下形式且无空格分隔: - - [.][=] - -## 设置配置值 - -在配置项的键后加 = 号进行值的设置,配置项的键必须是 `
.` 的完整形式。 - -举例: - -``` -$ qmk config default.keymap=default -default.keymap: None -> default -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## 读取配置值 - -可以读取整个配置文件、单独配置键或是一整个配置系列,也可以同时指定读取多个配置项。 - -### 全量配置读取示例 - - qmk config - -### 单系列配置读取示例 - - qmk config compile - -### 单配置项读取示例 - - qmk config compile.keyboard - -### 多配置项读取示例 - - qmk config user compile.keyboard compile.keymap - -## 删除配置值 - -将配置值设置为 `None` 即可删除该配置值。 - -示例: - -``` -$ qmk config default.keymap=None -default.keymap: default -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -## 批量操作 - -一个指令中可以合并执行多个读写操作,将依序进行执行输出: - -``` -$ qmk config compile default.keymap=default compile.keymap=None -compile.keymap=skully -compile.keyboard=clueboard/66_hotswap/gen1 -default.keymap: None -> default -compile.keymap: skully -> None -Ψ Wrote configuration to '/Users/example/Library/Application Support/qmk/qmk.ini' -``` - -# 用户配置相关的配置项 - -| 配置项 | 默认值 | 描述 | -|-------|-------|------| -| user.keyboard | None | 键盘路径(举例:`clueboard/66/rev4`) | -| user.keymap | None | 键盘名称(举例:`default`) | -| user.name | None | 用户的Github用户名 | - -# 所有配置项 - -| 配置项 | 默认值 | 描述 | -|-------|-------|------| -| compile.keyboard | None | 键盘路径(举例:`clueboard/66/rev4`) | -| compile.keymap | None | 键盘名称(举例:`default`) | -| hello.name | None | 执行时展示的欢迎信息 | -| new_keyboard.keyboard | None | 键盘路径(举例:`clueboard/66/rev4`) | -| new_keyboard.keymap | None | 键盘名称(举例:`default`) | diff --git a/docs/zh-cn/cli_tab_complete.md b/docs/zh-cn/cli_tab_complete.md deleted file mode 100644 index 7a16e9766c8d..000000000000 --- a/docs/zh-cn/cli_tab_complete.md +++ /dev/null @@ -1,32 +0,0 @@ -# QMK Tab补全 - - - -在使用Bash 4.2及更高版本、Zsh或FiSH时,可以启用QMK CLI的Tab补全功能,可以实现对 `qmk` 参数中的开关、键盘、文件等参数的自动补全。 - -## 设置 - -有以下几种启用Tab补全的方法。 - -### 仅当前用户生效 - -将以下内容添加到文件 `.profile` 或 `.bashrc` 的末尾: - - source ~/qmk_firmware/util/qmk_tab_complete.sh - -若你的 `qmk_firmware` 存放在其它路径,以上路径也需要调整。 - -### 系统级的符号关联 - -若想让所有本地用户都可以实现Tab补全,可以按如下方法添加符号连接到 `qmk_tab_complete.sh` 脚本: - - `ln -s ~/qmk_firmware/util/qmk_tab_complete.sh /etc/profile.d/qmk_tab_complete.sh` - -### 系统级的脚本拷贝 - -有时符号连接的方案无效,可以改用拷贝文件到指定位置的方案。但须留意该Tab补全脚本可能会不定时更新,你需要定期重新拷贝一次该脚本。 - - cp util/qmk_tab_complete.sh /etc/profile.d diff --git a/docs/zh-cn/configurator_architecture.md b/docs/zh-cn/configurator_architecture.md deleted file mode 100644 index 386ebd6899c8..000000000000 --- a/docs/zh-cn/configurator_architecture.md +++ /dev/null @@ -1,66 +0,0 @@ -# QMK配置器框架 - - - -本章节提供了QMK配置器前端技术框架信息,若你对QMK配置器前端工程本身感兴趣,可以从[QMK配置器](https://github.com/qmk/qmk_configurator)代码库开始。 - -# 总览 - -![QMK配置器技术框架图](./../configurator_diagram.svg) - -# 详述 - -QMK配置器基于[单页面框架](https://en.wikipedia.org/wiki/Single-page_application)实现,供使用者创建兼容QMK键盘的自定义键映射方案。键映射方案可以导出为JSON格式的数据,也可以编译出可通过[QMK工具箱](https://github.com/qmk/qmk_toolbox)刷写到键盘中的固件文件。 - -配置器从“键盘元数据仓库(Keyboard Metadata store)”获取键盘元数据,编译请求通过QMK API提交,编译产出放在S3兼容的数据仓库[Digital Ocean空间](https://www.digitalocean.com/products/spaces/)中。 - -## 配置器前端 - -地址: - -[配置器前端](https://config.qmk.fm)会编译并产出一些静态文件并通过Github Pages托管,每当[QMK配置器 `master`](https://github.com/qmk/qmk_configurator)分支收到推送的提交时都会触发。可以通过[QMK配置器 actions页面](https://github.com/qmk/qmk_configurator/actions/workflows/build.yml)查看这些job的状态。 - -## 键盘元数据 - -地址: - -每当[qmk_firmware](https://github.com/qmk/qmk_firmware)仓库中的键盘定义变化时,会生成JSON格式的键盘元数据,并上传到指定空间用于配置器生成每种键盘的UI展现。可以在[QMK固件 actions页面](https://github.com/qmk/qmk_firmware/actions/workflows/api.yml)查看相关job的状态。如果你是QMK开发团队成员(Collaborator),可以使用 `workflow_dispatch` 事件触发器来手动执行该job。 - -## QMK API - -地址: - -QMK API接受 `keymap.json` 文件输入并进行编译,这和你在 `qmk compile` 和 `qmk flash` 中使用的文件一样。当 `keymap.json` 文件被提交后,浏览器中的页面将定时查看job状态(每2秒一次,有时更久一些)直到job完成。最终产出的JSON描述信息里包含了键映射方案的源文件,及编译出的二进制的可下载链接地址。 - -为遵循GPL协议,QMK API会确保源文件及编译产出总是同时提供的。 - -API有3种非异常的回应状态- - -1. 编译job排队中 -2. 编译job执行中 -3. 编译job已完成 - -### 编译job排队中 - -此状态表明[QMK编译器](#QMK编译器)节点还未选中该job,在配置器页面此时会显示“等待一个可用的烤炉(Waiting for an oven)”。 - -### 编译job执行中 - -此状态说明编译job已经在执行中,配置器页面会显示为“烤制中”(Baking)。 - -### 编译job已完成 - -此状态说明编译job已经执行完毕,输出的JSON格式的状态信息里有源文件及编译产出的二进制文件的下载链接项。 - -## Redis/RQ - -QMK API通过Redis队列分发job到可用的[QMK编译器](#QMK编译器)节点。接收到的 `keymap.json` 文件先送到RQ队列,而 `qmk_compiler` 节点则从中拉取执行。 - -## QMK编译器 - -[QMK编译器](https://github.com/qmk/qmk_compiler)负责执行 `keymap.json` 文件的实际编译工作。它的工作逻辑是先拉取有请求的 `qmk_firmware` 分支代码,执行 `qmk compile keymap.json`,最后上传源文件及二进制产出到Digital Ocean空间中。 - -当用户需要下载源代码/二进制文件时,API会给出重定向后的已鉴权地址链接。 diff --git a/docs/zh-cn/configurator_default_keymaps.md b/docs/zh-cn/configurator_default_keymaps.md deleted file mode 100644 index 9f990286f245..000000000000 --- a/docs/zh-cn/configurator_default_keymaps.md +++ /dev/null @@ -1,198 +0,0 @@ -# 向QMK配置器中添加默认键映射 :id=adding-default-keymaps - - - -本章节描述了如何向QMK配置器中添加一款键盘的默认键映射 - - -## 技术信息 :id=technical-information - -QMK配置器使用JSON作为键映射的本地文件格式。我们尽力确保其行为与在 `qmk_firmware` 中 执行 `make :default` 时一致。 - -该目录下的键映射需要定义四个键值对: - -* `keyboard` (字符串) - * 键盘名称,与执行 `make` 进行编译时使用的一致(如 `make 1upkeyboards/1up60rgb:default`)。 -* `keymap` (字符串) - * 应设置为 `default`. -* `layout` (字符串) - * 默认键映射应使用的配列宏定义。 -* `layers` (数组) - * 键映射数据。此键下的每行元素对应一个层定义,层定义中包含该层的键码组成信息。 - -额外地,大部分键映射中还有一个 `commit` 项,该项并不是QMK配置器后端服务API所需,而是用于告知配置器维护者这份JSON键映射数据来源于代码库中的哪个版本的键映射。该值为 `qmk_firmware` 代码库中最后一次修改键盘默认 `keymap.c` 文件提交的commit的SHA标记。该SHA值的获取方式是拉取[`qmk/qmk_firmware` 库的 `master`分支](https://github.com/qmk/qmk_firmware/tree/master/)后,执行 `git log -1 --pretty=oneline -- keyboards//keymaps/default/keymap.c`(若键盘有什么问题且存在 `keymap.json` 文件,则用之作为替代),执行结果应类似于: - -``` -f14629ed1cd7c7ec9089604d64f29a99981558e8 Remove/migrate action_get_macro()s from default keymaps (#5625) -``` - -本例中,`f14629ed1cd7c7ec9089604d64f29a99981558e8` 即应为 `commit` 的值。 - - -## 示例 :id=example - -若某人想添加H87a Hineybush键盘的默认键映射方案,应到 `qmk_firmware` 下H87a的默认键映射下执行上述 `git log` 命令: - -``` -user ~/qmk_firmware (master) -$ git log -1 --pretty=oneline master -- keyboards/hineybush/h87a/keymaps/default/keymap.c -ef8878fba5d3786e3f9c66436da63a560cd36ac9 Hineybush h87a lock indicators (#8237) -``` - -在我们获取了commit哈希值后,还需要键映射定义(为加强可读性进行了编辑处理): - -```c -... -#include QMK_KEYBOARD_H - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - - [0] = LAYOUT_all( - KC_ESC, 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_PSCR, KC_SCRL, KC_PAUS, - KC_GRV, 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_INS, KC_HOME, KC_PGUP, - 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_END, KC_PGDN, - 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_NUHS, KC_ENT, - KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_TRNS, KC_UP, - KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, MO(1), KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), - - [1] = LAYOUT_all( - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, BL_TOGG, BL_DEC, BL_INC, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_VOLU, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, QK_BOOT, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_MPLY, KC_MNXT, KC_VOLD, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, - KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), - -}; -``` - -默认键映射使用了 `LAYOUT_all` 宏,最后其会成为 `layout` 项的值。编译为QMK配置器的JSON键映射数据后,输出文件应为: - -```json -{ - "keyboard": "hineybush/h87a", - "keymap": "default", - "commit": "ef8878fba5d3786e3f9c66436da63a560cd36ac9", - "layout": "LAYOUT_all", - "layers": [ - [ - "KC_ESC", "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_PSCR", "KC_SCRL", "KC_PAUS", - "KC_GRV", "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_INS", "KC_HOME", "KC_PGUP", - "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_END", "KC_PGDN", - "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_NUHS", "KC_ENT", - "KC_LSFT", "KC_NUBS", "KC_Z", "KC_X", "KC_C", "KC_V", "KC_B", "KC_N", "KC_M", "KC_COMM", "KC_DOT", "KC_SLSH", "KC_RSFT", "KC_TRNS", "KC_UP", - "KC_LCTL", "KC_LGUI", "KC_LALT", "KC_SPC", "KC_RALT", "MO(1)", "KC_RGUI", "KC_RCTL", "KC_LEFT", "KC_DOWN", "KC_RGHT" - ], - [ - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "RGB_TOG", "RGB_MOD", "RGB_HUD", "RGB_HUI", "RGB_SAD", "RGB_SAI", "RGB_VAD", "RGB_VAI", "BL_TOGG", "BL_DEC", "BL_INC", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_VOLU", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "QK_BOOT", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_MPLY", "KC_MNXT", "KC_VOLD", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", - "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS", "KC_TRNS" - ] - ] -} -``` - -`layers` 数组中的空白区域不影响键映射功能,仅为了方便阅读。 - - -## 附加说明 :id=caveats - -### 层定义只能通过序号进行引用 :id=layer-references - -QMK中常见的一种做法是通过一系列 `#define` 或 `enum` 类型声明来对层定义进行命名: - -```c -enum layer_names { - _BASE, - _MEDIA, - _FN -}; -``` - -对于C代码来讲可行,但对于配置器来讲,你*必须*使用层序号 - 上例中的`MO(_FN)` 应使用 `MO(2)`。 - -### 不支持任何形式的定制化代码 :id=custom-code - -需要在 keymap.c 文件中添加函数代码的功能,如Tap Dance或是Unicode,都*完全*无法在配置器中构建。即便是在 `qmk_firmware` 代码库中在键盘定义中设置了 `TAP_DANCE_ENABLE = yes`,也只会导致*任何*固件构建在配置器中行不通。这是由API及JSON格式的键映射数据同时造成的限制。 - -### 对自定义键码的不完全支持 :id=custom-keycodes - -仅有一个方案可以支持自定义键码:若自定义键码的逻辑实现是在 qmk_firmware 下的键盘定义中完成的,而非在键映射中,那么这个键码*可以*在配置器中使用且*可以*编译运行。(因此,)相对于在 `keymap.c` 中使用如下代码段: - -```c -enum custom_keycodes { - CUSTOM_1 = SAFE_RANGE, - CUSTOM_2, - CUSTOM_3 -}; -... -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case CUSTOM_1: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #1."); - } - return false; - case CUSTOM_2: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #2."); - } - return false; - case CUSTOM_3: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #3."); - } - return false; - } - return true; -}; -``` - -... 请将键码的 `enum` 定义块添加到键盘的头文件(``)中,例如(留意 `enum` 在这里命名为 `keyboard_keycodes`): - -```c -enum keyboard_keycodes { - CUSTOM_1 = SAFE_RANGE, - CUSTOM_2, - CUSTOM_3, - NEW_SAFE_RANGE // 重要! -}; -``` - -... 之后在 `.c` 中的 `process_record_kb()` 代码逻辑应为: - -```c -bool process_record_kb(uint16_t keycode, keyrecord_t *record) { - switch(keycode) { - case CUSTOM_1: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #1."); - } - return false; - case CUSTOM_2: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #2."); - } - return false; - case CUSTOM_3: - if (record->event.pressed) { - SEND_STRING("This is custom keycode #3."); - } - return false; - } - return process_record_user(keycode, record); -}; -``` - -注意最后的 `process_record_user()` 调用,若用户需要添加自定义键码到键映射中,须使用 `NEW_SAFE_RANGE` 替代 `SAFE_RANGE`,而其定义来自于上面键盘层定义中。 - - -## 更多资料 :id=additional-reading - -为了让QMK配置器支持你的键盘,你的键盘定义必须存在于 `qmk_firmware` 代码库的 `master` 分支中。相关操作指引,请参见[在QMK配置器中支持你的键盘](zh-cn/reference_configurator_support.md). diff --git a/docs/zh-cn/configurator_step_by_step.md b/docs/zh-cn/configurator_step_by_step.md deleted file mode 100644 index bbfb71d5a6dd..000000000000 --- a/docs/zh-cn/configurator_step_by_step.md +++ /dev/null @@ -1,63 +0,0 @@ -# QMK 配置器: 入门 - - - -本章节描述了如何使用QMK配置器构建出固件文件的过程。 - -## 第一步:选择键盘 - -从下拉列表中选择一款用于创建键映射的键盘。 - -?> 当键盘有多个版本可选择时,请确保选择正确。 - -因为很重要,这里我再次说一遍: - -!> **请选择正确的版本!** - -如果你的键盘声称是基于QMK的但未在列表中,可能是开发者还未提交给我们,或者提交还未被合并进来。若在[Pull Request](https://github.com/qmk/qmk_firmware/pulls?q=is%3Aopen+is%3Apr+label%3Akeyboard)中没有找到请求支持该键盘的issue,请到[QMK固件](https://github.com/qmk/qmk_firmware/issues)提交一个issue。也有一些基于QMK的键盘是由制造商自己的GitHub账号在维护着,请也确认一下。 - -## 第二部:选择键盘配列 - -选择最适合你要创建的键映射的配列,一些键盘的配列不完整或有问题,后续会逐渐支持。 - -!> 有时会遇到没有特别适合的配列的情况,请选择 `LAYOUT_all`。 - -## 第三步:命名你的键映射 - -如何起名完全取决于你。 - -?> 如果编译时遇到了问题,可能是因为QMK固件代码库中已经有了同名项,可以尝试改一下名字。 - -## 第四步:设计你的键映射 - -以下三种方法可以添加键码: - -1. 拖拽 -2. 点击布局上的空白项,再点击所需的键码 -3. 点击布局上的空白项, 再点击你物理键盘上的按键 - -?> 鼠标在键上悬停时会有一个键码值的提示出现,详细描述信息请参见: - -* [基础键码资料](zh-cn/keycodes_basic.md) -* [进阶键码资料](zh-cn/feature_advanced_keycodes.md) - -!> 如果你选择的配列与物理实机有出入,请将不需要的按键留空。如果不清楚应该用哪个键,例如,你只需要一个退格键,但 `LAYOUT_all` 中有两个退格键,须将两个键都放上一样的键码。 - -## 第五步:保存键映射留待后续修订 - -当你调整完毕键映射方案,或打算以后继续编辑,点击 `导出Keymap JSON文件(Download this QMK Keymap JSON File)` 按钮,当前键映射方案将保存到你的计算机中,之后可以点击 `导入Keymap JSON文件(Upload a QMK Keymap JSON File)` 按钮导入后继续编辑。 - -!> **注意:** 导出的.json文件与 kbfirmware.com 和其它工具软件生成的并不兼容,如果你将导出的数据放到那些工具中,或尝试导入那些工具生成的.json文件,是不可行的。 - -## 第六步:编译固件 - -点击绿色的 `编译(Compile)` 按钮。 - -编译完成后,可以点击绿色的 `固件(Download Firmware)` 下载固件文件。 - -## 下一步:刷写到键盘中 - -参见[刷写固件](zh-cn/newbs_flashing.md). diff --git a/docs/zh-cn/configurator_troubleshooting.md b/docs/zh-cn/configurator_troubleshooting.md deleted file mode 100644 index a48ad1dd7262..000000000000 --- a/docs/zh-cn/configurator_troubleshooting.md +++ /dev/null @@ -1,31 +0,0 @@ -# 配置器问题排查 - - - -## 我的 .json 文件不可用 - -如果该 .json 文件确实是QMK配置器中导出的,恭喜你遇到bug了,请在[QMK配置器](https://github.com/qmk/qmk_configurator/issues)库中提交一个issue。 - -如果不是……那么页面顶部加大加粗的提示让你不要使用其它 .json 文件,你是怎么错过的? - -## 我的配列中有好多空格键,我应该怎么处理? - -如果你是说有三个空格键栏,最好的做法是都放上空格键。这个处理方案也适用于退格键和Shift键。 - -## 用于...的键码是什么? - -参见: - -* [基础键码资料](zh-cn/keycodes_basic.md) -* [进阶键码资料](zh-cn/feature_advanced_keycodes.md) - -## 无法编译 - -请检查键映射中所有的层,确保没有随机(random)键。 - -## Bug及其它问题 - -我们很乐意倾听你的需求及bug报告,请到[QMK配置器](https://github.com/qmk/qmk_configurator/issues)代码库中提交吧。 diff --git a/docs/zh-cn/contributing.md b/docs/zh-cn/contributing.md deleted file mode 100644 index 03d3ea916aee..000000000000 --- a/docs/zh-cn/contributing.md +++ /dev/null @@ -1,175 +0,0 @@ -# 如何做贡献 - - - -👍🎉 首先感谢各位百忙之中抽空阅读本文档,并为我们无私奉献。给您点赞啦! 🎉👍 - -第三方的帮助让QMK获得了成长与进步。我们希望提供一套对贡献者和维护者都感到简便实用的PR(pull request)及贡献流程,因此我们整理出了一些准则,以免你的PR在被接纳前需要大改一番。 - -* [项目概况](#project-overview) -* [代码规范](#coding-conventions) -* [一般教程](#general-guidelines) -* [行为守则对于我来说有何意义?](#what-does-the-code-of-conduct-mean-for-me) - -## 这文章巨长无比不想读啊! 我就想问个问题而已! - -您要是有关于QMK的问题,请在[OLKB Subreddit](https://reddit.com/r/olkb)或者是[Discord](https://discord.gg/Uq7gcHh)上进行提问。 - -请记住: - -* 你的问题也许要过几个小时才会有人回复,请耐心一些。 -* 参与到QMK中的成员都是在无偿地贡献着自己的时间和精力,我们没有受雇于开发QMK或是专职回答你的疑问。 -* 您可以看看下面的教程,可以让您的问题浅显易懂,更容易回答: - * https://opensource.com/life/16/10/how-ask-technical-questions - * http://www.catb.org/esr/faqs/smart-questions.html - -# 项目概况 :id=project-overview - -QMK很大一部分是C语言编写的,小部分特性是C++的。QMK的设计目标是在键盘上的嵌入式处理器中工作,如AVR([LUFA](https://www.fourwalledcubicle.com/LUFA.php))和ARM ([ChibiOS](https://www.chibios.org))。如果您对Arduino很熟悉的话,会发现优缺点也基本是相似的。但无论你之前是否有Arduino使用经验,都不会影响你参与到QMK贡献中来。 - - - -# 我到哪里寻求帮助? - -您要是有问题的话可以 [提出一个issue](https://github.com/qmk/qmk_firmware/issues) 或 [在Discord上交流一下](https://discord.gg/Uq7gcHh). - -# 我怎样才能做出贡献? - -您以前是否没有参与贡献过开源社区,而又想知道如何对QMK提供帮助?这里有一份快速指引! -*译注:对于没有基本编程经验的人,请谨慎考虑这套操作流程,可参考,照着做很容易出问题,社区的语言障碍也会阻碍你对这些步骤的细节进行咨询* - -0. 先注册一个 [GitHub](https://github.com) 账户。 -1. 完整整理出来你要贡献的键映射,或是 [找一个你想解决的问题](https://github.com/qmk/qmk_firmware/issues),或者 [找一个你想添加的特性](https://github.com/qmk/qmk_firmware/issues?q=is%3Aopen+is%3Aissue+label%3Afeature)。 -2. 把关联着问题的仓库fork到你的仓库。这样在`你的GitHub用户名/qmk_firmware` 下就有一个副本啦。 -3. 使用 `git clone https://github.com/你的GitHub用户名/仓库名.git` 命令把仓库同步到你的电脑中。 -4. 您要是想开发一个新特性的话可以先创建一个issue和QMK的维护者讨论一下您要做什么。 -5. 使用 `git checkout -b 此处写分支名字(别用汉字)` 命令来创建一个新分支(branch)用于开发。 -6. 对要解决的问题或要添加的特性进行适当的更改。 -7. 使用 `git add 把改变的文件的目录写这里` 可以添加改变的文件内容到git用于管理工程状态的索引(快照)里。 -8. 使用 `git commit -m "这里写修改的相关信息"` 来描述你做出了什么修改。 -9. 使用 `git push origin 此处写分支名字`来把你的更改同步到GitHub库里(反正不是打篮球那个库里)。 -10. 提交一个[QMK 固件的pull request](https://github.com/qmk/qmk_firmware/pull/new/master)。 -11. 给你的pull request拟一个标题,包括简短的描述和问题或错误代码。比如, 你可以起一个这样的"Added more log outputting to resolve #4352"(最好用英语,毕竟QMK的维护团队成员都是英语语系,有可能会看不懂中文)。 -12. 在描述(description)里面写你做了哪些更改,你的代码里还存在什么问题, 或者你想对QMK维护着询问的问题。你的pull request有点小问题无伤大雅(没有完美的pull request), QMK维护团队会尽力帮您改进的! -13. 维护人员审查代码可能需要一些时间。 -14. 维护人员会通知您要更改什么地方,然后您就按照建议改一改。 -15. 你的pull request合并成功了,恭喜! - -# 代码规范 :id=coding-conventions - -我们的编码风格很容易掌握,如果你有C语言或Python编码经验,跟随我们的编码风格不会有什么困难。 - -* [编码规范 - C](zh-cn/coding_conventions_c.md) -* [编码规范 - Python](zh-cn/coding_conventions_python.md) - -# 基本准则 :id=general-guidelines - -在QMK中存在多种类型的修改需求,因此也会有审查严格性上的差异。请在做出任何修改时留意,你的改动隶属于什么类型。 - -* 将PR(pull request)分成一个个的逻辑单元。 比如,不要一次将两个新特性PR出去。要添加的特性排好队,一个一个来。 -* 提交之前使用 `git diff --check` 做以下检查,不要提交多余的空格 -* 确定你的代码能通过编译 - * 键映射: 确定`make keyboard:your_new_keymap` 不返回错误 - * 键盘: 确定 `make keyboard:all` 不返回错误 - * 核心代码: 确定 `make all` 不返回错误 -* 提交的信息尽量明确。第一行写点简短介绍(每行不多于70个英文字母), 第二行空着,第三行和后面就要写些必要的细节了。最好用英文写,比如: - -``` -Adjust the fronzlebop for the kerpleplork - -The kerpleplork was intermittently failing with error code 23. The root cause was the fronzlebop setting, which causes the kerpleplork to activate every N iterations. - -Limited experimentation on the devices I have available shows that 7 is high enough to avoid confusing the kerpleplork, but I'd like to get some feedback from people with ARM devices to be sure. -``` - -!> **特别留意:** 若你要对其它QMK使用者提交的代码进行功能修改或尝试修复bug,例如非默认的键映射、用户空间和配列部分,须在PR中标记出代码的原始提交者。很多QMK使用者都会对自己提交的代码在不知晓的情况下产生了改动感到困惑和沮丧,无论他的Git及Github经验丰富与否。 - -## 文档 - -对文档进行修正是最简单的参与贡献的一个办法,找到错误放置的文档或是修复不完备的部分很容易!我们也急需能修订文档的贡献者参与进来,所以如果你具备这样的能力但不清楚如何开始,请[看这里](#我怎样才能做出贡献?)! - -文档位于 `qmk_firmware/docs` 目录下,如果你习惯于在web页面中完成工作目标,可以在 https://docs.qmk.fm/ 各文档页面下方点击“Edit this page”在线进行编辑。 - -在文档中附代码案例时, 先观察文档其他地方的命名规范。比如, 将enum类型的定义命名为 `my_layers` 或 `my_keycodes` 的形式可以保持前后一致性: - -```c -enum my_layers { - _FIRST_LAYER, - _SECOND_LAYER -}; - -enum my_keycodes { - FIRST_LAYER = SAFE_RANGE, - SECOND_LAYER -}; -``` - -### 预览文档 :id=previewing-the-documentation - -在发起pull request前,请通过文档预览来检查你的本地更改。可以在 `qmk_firmware/` 目录下执行以下命令来配置文档开发环境: - - qmk docs - -或者,如果你有安装Python 3,可以尝试: - - python3 -m http.server 8936 --directory docs - -然后在本地浏览器打开 `http://localhost:8936/`. - -## 键映射 - -大多数QMK新手都从创建一个自己的键映射 -开始。我们尽力保证键映射规范宽松 (毕竟键映射体现的是个人喜好) 不过我们仍要求须遵守以下准则,以便他人更好地发现并理解你的键映射代码。 - -* 使用这份 [模板](zh-cn/documentation_templates.md) 写一份 `readme.md`。 -* 所有的键映射PR都会被压缩处理(squashed,参见[Github文档](https://docs.github.com/cn/github/collaborating-with-pull-requests/incorporating-changes-from-a-pull-request/about-pull-request-merges)),如果你对commit被压缩很介意,请自行处理 -* 不要把新特性和键映射放在一个PR中。先提交新特性,再通过PR提交键映射 -* 键映射文件夹中不要提交 `Makefile` 文件(已不再使用) -* 更新头文件中的copyrights信息(看 `%YOUR_NAME%` 部分) - -## 键盘 - -QMK的最终归宿是键盘。有些键盘是社区维护的,有一些是制作这些键盘的人维护的。`readme.md` 会告诉你是谁维护了这个键盘,如果你对某个键盘有疑问,可以 [创建一个Issue](https://github.com/qmk/qmk_firmware/issues) 来问一问维护者。 - -我们建议你按下面的来操作: - -* 基于[模板](zh-cn/documentation_templates.md)编写 `readme.md`。 -* commit数量尽量合理,否则你的PR可能会被我们压缩。 -* 不要把新特性和新键盘定义放在一个PR中。先提交新特性,再通过PR提交新键盘定义 -* 用最近一级的父文件夹的名字命名 `.c`/`.h` 文件, 比如 `/keyboards///.[ch]` -* 键盘文件夹就不要放`Makefile`了,这个操作都过时啦 -* 更新文件头部的copyrights(看`%YOUR_NAME%`那) - -## Quantum/TMK 核心 - -在你投入大量精力到新功能开发中之前,请先确保使用了最佳的实现方案。通过阅读[了解QMK](zh-cn/understanding_qmk.md)可以获得对QMK的基本认知,这个文档将带你领略QMK的程序流程,然后你可以和维护团队探讨一下实现你想法的最佳方法的思路,以下渠道都可以: - -* [在Discord中交流](https://discord.gg/Uq7gcHh) -* [建立一个Issue](https://github.com/qmk/qmk_firmware/issues/new) - -新特性和BUG的修复影响所有键盘,开发组也在翻修QMK。所以,在实施重大改动之前一定要讨论一下。如果你在没有事先与维护团队沟通的情况下提交了一个PR,而且你的选择与维护团队的计划方向不符,那你可能要面临大改了。 - -修复BUG或者开发新特性之前看看这个: - -* **默认不启用** - QMK运行的芯片多数内存有限,首要考虑的应是已有的键映射不要被破坏,因此你的功能应当是“可以**启用**”的,而不是“可以禁用”的。如果你觉得该特性应该默认开启或者你能帮助缩减代码,请先和我们沟通一下。 -* **提交之前在本地编译** - 这个简直就是家喻户晓了,但是也确实需要编译啊! 在你发起PR前,请确保任何改动都通过了编译验证。 -* **注意版本和芯片平台兼容性** - 有那么几个键盘有支持不同配置甚至是不同芯片的版本。请确保你开发的特性同时支持AVR和ARM两个平台,或者在不支持的平台自动禁用。 -* **解释你的新特性** - 在`docs/`写个文档, 你可以创建新文档或者写到现有文档中。如果你不把它记录下来,其他人就无法从你的努力中获益。 - -也可以看看以下建议: - -* commit数量尽量合理,否则你的PR可能会被我们压缩。 -* 不要把新键盘定义或新键映射与关键改动放在一个PR中。先提交关键改动。 -* 给你的特性编写[单元测试](zh-cn/unit_testing.md)。 -* 你编辑的文件风格要一致,如果风格不明确或者是混搭风的,请先阅读上方的[代码规范](#coding-conventions)。 - -## 重构 - -为了保持QMK脉络清晰,QMK的深度重构工作已在规划中,并会通过合作者进行相应的修改。如果你有重构的思路或建议请[创建一个issue](https://github.com/qmk/qmk_firmware/issues), 我们很乐意讨论一下QMK可以如何改进。 - -# 行为守则对于我来说有何意义? :id=what-does-the-code-of-conduct-mean-for-me - -我们的[行为守则](https://qmk.fm/coc/) 指出您有责任尊重并礼貌地对待项目中的每个人,无论他们的身份如何。如果你是我们行为守则所描述的不当行为的受害者,我们将站在你这边,尽最大努力对施暴者进行谴责。 diff --git a/docs/zh-cn/custom_quantum_functions.md b/docs/zh-cn/custom_quantum_functions.md deleted file mode 100644 index dba9e7e7c099..000000000000 --- a/docs/zh-cn/custom_quantum_functions.md +++ /dev/null @@ -1,476 +0,0 @@ -# 如何定制化键盘功能 - - - -对于很多人来说对客制化键盘的诉求不只是向电脑输入按下的键。你肯定想实现比简单按键和宏更复杂的功能。QMK支持基于注入点的代码注入,功能重写,另外还可以自定义键盘在不同情况下的行为。 - -本页不要求任何额外的QMK知识基础,但阅读[理解QMK](zh-cn/understanding_qmk.md)将会在更基础的层面帮你理解发生了什么。 - -## 核心/键盘/键映射的概念 :id=a-word-on-core-vs-keyboards-vs-keymap - -QMK基于如下层级组成: - -* Core (`_quantum`) - * Keyboard/Revision (`_kb`) - * Keymap (`_user`) - -该文后续部分所提及的函数在定义时皆可添加 `_kb()` 或 `_user()` 后缀,我们建议在键盘及其子版本中使用 `_kb()` 后缀,而在键映射中使用 `_user()` 后缀。 - -在键盘及其子版本中定义函数时,一个重要的点是在 `_kb()` 函数执行任何逻辑前,应先调用 `_user()` 函数,否则这些键映射中的函数将没有机会被执行。 -# 自定义键码 - -到目前为止,最常见的任务是更改现有键码的行为或创建新的键码。从代码角度来看这些操作都很相似。 - -## 定义一个新键码 - -创建键码的第一步,是先定义其枚举值,也就是给键码起个名字并分配一个唯一值。QMK没有直接限制最大可用的键码值,而是提供了一个 `SAFE_RANGE` 宏。你可以在定义枚举时用 `SAFE_RANGE` 来保证你取得了唯一的键码值。 - - -这有定义两个键码的枚举值的例子。添加以下代码块至 `keymap.c` 后你就可以在布局中使用 `FOO` 和 `BAR` 了。 - -```c -enum my_keycodes { - FOO = SAFE_RANGE, - BAR -}; -``` - -## 编程设计你的键码的行为 :id=programming-the-behavior-of-any-keycode - -当你覆盖一个已存在按键的行为时,或是给新按键设计功能时,请使用 `process_record_kb()` 和 `process_record_user()` 函数。QMK会在响应并处理按键事件前调用这些函数,如果这些函数返回值为 `true`,QMK将继续用常规的方式处理键码,这样可以很方便的扩展键码的功能而不需要替换代码实现。如果函数返回`false` QMK会跳过常规的键处理逻辑,需要发送的按键按下或抬起事件则需交由你负责完成。 - -任意按键在按下或抬起时,每次都会调用这些函数。 - -### process_record_user()` 实现示例 - -这个例子做了两个事。自定义了一个叫做 `FOO` 的键码的行为,并提供了在按下回车时播放音符的功能。 - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // 按下时做些什么 - } else { - // 抬起时做些什么 - } - return false; // 跳过此键的所有进一步处理 - case KC_ENTER: - // 当按下回车时播放音符 - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // 让QMK响应回车按下/抬起事件 - default: - return true; // 正常响应其他键码 - } -} -``` - -### `process_record_*` 实现示例 - -* 键盘/各子版本:`bool process_record_kb(uint16_t keycode, keyrecord_t *record)` -* 键映射:`bool process_record_user(uint16_t keycode, keyrecord_t *record)` - -`keycode` 参数为键映射中形如 `MO(1)`,`KC_L` 等定义的键值项。 应使用 `switch...case` 代码块来处理这些事件。 - -`record` 参数含有按键的真实状态信息: - -```c -keyrecord_t record { - keyevent_t event { - keypos_t key { - uint8_t col - uint8_t row - } - bool pressed - uint16_t time - } -} -``` - -# 键盘初始化代码 - -键盘初始化过程须经过几个步骤,而你的目的决定了你需要关注哪些函数。 - -有三个主要初始化函数,按调用顺序列出。 - -* `keyboard_pre_init_*` - 会在大多数其他功能运行前执行。适用于那些需要尽早执行的硬件初始化工作。 -* `matrix_init_*` - 在固件启动过程中被调用。此时硬件已初始化,但部分功能还不可用。 -* `keyboard_post_init_*` - 在固件启动过程的最后被调用。大多数情况下,你的“客制化”代码都可以放在这里。 - -!> 对于大多数人来说 `keyboard_post_init_user` 是你想要关注的函数。例如, 你可以在这里启动RGB背光灯。 - -## 键盘预初始化代码 - -这部分代码执行的非常早,甚至是在USB通信功能启动之前。 - -在这之后不久即会完成矩阵的初始化。 - -对于大多数用户来说不应在此处进行修改,因为它主要用于硬件初始化。 - -但如果你有硬件须初始化的话放在这里再好不过了(比如初始化LED引脚). - -### `keyboard_pre_init_user()` 实现示例 - -本例中,在键盘层将 B0, B1, B2, B3, 和 B4 引脚设置为LED引脚。 - -```c -void keyboard_pre_init_user(void) { - // 调用键盘预初始化代码 - - // 设置LED引脚为输出模式 - setPinOutput(B0); - setPinOutput(B1); - setPinOutput(B2); - setPinOutput(B3); - setPinOutput(B4); -} -``` - -### `keyboard_pre_init_*` 函数文档 - -* 键盘/各子版本:`void keyboard_pre_init_kb(void)` -* 键映射:`void keyboard_pre_init_user(void)` - -## 矩阵初始化代码 - -在矩阵初始化后被调用。此时一部分硬件已设置完成,但一些功能尚未完成初始化。 - -此处可以用来设置一些与硬件无关,且对初始化位置没有特殊要求的功能。 - - -### `matrix_init_*` 函数文档 - -* 键盘/各子版本:`void matrix_init_kb(void)` -* 键映射:`void matrix_init_user(void)` - -### 低级矩阵函数的重写 :id=low-level-matrix-overrides - -* GPIO引脚初始化:`void matrix_init_pins(void)` - * 此处须完成低级行列引脚的初始化。默认实现中,这里会参考可选的键盘设置项 `ROW2COL`,`COL2ROW` 及 `DIRECT_PINS` 来初始化所有 `MATRIX_ROW_PINS` 及 `MATRIX_COL_PINS` 中定义的GPIO引脚的输入/输出状态。当键盘设计者重写该函数后,QMK本身不会进行任何引脚的初始化,只会听从重写的函数的实现逻辑。 -* `COL2ROW`-从行中读: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` -* `ROW2COL`-从列中读: `void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col)` -* `DIRECT_PINS`-直读: `void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row)` - * 以上三个函数须参考矩阵类别,从底层矩阵的相关引脚状态中获取输入信息,并且应该只需要实现三者之一。默认情况下,在遍历 `MATRIX_ROW_PINS` and `MATRIX_COL_PINS` 时,会根据是否设置了 `ROW2COL`,`COL2ROW` 或 `DIRECT_PINS` 来配置输入输出方式。当键盘设计者重写该函数后,QMK本身不会进行任何矩阵GPIO引脚状态的变更,只会听从重写的函数的实现逻辑。 - -## 键盘后初始化代码 - -这是键盘初始化过程中的最后一个任务。此时您可以配置并调整某些特性,因为此时这些特性已初始化完毕。 - -### `keyboard_post_init_user()` 实现示例 - -本示例在所有初始化完成后运行,配置RGB背光。 - -```c -void keyboard_post_init_user(void) { - // 调用后初始化代码 - rgblight_enable_noeeprom(); // 使能Rgb,不保存设置 - rgblight_sethsv_noeeprom(180, 255, 255); // 将颜色设置到蓝绿色(青色),不保存设置 - rgblight_mode_noeeprom(RGBLIGHT_MODE_BREATHING + 3); // 设置快速呼吸模式,不保存设置 -} -``` - -### `keyboard_post_init_*` 函数文档 - -* 键盘/各子版本:`void keyboard_post_init_kb(void)` -* 布局: `void keyboard_post_init_user(void)` - -# 矩阵扫描码 - -应尽量使用 `process_record_*()` 实现所需的键盘自定义以及事件监听,以确保这些代码不会对键盘性能产生负面的影响。然而,在极少数情况下需要在矩阵扫描中添加监听,此时需要极端留意这些函数代码的性能表现,因为这些函数每秒可能被执行十数次。 - -### `matrix_scan_*` 实现示例 - -这个例子被故意省略了。在监听处理这样一个对性能及其敏感的部分之前,您应该足够了解qmk的内部结构,才可以在没有示例的情况下编写。如果你需要帮助,请[新建一个issue](https://github.com/qmk/qmk_firmware/issues/new)或[在Discord上与我们交流](https://discord.gg/Uq7gcHh). - -### `matrix_scan_*` 函数文档 - -* 键盘/各子版本:`void matrix_scan_kb(void)` -* 布局: `void matrix_scan_user(void)` - -该函数在每次矩阵扫描时被调用,这基本与MCU处理能力上限相同。在这里写代码要谨慎,因为它会运行很多次。 - -在需要自定义矩阵扫描代码时可以使用该函数。这也可以用作自定义状态输出(比如LED灯或者屏幕)或者其他即便用户没有输入时你也想定期运行的功能。 - -# Keyboard housekeeping - -* 键盘/各子版本:`void housekeeping_task_kb(void)` -* 键映射:`void housekeeping_task_user(void)` - -该函数在所有QMK处理工作完毕后,下一轮开始执行前被执行。可以放心地假设此时QMK已对最新的矩阵扫描结果完成了所有的处理工作 -- 更新层状态,发送USB事件,更新LED状态,刷新显示屏。 - -与 `matrix_scan_*` 类似,这些函数会频繁调用直至MCU处理能力上限。为了确保键盘的响应能力,建议在这些函数中尽量做最少的事情,在你确实需要在这里实现特别的功能时,可能会影响到其它功能的表现。 - -# 键盘 空闲/唤醒 代码 - -在主控板支持情况下,暂停大部分功能可以实现“空闲”状态,例如RGB灯光和背光。既可以节省电量消耗,也可能增强键盘的表现。 - -这由两个函数控制: `suspend_power_down_*` 和 `suspend_wakeup_init_*`,分别在主控板空闲和唤醒时被调用。 - - -### suspend_power_down_user() 和 suspend_wakeup_init_user() 的实现示例 - - -```c -void suspend_power_down_user(void) { - // 当键盘挂起时会被多次调用的代码 -} - -void suspend_wakeup_init_user(void) { - // 键盘唤醒时被调用的代码 -} -``` - -### 键盘 挂起/唤醒 函数文档 - -* 键盘/各子版本:`void suspend_power_down_kb(void)` 和 `void suspend_wakeup_init_user(void)` -* 键映射:`void suspend_power_down_kb(void)` 和 `void suspend_wakeup_init_user(void)` - -# 层切换代码 :id=layer-change-code - -每当层发生切换时被执行,可用于感知层切换事件,或自定义层处理逻辑。 - -### `layer_state_set_*` 实现示例 - -本例中,通过Planck键盘示范了如何将[RGB背光灯](zh-cn/feature_rgblight.md)设置为与层同步。 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - rgblight_setrgb (0x00, 0x00, 0xFF); - break; - case _LOWER: - rgblight_setrgb (0xFF, 0x00, 0x00); - break; - case _PLOVER: - rgblight_setrgb (0x00, 0xFF, 0x00); - break; - case _ADJUST: - rgblight_setrgb (0x7A, 0x00, 0xFF); - break; - default: // 默认层及其它层 - rgblight_setrgb (0x00, 0xFF, 0xFF); - break; - } - return state; -} -``` - -可以通过 `IS_LAYER_ON_STATE(state, layer)` 和 `IS_LAYER_OFF_STATE(state, layer)` 宏来确认常规层的状态。 - -如果不在 `layer_state_set_*` 函数中,可以通过 `IS_LAYER_ON(layer)` 和 `IS_LAYER_OFF(layer)` 宏来确认全局的层状态。 - -### `layer_state_set_*` 函数文档 - -* 键盘/各子版本:`layer_state_t layer_state_set_kb(layer_state_t state)` -* 布局: `layer_state_t layer_state_set_user(layer_state_t state)` - - -此处的 `state` 为当前活跃层的位掩码, 详见[键映射概述](zh-cn/keymap.md#keymap-layer-status) - - -# 配置的持久存储(EEPROM) - -该功能可以让键盘的配置持久存储下来。这些配置存储在控制器的EEPROM中,即便掉电后依旧可以留存下来。可以通过 `eeconfig_read_kb` 和 `eeconfig_read_user` 来读取,通过 `eeconfig_update_kb` and `eeconfig_update_user` 来进行保存。该功能常用于保存一些开关状态(比如rgb层指示灯)。此外,可以通过 `eeconfig_init_kb` 和 `eeconfig_init_user` 来设置EEPROM的默认配置值。 - -复杂的地方是,有很多方法可以存储和访问EEPROM数据,并且没有哪种方法是“正确”的。但是,每个功能只有一个双字(四字节)空间可用。 - -记住EEPROM是有写入寿命的。尽管写入寿命很高,但是并不是只有这些配置信息会写到EEPROM中。如果你写入过于频繁,你的MCU寿命将会急速减少。 - -* 如果您不理解这个例子,那么您可以不使用这个特性,因为它相当复杂。 - -### 实现示例 - -本例讲解了如何添加并读写设置项。本例使用用户键映射来实现。这是一个复杂的函数,有很多事情要做。实际上,它使用了很多前述的函数来工作! -(译注:该示例由于英文行文,可能会觉得看得稀里糊涂。实现的功能很简单,即开启了层指示功能(RGB_LYR)时,rgb背光灯会展示当前层的特定颜色用以指示层状态,而触发任何改变rgb背光颜色的键码时,rgb背光灯将回归普通的背光灯角色,不再作为层指示器) - -在你的keymap.c文件中,将以下代码添加至顶部: -```c -typedef union { - uint32_t raw; - struct { - bool rgb_layer_change :1; - }; -} user_config_t; - -user_config_t user_config; -``` - -以上代码建立了一个32位的结构体,用于在内存及EEPROM中存储配置项。此时不再需要再单独声明变量,因为都已经在该结构体中定义了。须记住 `bool`(布尔)值占用1位,`uint8_t` 占用8位,`uint16_t` 占用16位。你可以混合搭配使用,但改变这些顺序会因为错误的读写而招致问题。 - -我们在 `layer_state_set_*` 函数中会使用 `rgb_layer_change`。通过 `keyboard_post_init_user` 和 `process_record_user` 来配置所需的一切。 - -在编写 `keyboard_post_init_user` 时,你需要使用 `eeconfig_read_user()` 来计算并填充你刚刚创建的结构体。然后即可以使用结构体数据来控制键映射中的功能。就像这样: -```c -void keyboard_post_init_user(void) { - // 调用键映射级别的矩阵初始化 - - // 从EEPROM读用户配置 - user_config.raw = eeconfig_read_user(); - - // 如使能,设置默认层 - if (user_config.rgb_layer_change) { - rgblight_enable_noeeprom(); - rgblight_sethsv_noeeprom_cyan(); - rgblight_mode_noeeprom(1); - } -} -``` -以上函数会在读EEPROM配置后立即设置默认层的RGB颜色。"raw"值将被转换为上述创建的实际使用的"union"结构体。 - -```c -layer_state_t layer_state_set_user(layer_state_t state) { - switch (get_highest_layer(state)) { - case _RAISE: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_magenta(); rgblight_mode_noeeprom(1); } - break; - case _LOWER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_red(); rgblight_mode_noeeprom(1); } - break; - case _PLOVER: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_green(); rgblight_mode_noeeprom(1); } - break; - case _ADJUST: - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_white(); rgblight_mode_noeeprom(1); } - break; - default: // 针对其他层或默认层 - if (user_config.rgb_layer_change) { rgblight_sethsv_noeeprom_cyan(); rgblight_mode_noeeprom(1); } - break; - } - return state; -} -``` -这样仅在相关值使能时才会改变RGB背光灯。若要配置该值, 为 `process_record_user` 创建一个新键码 `RGB_LYR`。此时我们想实现的是,如果触发了常规的RGB码,以上示例中的逻辑都将不生效,形如: -```c - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case FOO: - if (record->event.pressed) { - // 按下时做点什么 - } else { - // 抬起时做点什么 - } - return false; // 跳过此键的进一步处理 - case KC_ENTER: - // 在按下回车时播放音符 - if (record->event.pressed) { - PLAY_SONG(tone_qwerty); - } - return true; // 让QMK产生回车按下/抬起事件 - case RGB_LYR: // 这允许我们将背光灯作为层指示,或正常用途 - if (record->event.pressed) { - user_config.rgb_layer_change ^= 1; // 切换状态 - eeconfig_update_user(user_config.raw); // 向EEPROM写入新状态 - if (user_config.rgb_layer_change) { // 如果层指示功能被使能 - layer_state_set(layer_state); // 那么立刻更新层颜色 - } - } - return false; - case RGB_MODE_FORWARD ... RGB_MODE_GRADIENT: // 对于所有的RGB代码 (参考 quantum_keycodes.h, 400 行处) - if (record->event.pressed) { // 本句失能层指示功能,假设你现在要调整该功能…你要把它禁用 - if (user_config.rgb_layer_change) { // 仅当使能时 - user_config.rgb_layer_change = false; // 失能,然后 - eeconfig_update_user(user_config.raw); // 向EEPROM写入设置 - } - } - return true; break; - default: - return true; // 其他键码正常处理 - } -} -``` -最后,须添加 `eeconfig_init_user` 函数,从而当EEPROM重置时,可以指定默认值, 甚至自定义操作。若想强制重置EEPROM,请用 `EEP_RST` 键码或[Bootmagic](zh-cn/feature_bootmagic.md) 功能。比如,在你想重置RGB层指示配置,并保存默认值时。 - -```c -void eeconfig_init_user(void) { // EEPROM被重置 - user_config.raw = 0; - user_config.rgb_layer_change = true; // 我们想要默认使能 - eeconfig_update_user(user_config.raw); // 向EEPROM写入默认值 - - // 通过使用非'noeeprom'版本的函数,可以同时写入这些配置到EEPROM中。 - rgblight_enable(); // 默认使能RGB - rgblight_sethsv_cyan(); // 默认设置青色 - rgblight_mode(1); // 默认设置长亮 -} -``` - -一切已就绪,RGB层指示将在需要时生效。这个设置会持久存储,即便是拔下键盘。如果你使用其他RGB码,层指示将失效,从而可以停留在期望的模式及颜色下。 - -### 'EECONFIG' 函数文档 - -* 键盘/各子版本:`void eeconfig_init_kb(void)`, `uint32_t eeconfig_read_kb(void)` 和 `void eeconfig_update_kb(uint32_t val)` -* 键映射:`void eeconfig_init_user(void)`, `uint32_t eeconfig_read_user(void)` 和 `void eeconfig_update_user(uint32_t val)` - -`val` 是你想写入EEPROM的值,`eeconfig_read_*`函数会从EEPROM返回一个32位(双字)的值。 - -### 定时执行 :id=deferred-execution - -QMK支持在特定时间间隔后执行回调,以代替手动的计时器管理。 - -#### 定时回调函数 - -所有的 _定时回调函数_ 使用同样的函数签名,如下: - -```c -uint32_t my_callback(uint32_t trigger_time, void *cb_arg) { - /* 处理了一些工作 */ - bool repeat = my_deferred_functionality(); - return repeat ? 500 : 0; -} -``` - -第一个参数 `trigger_time` 为预期的执行时间,如果因为其它事情造成了延迟未能在准确的时间点执行,可以利用这个参数“追赶”或者跳过这次间隔,取决于你的目的是什么。 - -第二个参数 `cb_arg` 为下述的 `defer_exec()` 传入的参数,由此可以获取调用时的状态信息。 - -返回值为该函数下一次期望被回调的时间间隔毫秒数 -- 若返回 `0` 则会自动被注销掉。上例中,通过执行假想的 `my_deferred_functionality()` 函数来决策回调是否继续下去 -- 若是,则给出一个 `500` 毫秒的延迟计划,否则,返回 `0` 来告知定时处理后台任务该计划已执行完毕。 - -?> 须留意返回的延时时间是相对原定的触发时间点的,而不是回调执行完的时间点。这样可以防止偶发的执行延迟影响稳定的定时事件计划。 - -#### 注册定时回调 - -在定义好回调后,通过如下API进行定时回调注册: - -```c -deferred_token my_token = defer_exec(1500, my_callback, NULL); -``` - -第一个参数为执行 `my_callback` 的毫秒时间延迟 -- 上例中为 `1500` 毫秒,即 1.5 秒。 - -第三个参数为回调执行时传入的 `cb_arg` 参数。须确保该值在回调时依旧有效 -- 局部函数内的变量会在回调执行前就被释放掉因此不能用。如果并不需要这个参数,可以传入 `NULL`。 - -返回值 `deferred_token` 可被用于在回调执行前取消该定时计划。如果该函数调用失败,会返回 `INVALID_DEFERRED_TOKEN`,一般错误原因是延时值被设置为 `0` 或回调函数参数为 `NULL`,还有一种可能是已有过量的回调在等待被处理 -- 可以按照下述方法修改这个阈值。 - -#### 延长定时回调时间 - -由 `defer_exec()` 返回的 `deferred_token` 可以用来修改回调执行所需等待的时延值: -```c -// 重新调整 my_token 后续的执行计划为当前时间起800ms后 -extend_deferred_exec(my_token, 800); -``` - -#### 取消定时回调 - -由 `defer_exec()` 返回的 `deferred_token` 可以用来取消掉后续的执行计划: -```c -// 取消 my_token 的后续回调 -cancel_deferred_exec(my_token); -``` - -一旦 token 被取消了,即视为不再可用。重新使用该 token 是不支持的。 - -#### 定时回调的限制 - -可安排的定时回调计划数量是有限的,由 `MAX_DEFERRED_EXECUTORS` 定义的值确定。 - -如果定时回调注册失败了,可以在对应的键盘或键映射下的 `config.h` 文件中修改该值,比如将默认的 8 改为 16: - -```c -#define MAX_DEFERRED_EXECUTORS 16 -``` diff --git a/docs/zh-cn/driver_installation_zadig.md b/docs/zh-cn/driver_installation_zadig.md deleted file mode 100644 index db9bb9a3fd8f..000000000000 --- a/docs/zh-cn/driver_installation_zadig.md +++ /dev/null @@ -1,102 +0,0 @@ -# 利用Zadig安装Bootloader驱动 - - - -QMK在主机侧会展现为一台HID键盘设备,因此不需要额外的驱动。但若要在Windows下刷写键盘固件,重置主控板时出现的bootloader设备则通常需要一些驱动程序。 - -已知的特例有两个:常见于Pro Micro的Caterina bootloader,以及PJRC Teensys上的HalfKay bootloader, 会同时提供一个串行端口设备及一个HID设备,因此不需要额外的驱动。 - -这里我们推荐使用[Zadig](https://zadig.akeo.ie/)工具软件。若你在MSYS2中配置了开发环境,`qmk_install.sh` 脚本已经替你安装了相关驱动。 - -## 安装 - -将键盘重置为bootloader模式,点击 `RESET` 键码(可能在别的层中),或按一下通常在主控板背面上的重置开关,如果你的键盘上没有前两者,尝试在按住Esc键或空格+`B`键时插上键盘(更多信息参见[Bootmagic](zh-cn/feature_bootmagic.md))。有些键盘使用[指令](zh-cn/feature_command.md)功能来代替Bootmagic,这种情况下,可以在键盘插入状态下点击 左Shift+右Shift+`B` 或 左Shift+右Shift+Esc组合键来进入bootloader模式。 -也有一些键盘需要特别的操作才能进入bootloader状态。例如,[Bootmagic](zh-cn/feature_bootmagic.md)键(默认为:Esc键)在其它键上,比如左Control;或是指令组合键(默认为:左Shift+右Shift)为其它组合,如左Control+右Control。当不确定的时候,可以查阅一下主控板的README文件。 - -若要将USBaspLoader设备置为bootloader模式,请在按住 `BOOT` 按钮时点击 `RESET` 按钮,或是在按住 `BOOT` 按钮时插入USB线缆。 - -Zadig可以自动检测到bootloader设备,但有时你需要在 **Options(选项) → List All Devices(列出所有设备)** 的下拉列表中选择正确的设备。 - -!> 如果Zadig中列出的一个或多个设备为 `HidUsb` 驱动的,那么你的键盘应该没有进入bootloader模式,此时箭头会标记成橙色并会询问你确认是否要修改系统驱动,此时**不要**允许该操作。 - -如果箭头呈现绿色,选择所需的驱动,点击**Install Driver(安装驱动)**。如何选择正确的驱动进行安装请参见[已知驱动列表](#list-of-known-bootloaders)。 - -![在Zadig中安装了正确的bootloader驱动](https://i.imgur.com/b8VgXzx.png) - -最后,重新拔插一次键盘,确认驱动可以正常加载。如果你在使用QMK工具箱进行刷写,记得也重启一下,因为有时它不会检测到驱动的变化。 - -## 从错误的驱动安装中恢复 - -如果你发现键盘无法输入了,应当是因为错误地替换了键盘本身的驱动,而不是bootloader的驱动,你的键盘没有进入bootloader模式就进行安装时就会遇到这个问题。在Zadig中很容易看出这个问题 - 正常的键盘在其所有的接口上都应该有 `HidUsb` 驱动: - -![在Zadig中的一个正常的键盘](https://i.imgur.com/Hx0E5kC.png) - -打开Device Manager(设备管理器),选择**View(查看) → Devices by container(依类型排序设备)**,并定位到你键盘名所在的节点。 - -![在设备管理器中安装了错误的驱动的主控板](https://i.imgur.com/o7WLvBl.png) - -在这些节点上右键,选择**Uninstall device(卸载)**。如果出现了**Delete the driver software for this device(同时卸载该设备驱动文件)**也请勾选上。 - -![设备卸载确认对话框,选中了“删除驱动文件”](https://i.imgur.com/aEs2RuA.png) - -点击 **Action(操作) → Scan for hardware changes(扫描检测硬件改动)**。此时,键盘应该恢复可用状态了。再确认一下Zadig中键盘是否在使用 `HidUsb` 驱动,如果是,键盘即完全恢复可用状态了,如果不是,重复这一步直到Zadig中报告了正确的驱动。 - -?> 在这一步有时需要重启电脑,以便Windows可以选用新驱动文件。 - -## 卸载 - -卸载bootloadeer设备要比安装过程复杂一些。 - -打开设备管理器,选择**查看 → 依类型排序设备**,并找到bootloader设备,寻找USB VID和PID与Zadig的[该表格](#list-of-known-bootloaders)中一致的项。 - -在设备属性的详细信息tab中,找到 `Inf name(INF名称)` 值,通常该值类似于 `oemXX.inf`: - -![设备属性中的INF名称值](https://i.imgur.com/Bu4mk9m.png) - -之后使用管理员权限打开一个命令行窗口(在开始菜单处输出 `cmd` 并点击Ctrl+Shift+回车)。执行 `pnputil /enum-drivers` 并找到 `INF名称` 与 `Published Name(发布名称)` 一致的项: - -![对pnputil输出中匹配驱动项进行高亮展示](https://i.imgur.com/3RrSjzW.png) - -执行 `pnputil /delete-driver oemXX.inf /uninstall`,之后该驱动会被删除,相关设备也不再使用该驱动,但设备是不会被移除的。 - -与上一节相似,本流程也可能需要执行多次,因为一个设备可能会有多个可用的驱动。 - -!> **警告:** 操作过程中*务必非常小心*!以免不小心卸载掉其它关键驱动。如果你对操作不是很确定,多次检查 `/enum-drivers`的输出信息,也可以考虑执行 `/delete-driver` 时不添加 `/uninstall` 开关\。 - -## 已知驱动列表 :id=list-of-known-bootloaders - -该表列出了已知的bootloader设备及其USB VID(厂商ID)和PID(产品ID),以及可用于QMK刷写固件的驱动。留意usbser及HidUsb驱动是随Windows附带的,无法通过Zadig安装 - 如果你的设备驱动不符,请参照上节来卸载这些驱动。 - -此处列出的设备名应与Zadig中的一致,但不一定与设备管理器及QMK工具箱展示的一致。 - -|Bootloader |设备名 |VID/PID |驱动 | -|--------------|------------------------------|--------------|-------| -|`atmel-dfu` |ATmega16u2 DFU |`03EB:2FEF` |libusb0| -|`atmel-dfu` |ATmega32U2 DFU |`03EB:2FF0` |libusb0| -|`atmel-dfu` |ATm16U4 DFU V1.0.2 |`03EB:2FF3` |libusb0| -|`atmel-dfu` |ATm32U4DFU |`03EB:2FF4` |libusb0| -|`atmel-dfu` |*none* (AT90USB64) |`03EB:2FF9` |libusb0| -|`atmel-dfu` |AT90USB128 DFU |`03EB:2FFB` |libusb0| -|`qmk-dfu` |(键盘名) Bootloader |同`atmel-dfu` |libusb0| -|`halfkay` |*none* |`16C0:0478` |HidUsb | -|`caterina` |Pro Micro 3.3V |`1B4F:9203` |usbser | -|`caterina` |Pro Micro 5V |`1B4F:9205` |usbser | -|`caterina` |LilyPadUSB |`1B4F:9207` |usbser | -|`caterina` |Pololu A-Star 32U4 Bootloader |`1FFB:0101` |usbser | -|`caterina` |Arduino Leonardo |`2341:0036` |usbser | -|`caterina` |Arduino Micro |`2341:0037` |usbser | -|`caterina` |Adafruit Feather 32u4 |`239A:000C` |usbser | -|`caterina` |Adafruit ItsyBitsy 32u4 3V |`239A:000D` |usbser | -|`caterina` |Adafruit ItsyBitsy 32u4 5V |`239A:000E` |usbser | -|`caterina` |Arduino Leonardo |`2A03:0036` |usbser | -|`caterina` |Arduino Micro |`2A03:0037` |usbser | -|`bootloadhid` |HIDBoot |`16C0:05DF` |HidUsb | -|`usbasploader`|USBasp |`16C0:05DC` |libusbK| -|`apm32-dfu` |APM32 DFU ISP Mode |`314B:0106` |WinUSB | -|`stm32-dfu` |STM32 BOOTLOADER |`0483:DF11` |WinUSB | -|`kiibohd` |Kiibohd DFU Bootloader |`1C11:B007` |WinUSB | -|`stm32duino` |Maple 003 |`1EAF:0003` |WinUSB | -|`qmk-hid` |(键盘名) Bootloader |`03EB:2067` |HidUsb | diff --git a/docs/zh-cn/easy_maker.md b/docs/zh-cn/easy_maker.md deleted file mode 100644 index 420c77d3af56..000000000000 --- a/docs/zh-cn/easy_maker.md +++ /dev/null @@ -1,37 +0,0 @@ -# 极简式制作 - 通过配置器进行一次性的工程构建 - - - -你是否需要一种极简的控制器编程方案,类似Proton C或Teensy 2.0,以进行一次性的工程构建?QMK提供了极简制作器,通过QMK配置器可以在几分钟内制作一个固件。 - -有几种极简制作器,取决于你需要什么样的: - -* [引脚直连](https://config.qmk.fm/#/?filter=ez_maker/direct) - 将每个开关独立直连到一个引脚 -* 引脚直连 + 背光 (即将可用) - 类似引脚直连,单独加一个引脚连接到[背光](zh-cn/feature_backlight.md)控制器上 -* 引脚直连 + 小键盘锁 (即将可用) - 类似引脚直连,单独加一个引脚连接到Numlock LED上 -* 引脚直连 + 大写锁 (即将可用) - 类似引脚直连, 单独加一个引脚连接到Capslock LED上 -* 引脚直连 + 编码器 (即将可用) - 类似引脚直连, 再加两个引脚用于连接一个旋钮编码器 - -## 快速指引 - -最简单的情况是使用一个引脚直连的主控板,将每个引脚连接到一个开关,另一端再接地即可,从以下键盘列表中可以选择一款支持的MCU: - -* - -更多信息请参见[引脚直连](#direct-pin)一节。 - -# 引脚直连 :id=direct-pin - -与其名字表意相同,它的原理是一个引脚连接一个开关,每个开关的另一端接地(VSS或GND),不需要额外的部件,通常MCU内部自带上拉电阻,因此可以感知开关动作。 - - -这里有一个示意图,展示了如何将一个按钮连接到ProMicro的A3引脚上: - -![该示意图中的ProMicro的A3引脚导出一根线,连接到了开关的左边,另一根线从开关右边引出并接地。](https://i.imgur.com/JcDhZll.png) - -在开关连接到各自的引脚后,在键盘下拉列表中选择所使用的MCU,将键码指定到对应的引脚上即可构建出固件。以下链接仅展示支持引脚直连的极简式制作: - -* diff --git a/docs/zh-cn/faq_build.md b/docs/zh-cn/faq_build.md deleted file mode 100644 index 84cd3c6a4e93..000000000000 --- a/docs/zh-cn/faq_build.md +++ /dev/null @@ -1,73 +0,0 @@ -# 常被问及的编译问题 - - - -本页涉及所有编译QMK的问题,如果你还没有试过,请先阅读[编译环境配置](zh-cn/getting_started_build_tools.md)及[Make指引](zh-cn/getting_started_make_guide.md)。 - -## 无法在Linux下编程 -操作设备需要足够的权限,对于Linux用户,请参阅下方有关 `udev` 的规则说明。如果你对 `udev` 有困惑,可以先试试 `sudo` 命令,如果你对这个命令不熟悉,可以通过 `man sudo` 或 [这个web页面](https://linux.die.net/man/8/sudo)进行了解。 - -一个使用 `sudo` 的示例,这里假设你的控制器是ATMega32u4: - - $ sudo dfu-programmer atmega32u4 erase --force - $ sudo dfu-programmer atmega32u4 flash your.hex - $ sudo dfu-programmer atmega32u4 reset - -或者只是: - - $ sudo make ::flash - -但请留意,用 `sudo` 来执行 `make` 通常***不是***一个好主意,请尽量考虑使用上面的办法。 - -### Linux `udev` 规则 :id=linux-udev-rules - -在linux下,需要足够的权限才能读写bootloader设备,可以使用 `sudo` 来刷写固件(不推荐),也可以将[这个文件](https://github.com/qmk/qmk_firmware/tree/master/util/udev/50-qmk.rules) 放到 `/etc/udev/rules.d/` 目录下。 - -放好后,执行: - -``` -sudo udevadm control --reload-rules -sudo udevadm trigger -``` - -**注意:**在旧版ModeManager(<1.12)中,过滤功能仅在严格模式(strict mode)下可用,可以调整一下配置: - -``` -printf '[Service]\nExecStart=\nExecStart=/usr/sbin/ModemManager --filter-policy=default' | sudo tee /etc/systemd/system/ModemManager.service.d/policy.conf -sudo systemctl daemon-reload -sudo systemctl restart ModemManager -``` - -### 在Linux下无法检测到bootloader模式下的串口设备 -确认一下你的内核版本是否已配置为支持该设备。如果你的设备使用USB ACM,如Pro Micro(Atmega32u4),确认内核 配置中包含 `CONFIG_USB_ACM=y`,其它类型的设备可能需要 `USB_SERIAL` 及相关子配置的支持。 - -## DFU Bootloader显示为未知设备 - -在Windows下刷写键盘固件时很常见的一个问题。主要原因是安装了错误的驱动,或者压根没有装驱动。 - -要修复这个问题,可以尝试重新执行QMK安装脚本(位于MSYS2或WSL中的 `qmk_firmware` 目录下的 `./util/qmk_install.sh`)或重新安装QMK工具箱。此外,也可以尝试下载安装[QMK驱动安装包 `qmk_driver_installer`](https://github.com/qmk/qmk_driver_installer)来修复。 - -如果问题依旧,可能是需要下载安装Zadig,具体请参考[通过Zadig安装bootloader驱动](zh-cn/driver_installation_zadig.md)。 - -## USB VID 和 PID -通过编辑 `config.h` 你可以自由指定ID,随便选一个看起来不常用的ID一般不会有什么问题,冲突的概率很低。 - -大部分QMK设备都选用 `0xFEED` 作为VID,选取PID前请先看一下其它键盘的情况再决定。 - -同时请阅读这个issue: -https://github.com/tmk/tmk_keyboard/issues/150 - -你可以在以下地址购买唯一的VID:PID,但我觉得个人使用情况下没有必要。 -- https://www.obdev.at/products/vusb/license.html -- https://www.mcselec.com/index.php?page=shop.product_details&flypage=shop.flypage&product_id=92&option=com_phpshop&Itemid=1 - -### 在我刷写完键盘后就没响应了/点了没动静了 -- 设备是arm的(rev6 planck, clueboard 60, hs60v2等)(2019年2月) -因为ARM平台下EEPROM特殊的工作模式,已保存的配置可能会失效。主要影响的是默认层,有概率在特定情况下会导致键盘不可用,我们还没有搞明白原因。这个问题可以在重置EEPROM后恢复。 - -[Planck rev6 上重置 EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/539284620861243409/planck_rev6_default.bin) 可以用于强制重置EEPROM。刷入这个文件后,再次刷入正常固件,会将键盘恢复到_正常_工作状态。 -[Preonic rev3 上重置 EEPROM](https://cdn.discordapp.com/attachments/473506116718952450/537849497313738762/preonic_rev3_default.bin) - -也可以考虑使用bootmagic,只要它可以用。(参见[Bootmagic文档](zh-cn/feature_bootmagic.md)并结合键盘情况来了解如何操作) diff --git a/docs/zh-cn/faq_debug.md b/docs/zh-cn/faq_debug.md deleted file mode 100644 index 63d688ed9e6d..000000000000 --- a/docs/zh-cn/faq_debug.md +++ /dev/null @@ -1,136 +0,0 @@ -# 调试 FAQ - - - -此页面详细介绍了人们对键盘故障排除的各种常见问题。 - -## 调试 :id=debugging - -如果你在 `rules.mk` 中配置了 `CONSOLE_ENABLE = yes`,你的键盘将会输出调试信息。默认情况下输出很有限,可以启用调试模式来增加调试输出的丰富度。使用你的键映射方案中的 `DEBUG` 键码,或使用[指令](zh-cn/feature_command.md)功能来启动调试模式,或者将下面这段代码放到你的键映射中: - -```c -void keyboard_post_init_user(void) { - // 通过调整这些值可以改变其表现 - debug_enable=true; - debug_matrix=true; - //debug_keyboard=true; - //debug_mouse=true; -} -``` - -## 调试工具 - -有多种可用于调试的工具。 - -### 使用QMK工具箱调试 - -在兼容的平台上,[QMK工具箱](https://github.com/qmk/qmk_toolbox)可以展示你的键盘的调试输出。 - -### 使用 QMK CLI 进行调试 - -倾向于在终端进行调试?使用 [QMK CLI 命令行](zh-cn/cli_commands.md#qmk-console)可以展示键盘输出的调试信息。 - -### 使用hid_listen调试 - -更喜欢使用终端的方案?PJRC提供的[hid_listen](https://www.pjrc.com/teensy/hid_listen.html)也可以用来展示调试信息,已有Windows、Linux及MacOS下预编译好的可执行文件。 - -## 发送自定义调试信息 :id=debug-api - -有时在[自定义代码](zh-cn/custom_quantum_functions.md)中输出调试信息非常有用,要做到这个功能也很简单,在代码文件头部包含 `print.h` 文件: - -```c -#include "print.h" -``` - -然后可以使用以下输出函数: - -* `print("string")`: 字符串输出 -* `uprintf("%s string", var)`: 格式化字符串输出 -* `dprint("string")` 仅调试模式下,字符串输出 -* `dprintf("%s string", var)`: 仅调试模式下,格式化字符串输出 - -## 调试示例 - -以下列出了一些实际出现过的调试范例,更多资料参见[调试/定位QMK问题](zh-cn/faq_debug.md)。 - -### 当前按下的键的矩阵坐标是什么? - -在移植或尝试诊断PCB问题时,确认按下的键被正确扫描到是很有用的排查步骤。要启用该场景的日志输出,请在 `keymap.c` 中添加: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - // If console is enabled, it will print the matrix position and status of each key pressed -#ifdef CONSOLE_ENABLE - uprintf("KL: kc: 0x%04X, col: %u, row: %u, pressed: %b, time: %u, interrupt: %b, count: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed, record->event.time, record->tap.interrupted, record->tap.count); -#endif - return true; -} -``` - -输出示例 -```text -Waiting for device:....... -Listening: -KL: kc: 169, col: 0, row: 0, pressed: 1 -KL: kc: 169, col: 0, row: 0, pressed: 0 -KL: kc: 174, col: 1, row: 0, pressed: 1 -KL: kc: 174, col: 1, row: 0, pressed: 0 -KL: kc: 172, col: 2, row: 0, pressed: 1 -KL: kc: 172, col: 2, row: 0, pressed: 0 -``` - -### 扫描到一个键码需要多久? - -调试性能问题时,知晓开关矩阵的扫描频率是很有用的排查步骤。要启用该场景的日志输出,请在 `config.h` 中添加: - -```c -#define DEBUG_MATRIX_SCAN_RATE -``` - -输出示例 -```text - > matrix scan frequency: 315 - > matrix scan frequency: 313 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 - > matrix scan frequency: 316 -``` - -## `hid_listen` 无法识别到设备 - -如果设备没有就绪,在命令行下调试会看到如下输出: - -``` -Waiting for device:......... -``` - -当设备插入后,*hid_listen*可以发现设备,会有如下输出: - -``` -Waiting for new device:......................... -Listening: -``` - -若无法出现'Listening:'消息,尝试在[Makefile]中添加 `CONSOLE_ENABLE=yes` - -在类Linux系统下,访问设备可能需要一定权限,尝试使用 `sudo hid_listen`。 - -此外,很多Linux发行版可以通过创建如下内容的文件 `/etc/udev/rules.d/70-hid-listen.rules` 来避免通过root权限执行hid_listen: - -``` -SUBSYSTEM=="hidraw", ATTRS{idVendor}=="abcd", ATTRS{idProduct}=="def1", TAG+="uaccess", RUN{builtin}+="uaccess" -``` - -使用设备的真实VID和PID替换上面的abcd和def1,留意必须全小写。其中 `RUN{builtin}+="uaccess"` 仅在较老的发行版中需要使用。 - -## 命令行无法成功输出消息 -请检查: -- *hid_listen*确实找到了设备,如前文所述。 -- 通过**Magic**+d命令启用调试模式,参见[Magic Commands](https://github.com/tmk/tmk_keyboard#magic-commands). -- 配置`debug_enable=true`. 参见[调试](#debugging) -- 尝试用 `print` 替代 `dprint`, 参见**common/print.h**. -- 拔出其它可能影响命令行的设备,参见[Issue #97](https://github.com/tmk/tmk_keyboard/issues/97). diff --git a/docs/zh-cn/faq_general.md b/docs/zh-cn/faq_general.md deleted file mode 100644 index cc8ef3d19a25..000000000000 --- a/docs/zh-cn/faq_general.md +++ /dev/null @@ -1,58 +0,0 @@ -# 常见问题(FAQ) - - - -## QMK是什么? - -[QMK](https://github.com/qmk), 是量子机械键盘(Quantum Mechanical Keyboard)的缩写, 是制作自定义键盘工具的人组成的组织。 一切始于[QMK固件](https://github.com/qmk/qmk_firmware)项目, 可以认为是[TMK](https://github.com/tmk/tmk_keyboard)的改进版本. - -## 不知道从哪开始搞! - -这样的话建议从[新手指引](zh-cn/newbs.md)开始。那里有你需要的高质量的入门信息。 - -如果还是搞不懂的话,直接跳到[QMK配置器](https://config.qmk.fm)吧,你核心需要的东西都在那里。 - -## 我的固件如何刷写到硬件上? - -先参考[编译/刷写固件FAQ](zh-cn/faq_build.md),里面有充足的资料,常见的问题也给出了足够多的解决办法。 - -## 我的问题这里找不到相关信息怎么办? - -没有关系,请到[GitHub上发issue](https://github.com/qmk/qmk_firmware/issues)看看是否有人遇到了相同的问题(留意一定是相同的问题,而不是相似的)。 - -如果还是找不到解决办法,请[新建issue](https://github.com/qmk/qmk_firmware/issues/new)! - -## 我好像找到了bug? - -那么新建一个[issue](https://github.com/qmk/qmk_firmware/issues/new)吧,如果你还知道怎么修,带着修复方案发个Pull Request吧。 - -## 但是 `git` 和 `GitHub` 我实在是玩不转! - -别担心,这里有很好的[入门指引](zh-cn/newbs_git_best_practices.md)可以教你怎么轻松快乐地使用 `git` 和GitHub进行开发。 - -更多的 `git` 和GitHub知识,参考[这里](zh-cn/newbs_learn_more_resources.md)。 - -## 我可以添加一个支持的键盘 - -太棒啦!请发Pull Request吧,在代码审阅后,我们会合并进去! - -### 我可以打上 `QMK` 的标吗? - -很好啊!我们甚至乐意帮你这么做! - -我们有[一整页](https://qmk.fm/powered/)的资料旨在帮你在页面和键盘上打上QMK的标,里面有QMK官方提供的所有支援(信息及图片)。 - -如果你有任何疑问,可以发issue或通过[Discord](https://discord.gg/Uq7gcHh)联系我们。 - -## QMK和TMK区别是什么? - -TMK原先是由[Jun Wako](https://github.com/tmk)设计实现的,QMK来源于[Jack Humbert](https://github.com/jackhumbert)的Planck的TMK fork。一段时间后,Jack的这个fork与TMK渐行渐远,到2015年时,Jack决定将这份fork重命名为QMK。 - -技术上讲QMK等同于基于TMK增加了一些新功能,最显著的是在扩充了可用键码后,实现了很多诸如 `S()`, `LCTL()` 及 `MO()` 这样的高级功能,所有这些键码可以参见[键码](zh-cn/keycodes.md)页。 - -从工程项目及社区维护角度来看,TMK维护了一份官方支持的键盘及很少量的社区贡献,社区中各自维护着各自的fork,且因为默认键映射很少,TMK的使用者基本不会共享键映射。QMK通过统一的集约式仓库(repo)管理来鼓励分享键盘及键映射,任何符合质量基线的pull request都会被采纳,因此绝大部分贡献都来源于社区,QMK小组会在必要时提供支援。 - -两种模式各有利弊,并且TMK和QMK之间也会有合乎理法的代码交流。 diff --git a/docs/zh-cn/faq_keymap.md b/docs/zh-cn/faq_keymap.md deleted file mode 100644 index 0e1e5a20e88d..000000000000 --- a/docs/zh-cn/faq_keymap.md +++ /dev/null @@ -1,157 +0,0 @@ -# 键映射FAQ - - - -本页包含人们经常遇到的关于键映射的问题,如果你还没阅读过[键映射概览](zh-cn/keymap.md),请先阅读一下。 - -## 我能使用的键码有哪些? -所有可用键码收录在[键码](zh-cn/keycodes.md)页,在有更详尽的文档时,我们会更新这个链接。 - -所有键码实际定义在[quantum/keycode.h](https://github.com/qmk/qmk_firmware/blob/master/quantum/keycode.h). - -## 默认键码是什么? - -广为使用的键盘配列有三种——ANSI,ISO及JIS。北美主要使用ANSI,欧洲及非洲主要使用ISO,日本主要使用JIS,其它区域多为ANSI或ISO。这三种配列的键码可查阅: - - -![键盘配列示意图](https://i.imgur.com/5wsh5wM.png) - -## 如何对复杂的键码指定自定义的名称? - -使用更容易理解的自定义的名字去指代一些键码有时很实用,通常我们使用 `#define` 来实现: - -```c -#define FN_CAPS LT(_FL, KC_CAPSLOCK) -#define ALT_TAB LALT(KC_TAB) -``` - -这样键映射代码中就可以使用 `FN_CAPS` 和 `ALT_TAB` 了,可读性好得多。 - -## 一些按键发生了交换,或是不能用了 - -QMK有两个功能系列,Bootmagic及指令,都可以让键盘随时变得灵活多变,功能包含但不限于交换Ctrl/Caps、锁定Gui键、交换Alt/Gui、交换Backspace/Backslash、禁用所有按键等。 - -快速恢复的办法是插入键盘时按住空格+`Backspace`键,这样会重置键盘内存储的设置信息,键盘就会恢复常态。如果问题依旧存在,请参考: - -* [Bootmagic](zh-cn/feature_bootmagic.md) -* [指令](zh-cn/feature_command.md) - -## 菜单键(Menu)不可用 - -现代键盘上,位于 `KC_RGUI` 及 `KC_RCTL` 间的按键实际上叫做 `KC_APP`。原因是该键被发明时,相关标准中已经有了 `菜单(MENU)` 键,因此微软将该键命名为 `APP` 键。 - -## `KC_SYSREQ` 不可用 -请使用截图键码(`KC_PSCREEN` 及 `KC_PSCR`)替代 `KC_SYSREQ`,组合键’Alt + Print Screen‘实际上会被识别为’System request‘。 - -具体参见[issue #168](https://github.com/tmk/tmk_keyboard/issues/168)以及 -* https://en.wikipedia.org/wiki/Magic_SysRq_key -* https://en.wikipedia.org/wiki/System_request - -## 电源键不工作 - -QMK有两个容易让人迷惑的“电源键”键码:HID键盘页的 `KC_POWER`,及用户页的 `KC_SYSTEM_POWER`(或 `KC_PWR`)。 - -前者只有macOS支持,后者连同 `KC_SLEP` 及 `KC_WAKE` 在所有主流操作系统上都支持,因此使用后者是推荐的做法。在Windows下,按下按键即刻就会生效,而macOS下必须按住直到系统弹出一个对话框。 - -## 单发修饰键 -用来解决我自己的’the‘麻烦,我总是会将’The‘错输入为’the‘或’THe‘,单发Shift键缓解了我的这个麻烦。 -https://github.com/tmk/tmk_keyboard/issues/67 - -## 修饰键/层 卡住了 -层切换功能只有在正确配置的情况下,才不会出现卡住修饰键和层的问题。 -对于修饰键和层切换操作来讲,必须确保 `KC_TRANS` 在切换到目标layer时正确置位,才能让修饰键正确释放。或者在释放动作中确保返回到了之前的层。 - -* https://github.com/tmk/tmk_core/blob/master/doc/keymap.md#31-momentary-switching -* https://geekhack.org/index.php?topic=57008.msg1492604#msg1492604 -* https://github.com/tmk/tmk_keyboard/issues/248 - - -## 机械锁定式开关支持 - -该功能支持形如[Alps这款](https://deskthority.net/wiki/Alps_SKCL_Lock)的*机械锁定式开关*,启用该功能须在 `config.h` 中添加如下定义: - -``` -#define LOCKING_SUPPORT_ENABLE -#define LOCKING_RESYNC_ENABLE -``` - -启用该功能后,在你的键映射中须改为使用 `KC_LCAP`,`KC_LNUM` 和 `KC_LSCR`。 - -旧式复古风(vintage style)键盘偶尔能见到锁定式开关,但在现代键盘中见不到了。***因此你基本不会需要这个功能的,直接使用 `KC_CAPS`,`KC_NUM` 和 `KC_SCRL` 就好*** - -## 输入形如法语中软音'Ç'这样的非ASCII字符 - -参见[Unicode](zh-cn/feature_unicode.md)功能. - -## macOS系统下的 `Fn` - -和其它键盘不同,Apple键盘上的Fn有自己的键码...在某种程度上。其占用了基础6KRO HID事件上报中的第六个键码 —— 因此Apple键盘实际上只是5KRO(5键无冲)的。 - -技术上讲QMK确实能发送这种键码,但这么做需要修改上报事件中Fn键状态的格式。更麻烦的是,只有你的键盘的VID及PID与Apple键盘一致时才会生效。QMK对此提供官方支持可能会有法律风险,换句话说,我们不太可能去这么做的。 - -具体信息请参见[这个issue](https://github.com/qmk/qmk_firmware/issues/2179)。 - -## Mac OSX下支持的键有哪些? -你可以通过查阅以下代码确认OSX下支持的键码。 - -`usb_2_adb_keymap` 数组实现了从 Keyboard/Keypad 页到 ADB 扫描码(OSX内部使用的键码)的转换。 - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/Cosmo_USB2ADB.c - -以及 `IOHIDConsumer::dispatchConsumerEvent` 负责处理用户页部分。 - -https://opensource.apple.com/source/IOHIDFamily/IOHIDFamily-606.1.7/IOHIDFamily/IOHIDConsumer.cpp - - -## Mac OSX下的JIS键 -日语体系的JIS键盘有些特殊键码:`無変換(Muhenkan)`, `変換(Henkan)`, `ひらがな(hiragana)` 在OSX下无法被识别,可以尝试通过以下配置借助 **Seil** 来启用这些键。 - -* 在PC键盘中启用NFER键 -* 在PC键盘中启用XFER键 -* 在PC键盘中启用KATAKANA键 - -https://pqrs.org/osx/karabiner/seil.html - - -## RN-42蓝牙模块与Karabiner的兼容性问题 -Karabiner - Mac OSX系统下的键映射工具 - 默认会忽略RN-42模块的输入事件。须在Karabiner开启相关选项来支持你的键盘。 -https://github.com/tekezo/Karabiner/issues/403#issuecomment-102559230 -这个问题的其它详细信息参见 -https://github.com/tmk/tmk_keyboard/issues/213 -https://github.com/tekezo/Karabiner/issues/403 - - -## Esc和`位于同一个键位 - -参见[Grave Escape](zh-cn/feature_grave_esc.md)功能. - -## Mac OSX下的弹出功能 -`KC_EJCT` 在OSX下可用。 https://github.com/tmk/tmk_keyboard/issues/250 -Windows 10应该是忽略了这个键码,Linux/Xorg能识别到,但默认没有映射处理。 - -目前尚不清楚Apple键盘上弹出键到底是啥,HHKB在Mac模式下使用 `F20` 来作为弹出键(`Fn+f`),但应该和Apple的弹出键码不是一回事儿。 - -## 在 `action_util.c` 中的 `weak_mods` 和 `real_mods` 是什么东西? -___待完善的内容___ - -real_mods保存的是现实的/物理上的修饰键状态,而weak_mods保存的是虚拟的或临时的修饰键状态,且不应该影响到真实的修饰键的状态。 - -例如你按住了物理键盘上的左shift键,又输入了 ACTION_MODS_KEY(LSHIFT, KC_A), - -在weak_mods下, -* (1) 按住左shift: real_mods |= MOD_BIT(LSHIFT) -* (2) 按下 ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods |= MOD_BIT(LSHIFT) -* (3) 松开 ACTION_MODS_KEY(LSHIFT, KC_A): weak_mods &= ~MOD_BIT(LSHIFT) -real_mods依然保留着修饰键的状态值。 - -非weak_mods时, -* (1) 按住左shift: real_mods |= MOD_BIT(LSHIFT) -* (2) 按下 ACTION_MODS_KEY(LSHIFT, KC_A): real_mods |= MOD_BIT(LSHIFT) -* (3) 松开 ACTION_MODS_KEY(LSHIFT, KC_A): real_mods &= ~MOD_BIT(LSHIFT) -这时real_mods失去了‘物理键左shift’的状态值。 - -在键盘事件发送时,weak_mods会与real_mods求逻辑或。 -https://github.com/tmk/tmk_core/blob/master/common/action_util.c#L57 diff --git a/docs/zh-cn/faq_misc.md b/docs/zh-cn/faq_misc.md deleted file mode 100644 index d01caba3bebf..000000000000 --- a/docs/zh-cn/faq_misc.md +++ /dev/null @@ -1,108 +0,0 @@ -# 其它 FAQ - - - -## 怎么对键盘进行测试? :id=testing - -测试键盘就简单直接,把每个按键按一遍后确认发送的是正确的就行。也可以使用[QMK配置器](https://config.qmk.fm/#/test/)的测试模式检查键盘,即便这键盘没有运行着QMK。 - -## 安全措施 - -你应该不想见到键盘变砖,变得不能再刷写固件。这里给出了一些非常危险(或相反不太危险)的因素。 - -- 如果你的键盘没有RESET键,在你需要进入DFU模式时,不得不需要用螺丝刀打开后盖去按PCB上的RESET键。 -- 把 tmk_core/common 下的文件搞乱的话,容易导致键盘无法使用 -- .hex文件太大的话也会引起问题。`make dfu` 会先擦除存储块,再检查固件大小(哎呀,顺序错了),此时发现错误进而导致刷写失败,键盘停留在DFU模式下。 - - 因此,请留意.hex文件尺寸有大小限制,例如在Planck上是十六进制7000(十进制的28672) - -``` -Linking: .build/planck_rev4_cbbrowne.elf [OK] -Creating load file for Flash: .build/planck_rev4_cbbrowne.hex [OK] - -Size after: - text data bss dec hex filename - 0 22396 0 22396 577c planck_rev4_cbbrowne.hex -``` - - - 上面的文件大小是22396/577ch, 小于28672/7000h - - 任何合适的其它.hex文件,都可以尝试加载 - - 在键盘的Makefile中你添加的一些配置也会额外占用空间,在使用BOOTMAGIC_ENABLE, - MOUSEKEY_ENABLE, EXTRAKEY_ENABLE, CONSOLE_ENABLE, API_SYSEX_ENABLE - 时请留意 -- DFU工具/不会/允许bootloader被覆写(除非你往DFU工具上塞自己的东西),这个风险不大。 -- EEPROM的写循环一般是 100000(100k)次,不应不停地持续重复地刷写固件,不然很快就烧毁了。 - -## NKRO 不好使 -首先请确保在编译固件时有在**Makefile**中启用 `NKRO_ENABLE` - -如果依旧不行,尝试一下 `Magic` **N** 指令(默认是左Shift+右Shift+N),这个指令可以让键盘在**NKRO**和**6KRO**模式间临时切换。有的场景下**NKRO**无法工作必须切换到**6KRO**模式,比如在BIOS中操作时。 - -如果你的固件编译时指定了 `BOOTMAGIC_ENABLE` ,则需要使用 `BootMagic`**N** 指令(默认是空格+N)。这个配置保存在EEPROM中,断电也会留存。 - -https://github.com/tmk/tmk_keyboard#boot-magic-configuration---virtual-dip-switch - - -## 轨迹球需要复位电路 (PS/2鼠标支持) -缺失复位电路的情况下,由于不正确的硬件初始化,可能会导致设备不稳定,具体请参阅TPM754的电路原理图: - -- https://geekhack.org/index.php?topic=50176.msg1127447#msg1127447 -- https://www.mikrocontroller.net/attachment/52583/tpm754.pdf - - -## 无法读到大于16的矩阵列 -当列数大于16时,在 [matrix.h] 中的 `read_cols()` 中请用 `1UL<<16` 替代 `1<<16`。 - -在C语言中,对于AVR上的 `1`,会被视作一种[16位]的[整形(int)]类型,因此无法左移超过15位。因此 `1<<16` 的计算结果会错误地变成0。解决办法就是将类型改为[无符号长整形(unsigned long)]类型的 `1UL`。 - -https://deskthority.net/workshop-f7/rebuilding-and-redesigning-a-classic-thinkpad-keyboard-t6181-60.html#p146279 - -## 有些额外的按键不好使(系统,音频控制键) -在QMK的 `rules.mk` 中须定义 `EXTRAKEY_ENABLE` - -``` -EXTRAKEY_ENABLE = yes # 音频及系统控制 -``` - -## 无法从休眠唤醒 - -在Windows的**电源管理**的**设备管理**中,检查 `允许该设备唤醒计算机` 选项,同时检查一下BIOS中的相关设置,任意一个按键都应该能将计算机从休眠状态唤醒。 - -## 在使用Arduino? - -**注意Arduino的引脚编号与芯片的引脚编号是不同的**。例如,Arduino的 `D0` 引脚并不是 `PD0`,请对照其电路图检查电路。 - -- https://arduino.cc/en/uploads/Main/arduino-leonardo-schematic_3b.pdf -- https://arduino.cc/en/uploads/Main/arduino-micro-schematic.pdf - -Arduino Leonardo 以及 micro 使用的是**ATMega32U4**因此可以用TMK,但bootloader可能会是个麻烦的问题。 - -## 启用JTAG - -默认情况下,键盘启动后JTAG调试接口就被禁用了。支持JTAG的MCU出场时会带着 `JTAGEN` 保险丝,而键盘因为需要这部分MCU的引脚去控制开关矩阵、LED等功能。 - -如果你希望启用JTAG,在 `config.h` 中添加定义: - -```c -#define NO_JTAG_DISABLE -``` - -## USB 3兼容性问题 -将设备从USB 3.x端口改插到USB 2.0端口能解决一些问题。 - - -## Mac相关兼容性问题 -### OS X 10.11 和 Hub -参见: https://geekhack.org/index.php?topic=14290.msg1884034#msg1884034 - - -## BIOS (UEFI) 配置/恢复 (休眠 & 唤醒)/电源循环 -有人反馈过他们的键盘在BIOS下或是从休眠状态唤醒后会不可用。 - -目前这个问题的原因还不清楚,但一些编译选项应该和这个问题有关,你可以在Makefile中禁用 `CONSOLE_ENABLE`, `NKRO_ENABLE`, `SLEEP_LED_ENABLE` 或其他的试一试。 - -更多信息: -- https://github.com/tmk/tmk_keyboard/issues/266 -- https://geekhack.org/index.php?topic=41989.msg1967778#msg1967778 diff --git a/docs/zh-cn/feature_grave_esc.md b/docs/zh-cn/feature_grave_esc.md deleted file mode 100644 index 1795a508efe7..000000000000 --- a/docs/zh-cn/feature_grave_esc.md +++ /dev/null @@ -1,39 +0,0 @@ -# Grave Escape - - - -*译注:Grave键即标准键盘中Tab键上方的 ` 键,该符号用于英法语等西语体系,辅助调整发音,中文中没有对应概念;Escape即Esc键* - -若你使用60%或其它没有Fn键配列的键盘,会留意到没有独立的Escape键。Grave Escape功能可以让Grave键(`及`~`)与Escape共享一个按键 - -## 使用方法 - -在配列中使用 `QK_GESC` 替换 `KC_GRAVE` (一般都在`1`键左边)。默认点击会输出 `KC_ESC`,按下Shift或GUI键时,点击会输出 `KC_GRV` - -## 操作系统视角 - -假如翠花按下GESC键,系统接收到的是KC_ESC字符。若翠花按住Shift再按下GESC,将输出 `~` 或是反引号。若翠花按住GUI/CMD/Win键,将仅输出`字符 - -## 键码 - -|键 |别名 |描述 | -|---------|-----------|------------------------------------------------------------------| -|`QK_GESC`|`GRAVE_ESC`|单击输出Escape, 按住Shift或GUI时输出` | - -### 须留意 - -在macOS上 Command+`默认行为是“移动焦点到下一个窗口”,因此不会输出反引号。另外,即便在键盘配置中更改过快捷键,终端程序(Terminal)也通常会将这个操作视为循环切换窗口 - -## 配置 - -有几种键组合可以变更这种行为,如Windows下的Control+Shift+Escape、macOS下的Command+Option+Escape。若要调整,可以在 `config.h` 中通过 `#define` 配置 - -|定义 |描述 | -|--------------------------|-----------------------------------------| -|`GRAVE_ESC_ALT_OVERRIDE` |按住Alt时输出Escape | -|`GRAVE_ESC_CTRL_OVERRIDE` |按住Control时输出Escape | -|`GRAVE_ESC_GUI_OVERRIDE` |按住GUI时输出Escape | -|`GRAVE_ESC_SHIFT_OVERRIDE`|按住Shift时输出Escape | diff --git a/docs/zh-cn/feature_space_cadet.md b/docs/zh-cn/feature_space_cadet.md deleted file mode 100644 index e3dab9c72705..000000000000 --- a/docs/zh-cn/feature_space_cadet.md +++ /dev/null @@ -1,70 +0,0 @@ -# Space Cadet: The Future, Built In - - - - -*译注:Space Cadet来源于(在西方早期程序员中)著名的键盘Space Cadet Keyboard,具体信息参见下面的链接或[维基百科](https://en.wikipedia.org/wiki/Space-cadet_keyboard)* - -Steve Losh 在 [Space Cadet Shift](https://stevelosh.com/blog/2012/10/a-modern-space-cadet/) 详细地描述了该功能. 简而言之,点击左Shift时,会输出左括号;点击右Shift时,会输出右括号。如果按住Shift键,常规的Shift将正常工作。这功能实际上和听起来的一样爽,更爽的是现在连Control和Alt也支持! - -## 使用指南 - -首先,在你的配列中完成以下任一项: -- 替换左Shift为 `KC_LSPO`(左Shift,左括号),替换右Shift为 `KC_RSPC`(右Shift,右括号)。 -- 替换左Control为 `KC_LCPO`(左Control,左括号),替换右Control为 `KC_RCPC`(右Control,右括号)。 -- 替换左Alt为 `KC_LAPO`(左Alt,左括号),替换右Alt为 `KC_RAPC`(右Alt,右括号)。 -- 替换任意一个Shift为 `KC_SFTENT`(右Shift,回车)。 - -## 键码 - -|键码 |描述 | -|-----------|-----------------------------| -|`KC_LSPO` |按住时左Shift,点击时 `(` | -|`KC_RSPC` |按住时右Shift,点击时 `)` | -|`KC_LCPO` |按住时左Control,点击时 `(` | -|`KC_RCPC` |按住时右Control,点击时 `)` | -|`KC_LAPO` |按住时左Alt,点击时 `(` | -|`KC_RAPC` |按住时右Alt,点击时 `)` | -|`KC_SFTENT`|按住时右Shift,点击时回车 | - -## 须留意 - -同时按下两边的Shift键时会与Space Cadet功能冲突。请参见[指令功能](zh-cn/feature_command.md)以了解如何解决,也可以在 `rules.mk` 中禁用指令: - -```make -COMMAND_ENABLE = no -``` - -## 配置 - -默认情况下Space Cadet假设键盘布局为US ANSI,如果你的布局使用不同的括号符,可以在 `config.h` 中重定义。可以修改修饰键点击时发送的字符,亦或阻止修饰键工作。这个新的配置项依次绑定了三个键码:按住或组合其它键使用时的修饰键;点击时发送的修饰键点击(`Tap Modifier`)(在 `KC_TRNS` 中没有修饰键时);最后是点击时发送的键码。请记住,例如'KC_RSFT'按住时点击 `KC_KSPO` 及 `KC_TRNS` 时,修饰键依旧会对键码生效,即属于修饰键点击。 - -|定义 |默认值 |描述 | -|----------------|-------------------------------|----------------------------------------------------------------| -|`LSPO_KEYS` |`KC_LSFT, LSPO_MOD, LSPO_KEY` |按住时发送`KC_LSFT`,点击时发送 `LSPO_MOD` 及 `LSPO_KEY` 定义的键码. | -|`RSPC_KEYS` |`KC_RSFT, RSPC_MOD, RSPC_KEY` |按住时发送`KC_RSFT`,点击时发送 `RSPC_MOD` 及 `RSPC_KEY` 定义的键码. | -|`LCPO_KEYS` |`KC_LCTL, KC_LSFT, KC_9` |按住时发送`KC_LCTL`,点击时发送 `KC_LSFT` 及 `KC_9`. | -|`RCPC_KEYS` |`KC_RCTL, KC_RSFT, KC_0` |按住时发送`KC_RCTL`,点击时发送 `KC_RSFT` 及 `KC_0`. | -|`LAPO_KEYS` |`KC_LALT, KC_LSFT, KC_9` |按住时发送`KC_LALT`,点击时发送 `KC_LSFT` 及 `KC_9`. | -|`RAPC_KEYS` |`KC_RALT, KC_RSFT, KC_0` |按住时发送`KC_RALT`,点击时发送 `KC_RSFT` 及 `KC_0`. | -|`SFTENT_KEYS` |`KC_RSFT, KC_TRNS, SFTENT_KEY` |按住时发送`KC_RSFT`,点击时发送 `SFTENT_KEY`. | -|`SPACE_CADET_MODIFIER_CARRYOVER` |*未定义* |在尝试触发其它修饰键的修饰键点击前,暂存目前的修饰键。这在尝试触发Space Cadet前频繁发生修饰键提前松开时会有用。(译注[^1]) | - - -## 过时的配置项 - -以下是一些内部用于向后兼容的定义,目前仍可以使用,但上面的定义适用性要强得多。例如,若你点击 `KC_LSPO` 时不想按住修饰键,在旧定义中只有一个办法,使用 `DISABLE_SPACE_CADET_MODIFIER`。但现在可以定义为:`#define LSPO_KEYS KC_LSFT, KC_TRNS, KC_9`,效果是在按住按键时触发左Shift,点击则发送 `KC_9`。 - -|定义 |默认值 |描述 | -|------------------------------|-------------|-------------------------------------| -|`LSPO_KEY` |`KC_9` |点击左Shift时发送的键码 | -|`RSPC_KEY` |`KC_0` |点击右Shift时发送的键码 | -|`LSPO_MOD` |`KC_LSFT` |应用在 `LSPO_KEY` 上的修饰键 | -|`RSPC_MOD` |`KC_RSFT` |应用在 `RSPC_KEY` 上的修饰键 | -|`SFTENT_KEY` |`KC_ENT` |点击Shift时发送的键码 | -|`DISABLE_SPACE_CADET_MODIFIER`|*未定义* |定义时将阻止修饰键应用在Space Cadet上 | - -[^1]这句实在是绕,不能确保翻译到位,请参考英文文档 diff --git a/docs/zh-cn/flashing.md b/docs/zh-cn/flashing.md deleted file mode 100644 index 559b8742d037..000000000000 --- a/docs/zh-cn/flashing.md +++ /dev/null @@ -1,329 +0,0 @@ -# 刷写指引及Bootloader资料 - - - -用于键盘的bootloader有很多种,几乎每一种都在使用私有的刷写协议及工具。幸运的是,形如[QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)这样的工程目标就是尽量支持这些工具,本文会探讨各种bootloader的差异,以及可用的刷写方案。 - -针对基于AVR的键盘,QMK会自动检查所要刷写的 `.hex` 文件大小是否与在 `rules.mk` 中设置的 `BOOTLOADER` 值所匹配,同时会输出字节大小信息(及最大限制)。 - -同时也可以使用CLI工具刷写键盘,执行: -``` -$ qmk flash -kb -km -``` -更多信息参见文档[`qmk flash`](zh-cn/cli_commands.md#qmk-flash)。 - -## Atmel DFU - -Atmel系列的DFU bootloader默认配备在所有USB AVR系列上(16/32U4RC除外),广泛用于一些PCB上具备私有集成电路模块(IC)的键盘上(老款OLKB、Clueboards等)。有些使用的是LUFA实现的DFU bootloader,或是QMK的分支版本(新款OLKB),后者对硬件功能进行了扩充加强。 - -为保证对DFU bootloader的兼容性,请确保在 `rules.mk` 中存在如下部分内容(可选的值还有 `lufa-dfu` 或 `qmk-dfu`): - -```make -# 选择Bootloader -BOOTLOADER = atmel-dfu -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具) -* [dfu-programmer](https://github.com/dfu-programmer/dfu-programmer) / QMK中将构建目标设为 `:dfu`(推荐的命令行工具) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码 - * 如果PCB上有 `RESET` 键,点击之 - * 快速短接一下RST到GND -2. 等待操作系统识别到设备 -3. 清空flash存储数据(如果使用QMK工具箱或CLI的 `make`会自动进行) -4. 将.hex文件刷写进去 -5. 重置设备进入应用模式(如上,会自动进行) - -### QMK DFU - -QMK维护了[一个LUFA DFU bootloader的分支版本](https://github.com/qmk/lufa/tree/master/Bootloaders/DFU),其可以进行一次矩阵扫描来退出bootloader进入应用模式,同时会让LED闪烁或蜂鸣器响一声。若要启用该功能,将以下定义添加到 `config.h`: - -```c -#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW -#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW -// 可选: -//#define QMK_LED E6 -//#define QMK_SPEAKER C6 -``` -目前来讲不推荐将 `QMK_ESC` 键设置成与[Bootmagic](zh-cn/feature_bootmagic.md)同一个键,否则按下该键时只会让MCU在bootloader模式上反复进出。 - -制造商及型号字符串自动从 `config.h` 中获取,并会在型号后追加 " Bootloader"。 - -要生成该bootloader,需指定 `bootloader` 构建目标,即 `make planck/rev4:default:bootloader`。要生成可部署到正式产品的.hex文件(同时包含QMK及bootloader),使用 `production` 构建目标,即 `make planck/rev4:default:production`。 - -### `make` 构建目标 - -* `:dfu`: 每5秒检测一次直到发现可用的DFU设备,然后进行固件刷写。 -* `:dfu-split-left` 和 `:dfu-split-right`: 同 `:dfu` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Elite-C的分体式键盘这是理想的方法。 - -## Caterina - -Arduino及其仿制板使用[Caterina bootloader](https://github.com/arduino/ArduinoCore-avr/tree/master/bootloaders/caterina)或某种变体(使用Pro Micro或其仿制芯片、Pololu A-Star等构建的所有键盘),并基于虚拟串口使用AVR109协议进行通信。 - -为确保对Caterina bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = caterina -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具) -* [avrdude](https://www.nongnu.org/avrdude/) QMK中须基于 `avr109` 编程器 / `:avrdude` 构建目标 (推荐的命令行工具) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写;一些型号需要你在750ms内重置两次): - * 点击 `QK_BOOT` 键码 - * 如果PCB上有 `RESET` 键,点击之 - * 快速短接一下RST到GND -2. 等待操作系统识别到设备 -3. 将.hex文件刷写进去 -4. 等待设备自动重置 - -### `make` 构建目标 - -* `:avrdude`: 每5秒检测一次直到发现可用的Caterina设备(通过检测新COM端口),然后进行固件刷写。 -* `:avrdude-loop`: 同 `:avrdude` 一样刷写固件,但会在一个设备刷写完后再次尝试刷写。主要用于批量刷写设备。按 Ctrl+C 以终止循环检测。 -* `:avrdude-split-left` 和 `:avrdude-split-right`: 同 `:avrdude` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Pro Micro的分体式键盘这是理想的方法。 - -## HalfKay - -HalfKay是一款由PJRC开发的超精简的bootloader,且呈现为HID设备(因此不需要额外的驱动),在所有的Teensys,即"the 2.0",上已经预刷写过。该bootloader目前是闭源的,因此一旦覆写(即通过ISP刷入其它bootloader)掉,就无法复原了。 - -为确保对Halfkay bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = halfkay -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具) -* [Teensy Loader Command Line](https://www.pjrc.com/teensy/loader_cli.html) / QMK中将构建目标设为 `:teensy`(推荐的命令行工具) -* [Teensy Loader](https://www.pjrc.com/teensy/loader.html) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写): - * 点击 `QK_BOOT` 键码 - * 如果Teensy上或PCB上有 `RESET` 键,点击之 - * 快速短接一下RST到GND -2. 等待操作系统识别到设备 -3. 将.hex文件刷写进去 -4. 重置设备进入应用模式(可能会自动进行) - -## USBasploader - -USBasploader是一款来源于[Objective Development](https://www.obdev.at/products/vusb/usbasploader.html)的bootloader。它通过模拟出一个USBasp ISP编程器来运行V-USB以用于一些形如ATmega328P这样的“非USB AVR芯片”。 - -为确保对USBasploader bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = usbasploader -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具) -* [avrdude](https://www.nongnu.org/avrdude/) QMK中须基于 `usbasp` 编程器 / `:usbasp` 构建目标(推荐的命令行工具) -* [AVRDUDESS](https://github.com/zkemble/AVRDUDESS) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码 - * 在按住 `BOOT` 按钮时,快速点击一下PCB上的 `RESET` -2. 等待操作系统识别到设备 -3. 将.hex文件刷写进去 -4. 点击PCB上的 `RESET` 按钮或将RST短接至GND一下。 - -## BootloadHID - -BootloadHID是一款用于AVR微控制器的bootloader,其呈现为HID输入设备,和HalkKay很像,因此在Windows下也无需安装驱动。 - -为确保对bootloadHID bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = bootloadhid -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具) -* [bootloadHID CLI](https://www.obdev.at/products/vusb/bootloadhid.html) / QMK中将构建目标设为 `:bootloadhid`(推荐的命令行工具) -* [HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) - - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码 - * 在按住“盐键”(salt key)时插入键盘 - 在PS2AVRGB板上,通常在MCU的A0及B0引脚上有这个按键,否则请查看键盘的使用说明。 -2. 等待操作系统识别到设备 -3. 将.hex文件刷写进去 -4. 重置设备到应用模式(可能会自动进行) - -### QMK HID - -QMK维护了[一个LUFA HID bootloader的分支版本](https://github.com/qmk/lufa/tree/master/Bootloaders/HID),通过USB HID节点设备进行刷写,工作模式类似于PJRC的Teensy Loader刷写器以及HalfKay bootloader。其可以进行一次矩阵扫描来退出bootloader进入应用模式,同时会让LED闪烁或蜂鸣器响一声。 - -为确保对QMK HID bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = qmk-hid -``` - -要启用额外的功能支持,请添加如下定义至 `config.h`: - -```c -#define QMK_ESC_OUTPUT F1 // COL pin if COL2ROW -#define QMK_ESC_INPUT D5 // ROW pin if COL2ROW -// 可选: -//#define QMK_LED E6 -//#define QMK_SPEAKER C6 -``` - -目前来讲不推荐将 `QMK_ESC` 键设置成与[Bootmagic Lite](zh-cn/feature_bootmagic.md)同一个键,否则按下该键时只会让MCU在bootloader模式上反复进出。 - -制造商及型号字符串自动从 `config.h` 中获取,并会在型号后追加 " Bootloader"。 - -要生成该bootloader,需指定 `bootloader` 构建目标,即 `make planck/rev4:default:bootloader`。要生成可部署到正式产品的.hex文件(同时包含QMK及bootloader),使用 `production` 构建目标,即 `make planck/rev4:default:production`。 - -兼容的刷写工具: - -* TBD - * 目前只能选择使用该 [Python脚本](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp_python), 或从LUFA仓库中构建[`hid_bootloader_cli`](https://github.com/qmk/lufa/tree/master/Bootloaders/HID/HostLoaderApp)。Homebrew也许(即将)能直接支持(通过 `brew install qmk/qmk/hid_bootloader_cli`)。 - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码 - * 如果PCB上有 `RESET` 键,点击之 - * 快速短接一下RST到GND -2. 等待操作系统识别到设备 -4. 将.hex文件刷写进去 -5. 重置设备进入应用模式(可能会自动进行) - -### `make` 构建目标 - -* `:qmk-hid`: 每5秒检测一次直到发现可用的DFU设备,然后进行固件刷写。 - -## STM32/APM32 DFU - -所有的STM32及APM32 MCU系列,除F103型号外(参见[STM32duino小节](#stm32duino))都在出场时预装了bootloader且无法修改或删除。 - -为确保对STM32-DFU bootloader的兼容性,请添加如下代码块至 `rules.mk`(可选替代项为 `apm32-dfu`): - -```make -# 选择Bootloader -BOOTLOADER = stm32-dfu -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具) -* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写): - * 点击 `QK_BOOT` 键码(对STM32F042设备可能无效) - * 如果有重置电路,点击PCB上的 `RESET` 键;有些主控板上可能会有一个开关需要先打开 - * 否则,你需要将 `BOOT0` 接线到VCC(通过 `BOOT0` 按钮或跳线),短接 `RESET` 至GND(通过 `RESET` 按钮或条线),然后断开 `BOOT0` 的接线。 -2. 等待操作系统识别到设备 -3. 将.bin文件刷写进去 -4. 重置设备进入应用模式(可能会自动进行) - -### `make` 构建目标 - -* `:dfu-util`: 每5秒检测一次直到发现可用的STM32 bootloader设备,然后进行固件刷写。 -* `:dfu-util-split-left` 和 `:dfu-util-split-right`: 同 `:dfu-util` 一样会刷写固件,但额外地会设置手性设置到EEPROM中,对于基于Proton-C的分体式键盘这是理想的方法。 -* `:st-link-cli`: 通过ST-Link CLI工具集而非dfu-util进行刷写,需要有ST-Link电子狗。 -* `:st-flash`: 通过[STLink工具](https://github.com/stlink-org/stlink)内的 `st-flash` 工具而非dfu-util进行刷写,需要有ST-Link电子狗。 - -## STM32duino :id=stm32duino - -该bootloader几乎是STM32F103板专用,该型号出厂不带USB DFU bootloader。其源代码及预编译好的二进制文件[在这里](https://github.com/rogerclarkmelbourne/STM32duino-bootloader)。 - -为确保对STM32duino bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = stm32duino -``` - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases) (推荐的图形化工具) -* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式(进入该模式后只有7秒时间可以刷写): - * 点击 `QK_BOOT` 键码(对STM32F042设备可能无效) - * 如果有重置电路,点击PCB上的 `RESET` 键;有些主控板上可能会有一个开关需要先打开 - * 否则,你需要将 `BOOT0` 接线到VCC(通过 `BOOT0` 按钮或跳线),短接 `RESET` 至GND(通过 `RESET` 按钮或条线),然后断开 `BOOT0` 的接线。 -2. 等待操作系统识别到设备 -3. 将.bin文件刷写进去 -4. 重置设备进入应用模式(可能会自动进行) - -## Kiibohd DFU - -Input Club出品的键盘使用NXP Kinetis微控制器而非STM32,并使用了独有的[自制bootloader](https://github.com/kiibohd/controller/tree/master/Bootloader),然而处理器 及协议上两者大部分是一致的。 - -在 `rules.mk` 中该bootloader的设置项为 `kiibohd`,但既然该bootloader仅用在Input Club主控板上,就不必要设置到键映射或是用户级了。 - -兼容的刷写工具: - -* [QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)(推荐的图形化工具) -* [dfu-util](https://dfu-util.sourceforge.net/) / QMK中将构建目标设为 `:dfu-util`(推荐的命令行工具) - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码(有可能只能进入到“安全”bootloader模式,参见[这里](https://github.com/qmk/qmk_firmware/issues/6112)) - * 如果PCB上有 `RESET` 键,点击之 -2. 等待操作系统识别到设备 -3. 将.bin文件刷写进去 -4. 重置设备进入应用模式(可能会自动进行) - -## tinyuf2 - -键盘可以考虑支持tinyuf2 bootloader,目前唯一支持的设备是F401/F411 blackpill。 - -在 `rules.mk` 中该bootloader的设置项为 `tinyuf2`,也可指定到键映射及用户级中。 - -为确保对tinyuf2 bootloader的兼容性,请添加如下代码块至 `rules.mk`: - -```make -# 选择Bootloader -BOOTLOADER = tinyuf2 -``` - -兼容的刷写工具: - -* 任何具备文件拷贝能力的程序,如 _macOS Finder_ 或 _Windows Explorer_ *。 - -刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码 - * 双击PCB上的 `nRST` 键 -2. 等待操作系统识别到设备 -3. 将.uf2文件拷贝到新出现的USB存储设备上 -4. 等待设备恢复可用状态 diff --git a/docs/zh-cn/flashing_bootloadhid.md b/docs/zh-cn/flashing_bootloadhid.md deleted file mode 100644 index c5e944f94779..000000000000 --- a/docs/zh-cn/flashing_bootloadhid.md +++ /dev/null @@ -1,75 +0,0 @@ -# BootloadHID刷写指引及资料 - - - -ps2avr(GB)基于一片ATmega32A微控制器及特殊的bootloader,无法使用常规的QMK方法进行刷写。 - -常规刷写过程: - -1. 使用如下任一方式进入bootloader模式: - * 点击 `QK_BOOT` 键码(一些设备上不管用) - * 在按住“盐键”(salt key)时插入键盘(该键一般会在键盘使用说明上写明) -2. 等待操作系统识别到设备 -3. 将.hex文件刷写进去 -4. 重置设备到应用模式(可能会自动进行) - -## 用于bootloadHID刷写的构建目标 - -?> 使用QMK安装脚本,具体[参见这里](zh-cn/newbs_getting_started.md),所需的bootloadHID工具应自动被安装上。 - -若希望通过命令行进行刷写,通过如下命令指定 `:bootloadhid` 构建目标: - - make ::bootloadhid - -## 基于图形化界面的刷写方法 - -### Windows -1. 下载[HIDBootFlash](http://vusb.wikidot.com/project:hidbootflash) -2. 重置键盘 -3. 确认VID为 `16c0` 且PID为 `05df` -4. 点击 `查找设备(Find Device)` 并确认目标键盘可见 -5. 点击 `打开.hex文件(Open .hex File)` 并定位到你创建的.hex文件 -6. 点击 `刷写设备(Flash Device)` 并等待刷写完毕 - -## 在命令行中进行刷写 - -1. 重置键盘 -2. 通过输入 `bootloadHID -r` 并追加 `.hex` 文件的路径进行主控板的刷写 - -### Windows系统上手动安装 -针对MSYS2: -1. 下载BootloadHID固件包:https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -2. 使用合适的工具解压,如7-Zip -3. 将解压出的 `commandline/bootloadHID.exe` 拷贝至MSYS目录下,一般是 `C:\msys64\usr\bin` - -针对Windows本地环境刷写,`bootloadHID.exe` 可以直接在非MSYS2环境下执行。 - -### Linux系统上手动安装 -1. 安装libusb开发依赖项: - ```bash - # 该操作具体取决于系统 - Debian下可以这样 - sudo apt-get install libusb-dev - ``` -2. 下载BootloadHID固件包: - ``` - wget https://www.obdev.at/downloads/vusb/bootloadHID.2012-12-08.tar.gz -O - | tar -xz -C /tmp - ``` -3. 构建bootloadHID可执行程序: - ``` - cd /tmp/bootloadHID.2012-12-08/commandline/ - make - sudo cp bootloadHID /usr/local/bin - ``` - -### MacOS系统上手动安装 -1. 执行以下命令安装Homebrew: - ``` - /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" - ``` -2. 安装以下包: - ``` - brew install --HEAD https://raw.githubusercontent.com/robertgzr/homebrew-tap/master/bootloadhid.rb - ``` diff --git a/docs/zh-cn/getting_started_docker.md b/docs/zh-cn/getting_started_docker.md deleted file mode 100644 index 038f17f9ac24..000000000000 --- a/docs/zh-cn/getting_started_docker.md +++ /dev/null @@ -1,59 +0,0 @@ -# Docker快速上手指引 - - - -本工程包含了一套Docker工作流,可以方便地在不更改你主系统环境情况下完成新固件文件的构建工作。这同时也保证了在你拉取该工程代码后的编译环境与其他人以及QMK开发者的一致。当你需要其他人协助你排查遇到的问题时会方便很多。 - -## 需求 - -核心需求是一个已安装的可用的 `docker` 或 `podman`。 -* [Docker CE](https://docs.docker.com/install/#supported-platforms) -* [Podman](https://podman.io/getting-started/installation) - -## 用法 - -拉取QMK仓库到本地(包括所有的子模块): - -```bash -git clone --recurse-submodules https://github.com/qmk/qmk_firmware.git -cd qmk_firmware -``` - -执行以下命令构建键映射: -```bash -util/docker_build.sh : -# 例: util/docker_build.sh planck/rev6:default -``` - -如上可以构建所需的键盘/键映射,可用于刷写的 `.hex` 及 `.bin` 输出文件存放在QMK目录下。如果省略了 `:keymap` 参数,所有的键映射都会被编译。留意编译参数格式与 `make` 构建时的一致。 - -同时也支持直接从Docker中编译和刷写,只需要指定 `target`: - -```bash -util/docker_build.sh keyboard:keymap:target -# 例: util/docker_build.sh planck/rev6:default:flash -``` - -可以不带参数地执行该脚本,其会依次要求你输入这些参数,也许你会觉得这样更好用: - -```bash -util/docker_build.sh -# 从输入中读取参数 (留空则构建所有的键盘/键映射) -``` - -可以通过设置环境变量 `RUNTIME` 为想使用的容器运行时的名称或路径来指定运行时,默认其会检测并自动选取docker或podman,相比于podman会更倾向于用docker。 - -```bash -RUNTIME="podman" util/docker_build.sh keyboard:keymap:target -``` - -## FAQ - -### 为什么我无法在我的Windows/macOS下刷写固件 - -在Windows及macOS上,需要有[Docker Machine](http://gw.tnode.com/docker/docker-machine-with-usb-support-on-windows-macos/)运行着,配置过程很繁琐,因此我们没有做推荐。请考虑使用[QMK工具箱](https://github.com/qmk/qmk_toolbox)。 - -!> Windows下需要启用[Hyper-V](https://docs.microsoft.com/en-us/virtualization/hyper-v-on-windows/quick-start/enable-hyper-v)才能运行Docker,这也意味着它无法运行在没有Hyper-V的Windows版本下,如Windows 7,Windows 8及**Windows 10家庭版**。 diff --git a/docs/zh-cn/getting_started_github.md b/docs/zh-cn/getting_started_github.md deleted file mode 100644 index 2a5ec8ca4f47..000000000000 --- a/docs/zh-cn/getting_started_github.md +++ /dev/null @@ -1,69 +0,0 @@ -# 如何在QMK中使用GitHub - - - -对不熟悉 GitHub 的人来说,使用GitHub 可能会有些难度。此教程会教您 fork 和 clone QMK,以及向 QMK 提交 pull request 。 - -?> 本教程假设您已安装GitHub,并且您喜欢使用命令行工作。 - -首先 [GitHub上的QMK页面](https://github.com/qmk/qmk_firmware), 您能看到右上方有个按钮写着"Fork": - -![从GitHub上分叉](https://i.imgur.com/8Toomz4.jpg) - -如果你是某组织成员,你将需要选择分叉到哪个账户。一般情况下, 你是想要分叉到你的私人账户下。当你完成分叉 (有时需要等一会), 点击"Clone or Download" 按钮: - -!从GitHub下载](https://i.imgur.com/N1NYcSz.jpg) - -你要选择 "HTTPS", 然后选择链接复制: - -![HTTPS链接](https://i.imgur.com/eGO0ohO.jpg) - -然后,在命令行输入`git clone --recurse-submodules `,然后粘贴你的链接: - -``` -user@computer:~$ git clone --recurse-submodules https://github.com/whoeveryouare/qmk_firmware.git -Cloning into 'qmk_firmware'... -remote: Enumerating objects: 9, done. -remote: Counting objects: 100% (9/9), done. -remote: Compressing objects: 100% (5/5), done. -remote: Total 183883 (delta 5), reused 4 (delta 4), pack-reused 183874 -Receiving objects: 100% (183883/183883), 132.90 MiB | 9.57 MiB/s, done. -Resolving deltas: 100% (119972/119972), done. -... -Submodule path 'lib/chibios': checked out '587968d6cbc2b0e1c7147540872f2a67e59ca18b' -Submodule path 'lib/chibios-contrib': checked out 'ede48346eee4b8d6847c19bc01420bee76a5e486' -Submodule path 'lib/googletest': checked out 'ec44c6c1675c25b9827aacd08c02433cccde7780' -Submodule path 'lib/lufa': checked out 'ce10f7642b0459e409839b23cc91498945119b4d' -``` - -现在你本地计算机有QMK的分叉了,你可以添加你的布局了, 为你的键盘编译并刷新固件吧。如果你觉得你的修改很不错, 你可以添加,提交,然后想你的分叉推出(pull)你的改变,像这样: - -``` -user@computer:~$ git add . -user@computer:~$ git commit -m "adding my keymap" -[master cccb1608] adding my keymap - 1 file changed, 1 insertion(+) - create mode 100644 keyboards/planck/keymaps/mine/keymap.c -user@computer:~$ git push -Counting objects: 1, done. -Delta compression using up to 4 threads. -Compressing objects: 100% (1/1), done. -Writing objects: 100% (1/1), 1.64 KiB | 0 bytes/s, done. -Total 1 (delta 1), reused 0 (delta 0) -remote: Resolving deltas: 100% (1/1), completed with 1 local objects. -To https://github.com/whoeveryouare/qmk_firmware.git - + 20043e64...7da94ac5 master -> master -``` - -现在你的改动已经在你GitHub上的分支中了 - 如果你回到这 (`https://github.com/你的GitHub账户名/qmk_firmware`) ,你可以点击下方所示按钮创建 "New Pull Request": - -![新的 Pull Request](https://i.imgur.com/DxMHpJ8.jpg) - -现在你可以看到你所做的一切 - 如果看起来不错, 就可以点击 "Create Pull Request"定稿了: - -![创建Pull Request](https://i.imgur.com/Ojydlaj.jpg) - -提交后,我们会开跟你说你的改动,要求您进行更改, 并最终接受您的更改!感谢您为QMK做的贡献 :) diff --git a/docs/zh-cn/getting_started_introduction.md b/docs/zh-cn/getting_started_introduction.md deleted file mode 100644 index 82d50355ebb5..000000000000 --- a/docs/zh-cn/getting_started_introduction.md +++ /dev/null @@ -1,59 +0,0 @@ -# 介绍 - - - -本页解释了使用QMK项目所需的基本信息。它假定您能熟练使用Unix shell,但您不熟悉C语言也不熟悉使用make编译。 - -## 基本QMK结构 - -QMK是[Jun Wako](https://github.com/tmk)的[tmk_keyboard](https://github.com/tmk/tmk_keyboard)工程的一个分叉。经过更改的TMK原始代码放在`tmk_core` 文件夹中。 QMK增加的新东西可以在 `quantum` 文件夹中找到。 键盘项目可以在 `handwired`(手动飞线) 和 `keyboard`(PCB键盘)这两个文件夹找到。 - -### 用户空间结构 - -在`users`文件夹里面的目录是每个用户的目录。这个文件夹里面放的是用户们在不同键盘都能用到的代码。详见[用户空间特性](zh-cn/feature_userspace.md) - -### 键盘项目结构 - -在`keyboards`文件夹和他的子文件夹`handwired`中就是各个键盘的项目了,比如`qmk_firmware/keyboards/clueboard`。内部结构与如下: - -* `keymaps/`: 可以构建的不同布局 -* `rules.mk`: 用来设置 "make" 命令默认选项的文件。别直接编辑这个文件,你应该使用具体某个布局的 `rules.mk`. -* `config.h`: 用于设置默认编译选项的文件。别直接编辑这个文件, 你应该使用具体某个布局的 `config.h`. - -### 布局结构 - -在各个布局的文件夹,你能找到以下文件。只有 `keymap.c` 是必要的, 如果其他文件找不到就会直接选择默认选项。 - -* `config.h`: 配置布局的选项 -* `keymap.c`: 布局的全部代码, 必要文件 -* `rules.mk`: 使能的QMK特性 -* `readme.md`:介绍你的布局,告诉别人怎么使用,附上功能说明。请将图片上传到imgur等图床(译注:imgur可能已被墙,为了方便国人访问,建议使用国内可以直接访问的图床)。 - -# `config.h` 文件 - -有三个重要的`config.h` 位置: - -* 键盘 (`/keyboards//config.h`) -* 用户空间 (`/users//config.h`) -* 布局 (`/keyboards//keymaps//config.h`) - -构建系统按照上述顺序自动获取配置文件。如果要覆盖由上一个 `config.h` 所做的设置,您需要首先为要更改的设置包含一些样板代码。 - -``` -#pragma once -``` - -要覆盖上一个 `config.h` 所做的设置,你要先 `#undef` 然后再 `#define` 这个设置. - -样板代码和设置看起来像这样: - -``` -#pragma once - -// 像下面那样覆盖设置(MY_SETTING指的是你要覆盖的设置项)! -#undef MY_SETTING -#define MY_SETTING 4 -``` diff --git a/docs/zh-cn/hand_wire.md b/docs/zh-cn/hand_wire.md deleted file mode 100644 index 97e80251fe95..000000000000 --- a/docs/zh-cn/hand_wire.md +++ /dev/null @@ -1,255 +0,0 @@ -# 手工搭建指南 - - - -## 模块清单 - -你需要的模块有:(*x*为你设计的键盘的键数) - -* QMK所兼容的主控板(Teensy, Pro-Micro, QMK Proton C 等) -* *x* 个键轴 (MX, Matias, Gateron 等) -* *x* 个通孔二极管(译注:即普通的直插二极管) -* 定位板及卫星轴 -* 电线 -* 电烙铁 -* 松香/焊油 -* 通风的环境/风扇通风 -* 剪线钳 - -可选地但比较有用的: - -* 剥线钳/一把锋利的剪刀 -* 镊子及小尖嘴钳 -* 焊台/一位助手 - -## 前期工作 - -组装PCB矩阵的方法多种多样,这份指引会描述一些基础信息并给出一些推荐方案。 - -既然我们要进行手工飞线搭建,这里就假设你已经有了定位板。如果你想构建完全定制化的配列,有 [ai03 Plate Generator](https://kbplate.ai03.me/) 以及 [Swillkb Plate & Case Builder](http://builder.swillkb.com/) 这样的工具可以助你设计出一个新的。 - -首先从安装键轴及卫星轴开始,考虑厚度及材质的影响,可能需要热熔胶来固定。 - -## 设计矩阵 :id=planning-the-matrix - -如果你在参考已有的手工搭建指南(比如[自制键盘固件目录](https://github.com/qmk/qmk_firmware/tree/master/keyboards/handwired)下的键盘),可以跳过该步骤,确保是按照文中的矩阵方案连线即可。 - -如果你的方案是将每个开关的一个引脚与两边的开关相连(行方向),另一个引脚与上下的开关相连(列方向),并串联一个二极管到一端,最常用的方案是二极管背对着连接到行方向的引脚(列向行)。即让远离二极管黑线一端连接到开关上(电流只能从一个方向通过二极管)。 - -可以很容易地设计出正交连接的键盘(如Planck)。 -(译注:这里的“正交”意思是行列方向连接规整) - -![Planck矩阵示例图](https://i.imgur.com/FRShcLD.png) -[作者:RoastPotatoe "如何手工搭建Planck键盘"](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/) (英文)内的图例 - -键盘配列越大,功能越丰富,则矩阵也会更复杂。[Keyboard Firmware Builder](https://kbfirmware.com/) 可以帮助你设计矩阵配列(下图为通过 [Keyboard Layout Editor](https://www.keyboard-layout-editor.com) 导出的全尺寸ISO键盘)。 - -![ISO键盘矩阵示例图](https://i.imgur.com/UlJ4ZDP.png) - -必须时刻留意矩阵的行列数总和不能超出控制器的IO引脚数,因此上图的方案可以使用 Proton C 或 Teensy++ 控制器,但常规 Teensy 或 Pro Micro 不行。 - -### 常见微控制器板 :id=common-microcontroller-boards - -| 控制器板 | 控制器方案 | # I/O引脚数 | 引脚图 | -| :------------ |:-------------:| ------:| ------ | -| Pro Micro* | ATmega32u4 | 20 | [链接](https://learn.sparkfun.com/tutorials/pro-micro--fio-v3-hookup-guide/hardware-overview-pro-micro#Teensy++_2.0) | -| Teensy 2.0 | ATmega32u4 | 25 | [链接](https://www.pjrc.com/teensy/pinout.html) | -| [QMK Proton C](https://qmk.fm/proton-c/) | STM32F303xC | 36 | [链接 1](https://i.imgur.com/RhtrAlc.png), [2](https://deskthority.net/wiki/QMK_Proton_C) | -| Teensy++ 2.0 | AT90USB1286 | 46 | [链接](https://www.pjrc.com/teensy/pinout.html#Teensy_2.0) | - -*Elite C 与 Pro Micro 除将 Micro USB 替换为 USB-C 外其余无差别。 - -一些主控板专门为手工接线设计,除可直接连接少量开关外还有额外的引脚,但这些通常会更贵一些,也更难掌控。 - -实装的 Postage mini 主控板 - -| 控制器板 | 控制器方案 | # I/O引脚数 | -| :------------ |:-------------:| ------:| -| [Swiss helper](https://www.reddit.com/r/MechanicalKeyboards/comments/8jg5d6/hand_wiring_this_might_help/) | ATmega32u4 | 20 | -| [Postage 主控板](https://github.com/LifeIsOnTheWire/Postage-Board/)| ATmega32u4| 25 | -| [Postage mini 主控板](https://geekhack.org/index.php?topic=101460.0)| ATmega32u4| 25 | - -## 矩阵布线 - -布线方案不是唯一的,要达成的效果是可以正确连接所有的焊点并不会出现预期外的短路。 - -公开的材料和技术方案: - -(译注:链接文章及标题恕不翻译) - -| 技术方案 | 示例 | 优点 | 缺点 | 图片 -| :-----------| :------- | :------ | :--- | :--- -| 间断开口的线缆 | [Sasha Solomon's Dactyl](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) 以及 [Cribbit's modern hand wire](https://geekhack.org/index.php?topic=87689.0) | 整洁 | 线缆开口的操作会有些困难 | ![开口的线缆](https://i.imgur.com/0GNIYY0.jpg) -| 适宜长度的线缆 | [u/xicolinguada's ortho build](https://www.reddit.com/r/MechanicalKeyboards/comments/c39k4f/my_first_hand_wired_keyboard_its_not_perfect_but/) | 剥线容易 | 较难固定位置 | ![适宜长度的线缆](https://i.imgur.com/mBe5vkL.jpg) -| 漆包线 | [fknraiden's custom board](https://geekhack.org/index.php?topic=74223.0) | 可以直接焊接(烧掉绝缘层) | 外观差? | ![漆包线](https://i.imgur.com/b4b7KDb.jpg) -| 弯折二极管引脚作为行方向连线 | [Matt3o's Brownfox](https://deskthority.net/viewtopic.php?f=7&t=6050) | 焊点更少 | 绝缘性差 | ![弯折了的二极管引脚](https://i.imgur.com/aTnG8TV.jpg) -| 硬线(如铜管) | [u/d_stilgar's invisible hardline](https://www.reddit.com/r/MechanicalKeyboards/comments/8aw5j2/invisible_hardline_keyboard_progress_update_april/) 以及 [u/jonasfasler's first attempt](https://www.reddit.com/r/MechanicalKeyboards/comments/de1jyv/my_first_attempt_at_handwiring_a_keyboard/) | 非常漂亮 | 难度高,没有物理绝缘 | ![手工连接的硬线](https://i.imgur.com/CnASmPo.jpg) -| 用绝缘胶带(如高温胶带*)隔离开的裸线 | [Matt3o's 65% on his website](https://matt3o.com/hand-wiring-a-custom-keyboard/) | 简单(不用剥线) | 丑拒 | ![裸线](https://i.imgur.com/AvXZShD.jpg) -| 铜箔胶带 | [ManuForm Dactyl](https://github.com/tshort/dactyl-keyboard) | 非常简单 | 只适用于定位板/外壳与开关底部平齐的情况 | ![铜箔胶带](https://i.imgur.com/RFyNMlL.jpg) - -(*译注:原文是聚酰亚胺胶带,在中国通常叫高温胶带) - - -以上方案可以结合使用,在焊接前请准备好各种长度的线缆。 - - -### 分体键盘的注意事项 - -如果你想制作的是分体键盘(如Dactyl),每一半边都需要一个控制器以及连通两方的通信用线(如TRRS或硬连接线)。更多资料参见[QMK分体键盘文档](zh-cn/feature_split_keyboard.md)。 -(译注:TRRS即一种常用的4线耳机线插口,具体信息请查阅维基百科或[这份知乎文章](https://zhuanlan.zhihu.com/p/144233538)) - - -### 焊接 - -你可以找到很多焊接指导及技巧,这里列出了最相关及最关键的部分: - -要想焊接的牢固需要确保焊料与焊接两端的金属面充分地接触,一个好办法(也不是必须)是上锡前先(将线缆)在针脚上绕一圈或先拧在一起。 - -杆上绕圈 绕环的二极管引脚 - -如果二极管还在包装条上且需要弯折(作为绕圈的起点处或用于连接到邻接处),一个简便的办法是找一个盒子、桌子或尺子的直边上进行弯折。由于弯折统一在二极管一侧,也有助于区分二极管的方向。 - -弯折二极管引脚 - -如果你的电烙铁有温控功能,将其设置在 315ºC(600ºF)。 - -热起来后,给电烙铁上锡 - 即融化一部分锡料到烙铁头上然后立刻用湿海绵或烙铁头海绵擦掉,这样烙铁头上会有一层光滑明亮的焊料,以防止氧化且有助于焊料的焊接操作。 - -接下来进行焊接,先将烙铁头在焊接面上接触一会儿进行加热,然后上焊料焊接两侧。加热焊接面的目的是为了确保焊料可以粘附且不会过早冷却下来。 - -不能让焊料/焊点加热过度,热量会通过接触面烧毁原件(融毁开关外壳等)。并且,由于焊锡中有帮助[“浸润”](https://en.m.wikipedia.org/wiki/Wetting)(即上锡)的助焊剂,加热的越久助焊剂蒸发掉的越多,最终导致焊接点虚焊,除了看起来糟糕外,还有导致电路短路的风险。 - -#### 焊接二极管 - -从左上角的那个开关开始,将二极管放到开关上(用镊子,如果有的话)并纵向放直,有黑线的一端朝向你。让二极管间并联(二极管的阴极不应连接到其它二极管的阳极),二极管的阳极应连接到开关的左引脚上,而弯曲的阴极应朝向右边放置,如图: - -![soldering-diodes-01.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-01.png) - -在放稳二极管后,拿起焊锡,将其与左轴脚同时接触到电烙铁上 - 在松香的帮助下焊锡会很容易地覆盖在二极管及轴脚上。二极管可能会有些位移,此时你可以抓住二极管另外一端弯折过的引脚,小心地放回到位置上 - 但请留意另一端是会迅速变得烫手的。如果二极管容易乱跑,可以使用尖嘴钳之类的东西在焊接时辅助保持稳固。 - -松香加热时升起的烟有害,注意保护口鼻,不要熏到眼睛或皮肤。 - -焊接到位时,可以将焊点升起的烟吹走以免熏脸,也能帮助焊点快速降温。焊点在冷却后会形成沙哑状(无光泽)的表面,但请注意此时它依旧非常烫,需要几分钟时间的冷却才可以触摸,多吹吹有助于快速冷却。 - -在第一个二极管焊接完毕后,第二个二极管需要焊接轴脚以及上一个二极管弯折的那一端,看起来像这样: - -![soldering-diodes-02.png](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/soldering-diodes-02.png) - -在焊接完毕一整行后,用剪线钳剪掉二极管上方(绕轴脚后多出的部分),以及这一行最后侧多出来的引脚部分。在每一行焊接完毕后都要记得这一步。 - -在你完成了所有的二极管的焊接工作后,最好是逐一测试一下以确保焊接牢固稳定 - 再往后不是不能回头修正,但会越来越困难。 - -#### 纵向上的焊接 - -这一步你有几个可选项需考虑 - 给横向电缆进行绝缘处理是个好主意(毕竟二极管没有绝缘层),但如果你足够小心,横向电缆裸露着也行 - 但仍旧不建议这么做。如果你用的是单芯线,先将外皮整个褪下来再酌情装回去可能是最好的办法,但会因尺寸及材质原因造成操作困难,你可以将线缆上需要焊接到开关轴的部分裸露出来。 - -如果你使用多股线/铜绞线,可能最简单的方案就是用不固定长度的小段电线来纵向连接开关。通过融化掉焊接点的外皮的方式来用一整根线不是不可以,但这里不推荐这样做,这种操作会产生更多的有害烟尘,也会毁掉你的电烙铁。 - -在进行焊接操作前,先预弯折好线缆(如果是单芯线),或至少心中已经规划好焊接路线顺序(特别是你要做的设计是错列的时)。实际上焊接顺序不是特别重要,因为我们是通过焊接方案来确定键映射定义的 - 只要确保一行上的所有按键都有独自的列,且从左到右依次排列。 - -如果你不做任何的绝缘处理,可以将纵向的线升高一些,焊接在轴脚尖端上 - 如果线缆本身足够稳固,不会短路到连接着二极管的横线线缆上。 - -## 连接控制器 - -在矩阵焊接完成后,可以将其焊接到微控制器板上了。 - -将微控制器放在预期的位置上,同时要考虑到安装及外壳对齐问题。须记得USB槽的位置是可以与微控制器分开的,只需使用一小段公对母线接驳下即可。 - -找到微控制器板的引脚定义/文档([链接](#common-microcontroller-boards))并将所有的I/O引脚标出来(留意像teensy这种的控制器,模拟I/O引脚可能是数字I/O引脚的两倍),将线缆连接到这些引脚上。 - ----- - -### 针对 Teensy 2.0 的特殊说明 - -Teensy 上的部分引脚有点特殊,像 D6(片上LED),及一些 UART、SPI、I2C或PWM通道,不过只是在你计划着在键盘上还有其它功能设计时才需避免使用。如果你还不是很确定以后会不会增加什么功能上去,引脚应该还是足够充足到可以剩一部分出来的。 - -那些无论在什么控制器上都不应去使用的引脚,有:GND、VCC、AREF以及RST - 其它所有引脚都是可以用且也能在固件中访问的到的。 - ----- - - -将电线切割为控制器到各行/列上某一点距离的长度。可以焊到各行的任意位置上,只需要确保是在二极管之后 - 焊接到二极管前面(轴脚侧)的话该行将无法正常使用。 - -这里用排线的话会显得非常整洁,你也可以考虑如何排布线缆以连接到各行/列的近处。 - -排线 - -在往控制器上焊接电线时,请记住各引脚连接的是哪一行/列,在后续制作固件时我们需要用到这些信息来定义矩阵。 - -在你往下继续以前,请确保控制器已装配到位 - 切掉线缆再重新焊接非常麻烦! - - -## 一些基础的固件配置 - -至此,在你构建好固件后,键盘就应该能正常工作了。 - -通过 [Keyboard Firmware Builder](https://kbfirmware.com/) 网站可以轻松地创建一个简单的固件。通过 [Keyboard Layout Editor](https://www.keyboard-layout-editor.com) 可以自己制作配列数据,之后就可以导入进来并重新构建矩阵信息(如果你没有在先前的 [设计矩阵](#planning-the-matrix) 完成的话)。 - -继续完成剩下的步骤,在逐一配置完所有的按键后就可以编译下载固件了。其中 .hex 文件可以用来直接刷写到键盘上,而 .zip 包中的源代码可以用来添加高级功能并通过 [构建第一个固件](zh-cn/newbs_building_firmware?id=build-your-firmware) 中详述的方法进行本地构建。 - -Keyboard Firmware Builder提供的源代码是QMK的,但版本是2017年初的。如果要用现今版本的QMK来构建 .zip 中的源代码,需要在打开 .zip 后遵循以下几步: - -1. 解压 `kb` 目录到 `qmk_firmware/keyboards/handwired/`。 -2. 进入解压的 `kb` 目录,转到 `keymaps/default/` 目录下,打开 `keymap.c`。 -3. 找到并删除 `action_get_macro` 代码段: - ``` - const macro_t *action_get_macro(keyrecord_t *record, uint8_t id, uint8_t opt) { - ... - return MACRO_NONE; - } - ``` -4. 保存并关闭 `keymap.c`。 - -## 刷写固件 - -安装 [QMK Toolbox](https://github.com/qmk/qmk_toolbox). - -![QMK Toolbox](https://raw.githubusercontent.com/noroadsleft/qmk_images/master/docs/hand_wire/qmk_toolbox.png "QMK Toolbox 0.0.16 on Windows 8.1") - -在 “Local File” 栏处定位到你新创建的 .hex 文件,在 “MicroController” 中选择你的控制器板(常见型号[这里](#common-microcontroller-boards)有)。 - -插上你的键盘后在QMK Toolbox中点击reset(重置)按钮(如果没有重置按钮,短接一下Reset和接地引脚)再点击“Flash”(刷写)按钮。 - - -## 测试固件 - -可以用 [QMK配置器的键盘测试器](https://config.qmk.fm/#/test)、[Keyboard Tester](https://www.keyboardtester.com/tester.html) 或 [Keyboard Checker](https://keyboardchecker.com/) 进行测试,也可以打开一个文本编辑器并试着输入 - 你应该能成功输入键映射方案中的所有字符。对每个按键进行测试,并记录下不能正常工作的按键。对这些不能正常工作的按键,这里有一个快速排查指引: - -1. 将键盘翻过来,用一段金属物短接一下轴脚 - 这么做可以排除掉需要更换掉的坏轴的可能性。 -2. 检查轴脚上的焊点 - 应该是饱满且完整覆盖的。如果你稍加用力就能将其弄下来,那么就是焊接不到位。 -3. 检查二极管的焊点 - 如果二极管虚焊了,部分行可以使用,但其它的可能就不行了。 -4. 检查连接到各行的焊点 - 如果这里虚焊了,这些行就无法正常使用。 -5. 检查 Teensy 两侧的进/出线的焊点 - 两侧的线缆都必须确保已被良好地焊接。 -6. 检查 `.h` 文件中是否有错误或不当的 `KC_NO` - 如果不确定在哪里,用已有的 k*xy* 变量替换一下。 -7. 检查固件文件确实经过编译且正确刷写到Teensy上了。除非你在终端看到了错误消息,或是刷写时出现了弹框,否则一切应该是正常的。 -8. 使用万用表实测一下,触发开关时是否成功闭合(按下时可以连通电路)。 - -如果你完成了上述所有检查,应当留意有时可能是多种因素共同造成了开关的异常,因此最后将其短路掉来排查问题并没有什么害处。 - -## 即将完成 - -在确认键盘可以正常使用后,如果你用的是独立的控制器模块(非手工构建用),须将其固定好。办法有很多,比如热熔胶、双面胶带、3D打印的盒子、电工胶带等。 - -如果你觉得成就感满满,可以试着增加一些额外的功能,比如 [轴内LED](https://geekhack.org/index.php?topic=94258.0),[轴内RGB](https://www.reddit.com/r/MechanicalKeyboards/comments/5s1l5u/photoskeyboard_science_i_made_a_handwired_rgb/),[RGB背光](https://medium.com/@DavidNZ/hand-wired-custom-keyboard-cdd14429c7b3#.7a1ovebsk) 甚至可以是 [OLED显示屏!](https://www.reddit.com/r/olkb/comments/5zy7og/adding_ssd1306_oled_display_to_your_build/) - -固件的潜力非常大 - 阅览 [docs.qmk.fm](https://docs.qmk.fm) 可以看到全部功能的列表,也能深入了解人们是如何使用那些五花八门的键盘的。随时欢迎到 [OLKB subreddit](https://reddit.com/r/olkb) 或 [QMK Discord](https://discord.gg/Uq7gcHh) 上寻求帮助! - -## 其它指引链接 - -- [matt3o 的分步指引 (BrownFox build)](https://deskthority.net/viewtopic.php?f=7&t=6050) 以及他的 [个人站点](https://matt3o.com/hand-wiring-a-custom-keyboard/) 和 [指导视频](https://www.youtube.com/watch?v=LVzpsjFWPP4) -- [Cribbit:“现代化的手工搭建指南 - 强大,简洁,友好”](https://geekhack.org/index.php?topic=87689.0) -- [Sasha Solomon:“打造我的第一把键盘”](https://medium.com/@sachee/building-my-first-keyboard-and-you-can-too-512c0f8a4c5f) -- [RoastPotatoe: “如何手工搭建Planck键盘”](https://blog.roastpotatoes.co/guide/2015/11/04/how-to-handwire-a-planck/) -- [Masterzen:“手工搭建键盘记录”](https://www.masterzen.fr/2018/12/16/handwired-keyboard-build-log-part-1/) - - -# 遗留内容 - -以前本页内还有其它内容,现在我们已经将他们单独分离出去了。以下的内容是一些重定向链接,以供那些从老链接地址过来的人能找到自己要找的内容。 - -## 序: 键盘矩阵是如何工作的(以及为什么需要二极管) :id=preamble-how-a-keyboard-matrix-works-and-why-we-need-diodes - -* [键盘矩阵是如何工作的](zh-cn/how_a_matrix_works.md) diff --git a/docs/zh-cn/keymap.md b/docs/zh-cn/keymap.md deleted file mode 100644 index 91a5ac0c6640..000000000000 --- a/docs/zh-cn/keymap.md +++ /dev/null @@ -1,211 +0,0 @@ -# 键映射总览 - - - -QMK键映射定义在C源文件中,其数据结构上是一个容纳了数组的数组。外层数组容纳了各个层,内层各数组则为层内的键列表。基本所有键盘都通过定义 `LAYOUT()` 宏来创建该两级数组。 - - -## 键映射与配列 :id=keymap-and-layers -在QMK中, **`const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]`** 容纳了多个 **层**, 每个**层**下包含了由**16位**的**动作码**所组成的键映射信息。 最多可以定义**32个层**。 - -对于常规键的定义,其**动作码**的高8位皆为0,低8位保存了USB HID中使用的各个键对应的**键码**。 - -不同的层可以同时生效,层的编号从0至31,编号越高的层优先级越高。 -(译注:由于是ascii图,掺杂中文会导致排版错乱,各翻译标注在图下方。下同) - - Keymap: 32 Layers Layer: action code matrix - ----------------- --------------------- - stack of layers array_of_action_code[row][column] - ____________ precedence _______________________ - / / | high / ESC / F1 / F2 / F3 .... - 31 /___________// | /-----/-----/-----/----- - 30 /___________// | / TAB / Q / W / E .... - 29 /___________/ | /-----/-----/-----/----- - : _:_:_:_:_:__ | : /LCtrl/ A / S / D .... - : / : : : : : / | : / : : : : - 2 /___________// | 2 `-------------------------- - 1 /___________// | 1 `-------------------------- - 0 /___________/ V low 0 `-------------------------- -翻译: - -|原文 |译文 | -|--------------------------|-------------| -|Keymap: 32 Layers | 键映射:32个层| -|stack of layers | 层堆栈 | -|precedence | 优先级 | -|high/low | 高/低 | -|layer: action code matrix | 层:动作码矩阵| -|row/column | 行/列 | - -有时,键映射中存储的动作码在一些文档中也被称作键码,主要是由TMK沿袭而来的习惯。 - -### 键映射的层状态 :id=keymap-layer-status - -键映射的层状态由两个32位参数决定: - -* **`default_layer_state`** 指向一个总是可用的键映射层(0-31)(即默认层)。 -* **`layer_state`** 每一位标记对应层的启用/停用状态。 - -通常键映射中的'0'层为 `default_layer(默认层)`,其它层在启动时会被固件置为停用状态,不过这些可以通过 `config.h` 进行配置。当你换了一个按键布局时可用于更改 `default_layer`,比如从Qwerty布局切换到了Colemak布局。 - - Initial state of Keymap Change base layout - ----------------------- ------------------ - - 31 31 - 30 30 - 29 29 - : : - : : ____________ - 2 ____________ 2 / / - 1 / / ,->1 /___________/ - ,->0 /___________/ | 0 - | | - `--- default_layer = 0 `--- default_layer = 1 - layer_state = 0x00000001 layer_state = 0x00000002 -翻译: - -|原文 |译文 | -|-----------------------|-------------| -|Initial state of Keymap| 键映射原始状态| -|Change base layout | 更改了基础层 | - -另外,可以通过修改 `layer_state` 做到其他层对基础层的覆盖,以实现诸如导航键、功能键(F1-F12)、多媒体键等特殊动作。 - - Overlay feature layer - --------------------- bit|status - ____________ ---+------ - 31 / / 31 | 0 - 30 /___________// -----> 30 | 1 - 29 /___________/ -----> 29 | 1 - : : | : - : ____________ : | : - 2 / / 2 | 0 - ,->1 /___________/ -----> 1 | 1 - | 0 0 | 0 - | + - `--- default_layer = 1 | - layer_state = 0x60000002 <-' - - - -### 层优先级及穿透 -须记住**层堆栈中更高的层有着更高的优先级**。固件会从最高的活跃层开始向下找键码,一旦固件在活跃层上找到了一个非 `KC_TRNS`(穿透)键码,就会停止查找,再往下的层级不会被查看。 - - ____________ - / / <--- 较高的层 - / KC_TRNS // - /___________// <--- 较低的层 (KC_A) - /___________/ - - 这个场景中,较高层级中的非穿透键是可用的,如果定义为 `KC_TRNS`(及同等效果的),较低层级的键码 `KC_A` 将被采纳。 - -**注意:** 在层中定义合法的穿透键的方法有: -* `KC_TRANSPARENT` -* `KC_TRNS`(别名) -* `_______`(别名) - -这些键码允许在搜索非穿透键码时可以穿透当前层下落到更低层去。 - -## `keymap.c` 文件解析 - -本例中我们将深入到[Clueboard 66%的一款旧版的默认键映射](https://github.com/qmk/qmk_firmware/blob/ca01d94005f67ec4fa9528353481faa622d949ae/keyboards/clueboard/keymaps/default/keymap.c)方案中去。将该文件在另一个浏览器窗口中打开,以便对照本文进行同步阅览。 - -在一个 `keymap.c` 文件中会有三个你可能会关心的部分: - -* [预定义](#definitions) -* [层/键映射数据结构](#layers-and-keymaps) -* [自定义函数](#custom-functions),若有的话 - -### 预定义 - -文件头部可以看到: - - #include QMK_KEYBOARD_H - - // Helpful defines - // 译:便捷性的宏定义 - #define GRAVE_MODS (MOD_BIT(KC_LSHIFT)|MOD_BIT(KC_RSHIFT)|MOD_BIT(KC_LGUI)|MOD_BIT(KC_RGUI)|MOD_BIT(KC_LALT)|MOD_BIT(KC_RALT)) - - /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * - * You can use _______ in place for KC_TRNS (transparent) * - * Or you can use XXXXXXX for KC_NO (NOOP) * - * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ - // 译:可以用 _______ 替代 KC_TRNS(穿透),用 XXXXXXX 替代 KC_NO (空操作) - - // Each layer gets a name for readability. - // The underscores don't mean anything - you can - // have a layer called STUFF or any other name. - // Layer names don't all need to be of the same - // length, and you can also skip them entirely - // and just use numbers. - // 译:每一层为了便于识别可以起一个名字,下划线没有实际意义 - 叫STUFF之类的也行的, - // 译:层名不需要都一样长,甚至不定义这些直接用层号也是可以的 - enum layer_names { - _BL, - _FL, - _CL, - }; - -以上是一些便于编写键映射及自定义函数时可用的预定义,`GRAVE_MODS` 后续会用在自定义函数中,之后的 `_BL`, `_FL` 及 `_CL` 便于我们在代码中引用这些层。 - -注:在一些更早的键映射文件中,你可能会发现一些形如 `_______` 或 `XXXXXXX` 的定义,这些可以分别代替 `KC_TRNS` 及 `KC_NO`,这样可以更清楚地分辨出各层中定义了哪些键的键值。现在这些定义是不需要的,因为我们默认已经提供了这些定义。 - -### 层和键映射 - -这个文件中最主要的部分是 `keymaps[]` 定义,这里须列出你的层以及层中的内容。这一部分应该以如下定义起始: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -之后是一个LAYOUT()宏组成的列表,一个LAYOUT()下定义了一个层中的键列表,一般你需要至少一个“基础层”(如QWERTY、Dvorak或Colemak),之后是在其之上的多个“功能”层。受限于对层的处理顺序,较低的层无法覆盖在较高的层上。 - -QMK在 `keymaps[][MATRIX_ROWS][MATRIX_COLS]` 中保存着16位的动作码(有些时候也被称作键码),对于与常规键一致的键码,其高字节为0,低字节为USB HID 键盘所使用的键码值。 - -> QMK的前身TMK中使用 `const uint8_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS]` 来存储8位的键码,一些键码被保留用于引用执行 `fn_actions[]` 数组中的特定功能。 - -#### 基础层 - -以下示例是Clueboard的基础层定义: - - /* Keymap _BL: Base Layer (Default Layer) - */ - [_BL] = LAYOUT( - F(0), 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_GRV, KC_BSPC, KC_PGUP, \ - 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_PGDN, \ - 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_NUHS, KC_ENT, \ - KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RO, KC_RSFT, KC_UP, \ - KC_LCTL, KC_LGUI, KC_LALT, KC_MHEN, KC_SPC,KC_SPC, KC_HENK, KC_RALT, KC_RCTL, MO(_FL), KC_LEFT, KC_DOWN, KC_RGHT), - -这里有一些值得留意的地方: - -* 站在C语言源代码的角度看,这只是一个数组,但我们掺杂了大量括号使得每个键可以在视觉上与物理设备对齐。 -* 常规的键盘扫描码以KC_起始,而那些“特殊”键则不是。 -* 最左上的键可以触发自定义函数0(`F(0)`) -* "Fn"键定义为 `MO(_FL)`,当按住该键时会切换到 `_FL` 层。 - -#### 功能覆盖层 - -对于功能层,从代码角度讲与基础层没有任何区别。但在概念上讲,应该将其作为覆盖层而非替代层来定义。对大部分人来讲这个区别不重要,但当你构建越来越复杂的层结构时,其重要性会越来越凸显。 - - [_FL] = LAYOUT( - 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, BL_STEP, \ - _______, _______, _______,_______,_______,_______,_______,_______,KC_PSCR,KC_SCRL, KC_PAUS, _______, _______, _______, _______, \ - _______, _______, MO(_CL),_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, \ - _______, _______, _______,_______,_______,_______,_______,_______,_______,_______, _______, _______, _______, _______, KC_PGUP, \ - _______, _______, _______, _______, _______,_______, _______, _______, _______, MO(_FL), KC_HOME, KC_PGDN, KC_END), - -这里值得留意的有: - -* 我们使用 `_______` 定义来替代 `KC_TRNS`, 以便凸显在该层中有变化的那些键。 -* 对于这一层来讲,如果点击的是一个 `_______` 键,实际生效的将是其下的活跃层中的键。 - -# 核心细节 - -在阅读完本节后,你应该掌握了构建自己的键映射的基础能力,更多的资料请参见: - -* [键码](zh-cn/keycodes.md) -* [键映射FAQ](zh-cn/faq_keymap.md) - -我们仍在优化这份文档,如果你有更好的优化建议,请[提交一份issue](https://github.com/qmk/qmk_firmware/issues/new)! diff --git a/docs/zh-cn/mod_tap.md b/docs/zh-cn/mod_tap.md deleted file mode 100644 index 9dc59bfb79fd..000000000000 --- a/docs/zh-cn/mod_tap.md +++ /dev/null @@ -1,141 +0,0 @@ -# Mod-Tap - - - -Mod-Tap键 `MT(mod, kc)` 在按住时功能为修饰键,在点击时则是常规键码。举例来讲,可以设计出一个按键,当点击时发送Escape,按下时则作为Control或Shift - -修饰键码及`OSM()`将会被缀以`MOD_`前缀,而非`KC_` - -|修饰键码 |描述 | -|----------|------------------------------------------| -|`MOD_LCTL`|左Control | -|`MOD_LSFT`|左Shift | -|`MOD_LALT`|左Alt | -|`MOD_LGUI`|左GUI (Windows/Command/Meta键) | -|`MOD_RCTL`|右Control | -|`MOD_RSFT`|右Shift | -|`MOD_RALT`|右Alt (AltGr) | -|`MOD_RGUI`|右GUI (Windows/Command/Meta键) | -|`MOD_HYPR`|Hyper (左Control, Shift, Alt 及 GUI同时按下)| -|`MOD_MEH` |Meh (左Control, Shift, 及 Alt同时按下) | - -可以通过逻辑或进行组合: - -```c -MT(MOD_LCTL | MOD_LSFT, KC_ESC) -``` - -此时按住该键将触发左Control及左Shift,点击将发送Escape。 - -为了方便配列,QMK已包含一些常见的Mod-Tap: - -|键 |别名 |描述 | -|------------|-----------------------------------------------------------------|---------------------------------------------| -|`LCTL_T(kc)`|`CTL_T(kc)` |按住时为左Control,点击时为 `kc` | -|`LSFT_T(kc)`|`SFT_T(kc)` |按住时为左Shift,点击时为 `kc` | -|`LALT_T(kc)`|`LOPT_T(kc)`, `ALT_T(kc)`, `OPT_T(kc)` |按住时为左Alt,点击时为 `kc` | -|`LGUI_T(kc)`|`LCMD_T(kc)`, `LWIN_T(kc)`, `GUI_T(kc)`, `CMD_T(kc)`, `WIN_T(kc)`|按住时为左GUI,点击时为 `kc` | -|`RCTL_T(kc)`| |按住时为右 Control,点击时为 `kc` | -|`RSFT_T(kc)`| |按住时为右 Shift,点击时为 `kc` | -|`RALT_T(kc)`|`ROPT_T(kc)`, `ALGR_T(kc)` |按住时为右 Alt,点击时为 `kc` | -|`RGUI_T(kc)`|`RCMD_T(kc)`, `RWIN_T(kc)` |按住时为右 GUI,点击时为 `kc` | -|`LSG_T(kc)` |`SGUI_T(kc)`, `SCMD_T(kc)`, `SWIN_T(kc)` |按住时为左Shift及GUI,点击时为 `kc` | -|`LAG_T(kc)` | |按住时为左Alt及GUI,点击时为 `kc` | -|`RSG_T(kc)` | |按住时为右 Shift及GUI,点击时为 `kc` | -|`RAG_T(kc)` | |按住时为右 Alt及GUI,点击时为 `kc` | -|`LCA_T(kc)` | |按住时为左Control及Alt,点击时为 `kc` | -|`LSA_T(kc)` | |按住时为左Shift及Alt,点击时为 `kc` | -|`RSA_T(kc)` |`SAGR_T(kc)` |按住时为右 Shift及右 Alt (AltGr),点击时为 `kc` | -|`RCS_T(kc)` | |按住时为右 Control及右 Shift,点击时为 `kc` | -|`LCAG_T(kc)`| |按住时为左Control,Alt及GUI,点击时为 `kc` | -|`RCAG_T(kc)`| |按住时为右 Control,Alt及GUI,点击时为 `kc` | -|`C_S_T(kc)` | |按住时为左Control及Shift,点击时为 `kc` | -|`MEH_T(kc)` | |按住时为左Control,Shift及Alt,点击时为 `kc` | -|`HYPR_T(kc)`|`ALL_T(kc)` |按住时为左Control,Shift,Alt及GUI,点击时为 `kc` - 更多[参见这里](https://brettterpstra.com/2012/12/08/a-useful-caps-lock-key/)| - -## 注意 - -目前 `MT()` 的 `kc`参数限制在[基础键码集](zh-cn/keycodes_basic.md)中,因此不能使用 `LCTL()`,`KC_TILD` 及其它大于 `0xFF` 的键码。原因是,QMK使用16位的键码,其中3位是功能标记,1位标记左右修饰键,4位存储修饰键码,仅剩8位存储键码。当一次Mod-Tap触发时,只要有一个右修饰键被激发,其它的修饰键也都被视为右修饰键,因此无法混搭形如左Control+右Shift的形式,会被视为右Control+右Shift - -若展开讲就比较复杂了。迁移到32位的键码可以很大程度解决这个问题,但同时会招致配列矩阵大小翻倍,也可能会有其它未知问题。若是想用修饰键配合按键,可以考虑使用[Tap Dance/多击键](zh-cn/feature_tap_dance.md#example-5-using-tap-dance-for-advanced-mod-tap-and-layer-tap-keys) - -在使用Windows远程桌面时你可能会发现有些问题,这是因为远程桌面对键码响应过快。若要修复,可以打开远程桌面的“配置”,在“本地资源”页中的键盘属性,调整为“本地计算器”,此时功能即可恢复正常。另一个办法是加大[`TAP_CODE_DELAY`](zh-cn/config_options.md#behaviors-that-can-be-configured)。 - -## 截获Mod-Taps - -### 改变点击功能 - -若要在Mod-Tap中突破基础键码的限制,可以在 `process_record_user` 中实现。如,上档键码 `KC_DQUO` 无法与 `MT()` 共用,因为它实际上是 `LSFT(KC_QUOT)` 的别名,`KC_DQUO` 上的修饰键码会被 `MT()` 覆盖。但可以使用如下代码截获点击,手动发送 `KC_DQUO`: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LCTL_T(KC_DQUO): - if (record->tap.count && record->event.pressed) { - tap_code16(KC_DQUO); // 点击时发送 KC_DQUO - return false; // 通过返回false阻止对该键的其它处理 - } - break; - } - return true; -} -``` - -### 改变按住功能 - -类似地,同样可以使用这段自定义代码改变按住功能。下面的例子会在 `LT(0, kc)` (layer-tap键无实际意义,因为layer 0默认被激活)按住时对X,C和V键附加剪切,复制和粘贴功能: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(0,KC_X): - if (record->tap.count && record->event.pressed) { - return true; // 返回true来发送常规键码 - } else if (record->event.pressed) { - tap_code16(C(KC_X)); // 截获按住功能来发送Ctrl-X - } - return false; - case LT(0,KC_C): - if (record->tap.count && record->event.pressed) { - return true; // 返回true来发送常规键码 - } else if (record->event.pressed) { - tap_code16(C(KC_C)); // 截获按住功能来发送Ctrl-C - } - return false; - case LT(0,KC_V): - if (record->tap.count && record->event.pressed) { - return true; // 返回true来发送常规键码 - } else if (record->event.pressed) { - tap_code16(C(KC_V)); // 截获按住功能来发送Ctrl-V - } - return false; - } - return true; -} -``` - -### 同时改变点击和按住功能 - -最后一个例子通过 `LT(0,KC_NO)` 实现了点击复制,按住粘贴的功能: - -```c -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case LT(0,KC_NO): - if (record->tap.count && record->event.pressed) { - tap_code16(C(KC_C)); // 截获点击来发送Ctrl-C - } else if (record->event.pressed) { - tap_code16(C(KC_V)); // 截获按住功能来发送Ctrl-V - } - return false; - } - return true; -} -``` - -## 其它信息 - -在[点按配置](zh-cn/tap_hold.md)中描述了影响Mod-Tap行为的标记。 diff --git a/docs/zh-cn/newbs.md b/docs/zh-cn/newbs.md deleted file mode 100644 index 3be46262118d..000000000000 --- a/docs/zh-cn/newbs.md +++ /dev/null @@ -1,29 +0,0 @@ -# QMK入门教程 - - - -就像计算机一样,每把键盘里也有一个处理器,它的职责是在你点击键盘时,检测到这个动作并反馈给计算机。QMK固件即是为了这个目的而设计的一种"软件",负责检测点击,反馈给电脑。当你构建出一个自定义键映射时,就是在创建一个新的键盘"软件"。 - -QMK的愿景是提供强有力的功能,让不可能的事情变得可能,简单的事情依旧简单。即便是不会编程也可以创建强大的键映射方案。 - -想知道你的键盘是否能运行QMK?如果这个键盘是你自己组建的,那么很可能是可以的。我们[已经支持很多键盘](https://qmk.fm/keyboards/),所以即便你的键盘不能运行QMK,你也很容易能买到满足要求的键盘。 - -?> **这份指南适合于我吗?**
-编程对你是个困难的话,可以看看我们的[在线GUI页面](zh-cn/newbs_building_firmware_configurator.md)。 - -## 总览 - -这份指南适用于想通过源代码编译出键盘固件的需求。对于程序员,全过程都会感觉很熟悉。教程主要分3部分: - -1. [环境配置](zh-cn/newbs_getting_started.md) -2. [构建第一个固件](zh-cn/newbs_building_firmware.md) -3. [刷写固件](zh-cn/newbs_flashing.md) - -该指南的目的是帮助那些从未编译过软件的人,很多取舍及建议都是基于这个考量。完成一个目标可能有多种方案,我们尽量都去支持,如果你搞不明白你的目标如何实现,可以[向我们寻求帮助](zh-cn/support.md)。 - -## 更多资料 - -这份指南之外,也有一些其它能帮助你学习QMK的资料。我们归纳整理在[大纲](zh-cn/syllabus.md)页面和[学习资料](zh-cn/newbs_learn_more_resources.md)页面 diff --git a/docs/zh-cn/newbs_building_firmware.md b/docs/zh-cn/newbs_building_firmware.md deleted file mode 100644 index 681c7ba8f6c6..000000000000 --- a/docs/zh-cn/newbs_building_firmware.md +++ /dev/null @@ -1,68 +0,0 @@ -# 构建第一个固件 - - - -现在您已经准备好了构建环境,就可以开始构建自定义固件了。在这节指南中,我们将在3个程序中开展工作——文件管理器、文本编辑器和终端。在做出心满意足的固件前,请不要关闭它们。 -## 新建键映射 - -也许你会考虑从默认键映射复制一份来开始,如果你遵循编译环境配置指南到了最后,那么使用QMK命令行可以简单地做到: - - qmk new-keymap - -如果你的环境没有那样配置,或者你有多个键盘要做,可以指定键盘名: - - qmk new-keymap -kb - -检查命令行输出,应该类似于: - - Ψ keymap directory created in: /home/me/qmk_firmware/keyboards/clueboard/66/rev3/keymaps/ - -上面就是创建出的新 `keymap.c` 文件的路径。 - -## 使用趁手的编辑器打开 `keymap.c` - -在编辑器中打开 `keymap.c`,可以看到控制键盘所有功能的关键结构。`keymap.c` 文件头部的一些define和enum定义能让代码容易阅读一些,继续往下会找到这么一行: - - const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - -这行是所有层定义的起点,往下能看到有 `LAYOUT` 的行,都是一个层定义的起始,其下方为该层的组成定义。 - -!> 编辑时请非常留意不要错误增加/删除了逗号分隔符,否则很可能无法编译固件,且很难排查是哪里的逗号不对。 - -## 按照个人喜好设计层级 - -这一步的目标完全取决于你,既可以去修复一个你不爽的问题,也可以完全重写一个新的。你可以删除不需要的层,或是增加层到32个的上限,QMK功能丰富,可以在左边的导航栏中寻找“使用QMK”一节,浏览完整的功能信息,也可以看看这些比较简单的: - -* [基础键码](zh-cn/keycodes_basic.md) -* [量子键码](zh-cn/quantum_keycodes.md) -* [Grave/Escape](zh-cn/feature_grave_esc.md) -* [鼠标键](zh-cn/feature_mouse_keys.md) - -?> 你大概理解了键映射如何工作的话,留心尽量少去做改动,改动越多出了问题越难排查。 - -## 构建固件 :id=build-your-firmware - -对键映射做完修改后,该编译固件了。回到终端中使用编译命令: - - qmk compile - -如果没有完整地配置环境,或你有多个目标键盘,可以指定键盘及键映射: - - qmk compile -kb -km - -编译完成后,会输出详尽的编译产出文件信息,其末尾应该看起来像这样: - -``` -Linking: .build/planck_rev5_default.elf [OK] -Creating load file for flashing: .build/planck_rev5_default.hex [OK] -Copying planck_rev5_default.hex to qmk_firmware folder [OK] -Checking file size of planck_rev5_default.hex [OK] - * The firmware size is fine - 27312/28672 (95%, 1360 bytes free) -``` - -## 刷写固件 - -参阅[刷写固件](zh-cn/newbs_flashing.md)以了解如何将固件写入键盘主控。 diff --git a/docs/zh-cn/newbs_building_firmware_configurator.md b/docs/zh-cn/newbs_building_firmware_configurator.md deleted file mode 100644 index c4cd1143182e..000000000000 --- a/docs/zh-cn/newbs_building_firmware_configurator.md +++ /dev/null @@ -1,18 +0,0 @@ -# QMK配置器 - - - -[![QMK配置器截图](https://i.imgur.com/anw9cOL.png)](https://config.qmk.fm/) - -[QMK配置器](https://config.qmk.fm)是一个可用于生成`.hex`和`.bin`格式的QMK固件文件的在线交互页面。 - -这里有[视频教程](https://www.youtube.com/watch?v=-imgglzDMdY). 很多人给我们反馈该视频包含了足够多的知识可以用来开始编写自己的键盘程序。 - -QMK配置器在Chrome及Firefox中工作良好。 - -!> **来自于第三方工具的文件数据无法保证与QMK兼容,如Keyboard Layout Editor(KLE)或kbfirmware,请不要加载或导入这些文件。QMK配置器是一个独立的工具。** - -更多信息请参见[QMK配置器: 入门](zh-cn/configurator_step_by_step.md)。 diff --git a/docs/zh-cn/newbs_flashing.md b/docs/zh-cn/newbs_flashing.md deleted file mode 100644 index 9ffb792793d3..000000000000 --- a/docs/zh-cn/newbs_flashing.md +++ /dev/null @@ -1,124 +0,0 @@ -# 刷写键盘固件 - - - -在自定义的固件文件构建出来后,可以刷写到键盘中了。 - -## 将键盘调至DFU(Bootloader)模式 - -在你将自定义固件刷写到键盘前,键盘必须处于特有的刷写模式下。此时,键盘会处于不会响应点击等常规操作的状态,并且一定留意不要打断刷写工作,刷写固件过程中不可以把键盘拔下来。 - -不同的键盘进入刷写模式的方法都是不同的,如果你的键盘运行的是QMK、TMK或PS2AVRGB(Bootmapper客户端)且没有写明特别的操作说明的话,可以依次尝试以下操作: - -* 按住两边的Shift键,点击Pause -* 按住两边的Shift键,点击B -* 拔出键盘,同时按住“空格”键及B键,再插上键盘,等两秒后松开 -* 拔出键盘,按住键盘左上或左下的按键(一般来讲是Escape或左Control),在插上键盘 -* 按重置按键(Reset),一般在PCB背面 -* 在PCB上寻找导出的 `RESET` 和 `GND` 引脚,在插电的情况下短接一下 - -如果上面的方法没有用,且键盘主板上的芯片是 `STM32` 系列,情况要复杂一些。通常在[Discord](https://discord.gg/Uq7gcHh)上寻求帮助是最好的办法,并且很可能需要你提供一些键盘主板的照片 —— 所以如果你能提前准备好,我们沟通起来会快得多。 - -如果没有遇到什么问题,你会在QMK工具箱的输出信息里找到类似下面的黄色文字的信息: - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -``` - -已进入bootloader状态的设备也可以在设备管理器、系统信息或 `lsusb` 中看到。 - -## 使用QMK工具箱刷写固件 - -使用[QMK工具箱](https://github.com/qmk/qmk_toolbox/releases)刷写固件是最简单的方案。 - -然而该工具箱仅支持Windows及macOS,如果你在使用Linux环境(或是希望用命令行刷写固件),请参阅[在命令行中刷写固件](#使用命令行刷写固件)一节。 - -### 加载固件到QMK工具箱 - -打开QMK工具箱,在Finder或文件管理器中找到固件文件。键盘固件文件名后缀通常是 `.hex` 或 `.bin`,QMK工具箱会尝试将正确的文件拷贝到qmk根目录 `qmk_firmware` 中。 - -在Windows或macOS上,使用下面的指令可以快速打开当前目录。 - - - -#### ** Windows ** - -``` -start . -``` - -#### ** macOS ** - -``` -open . -``` - - - -固件文件的文件名格式为: - -``` -_.{bin,hex} -<键盘名>_<键映射名>.{bin,hex} -``` - -例如, `planck/rev5` 的 `default` 键映射对应的文件名是: - -``` -planck_rev5_default.hex -``` - -找到固件文件后,将其拖拽至QMK工具箱的"Local file"框,或点击“Open”并定位至固件文件。 - -### 刷写到键盘 - -点击QMK工具箱的`Flash`,将看到如下输出信息: - -``` -*** DFU device connected: Atmel Corp. ATmega32U4 (03EB:2FF4:0000) -*** Attempting to flash, please don't remove device ->>> dfu-programmer.exe atmega32u4 erase --force - Erasing flash... Success - Checking memory from 0x0 to 0x6FFF... Empty. ->>> dfu-programmer.exe atmega32u4 flash "D:\Git\qmk_firmware\gh60_satan_default.hex" - Checking memory from 0x0 to 0x3F7F... Empty. - 0% 100% Programming 0x3F80 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - 0% 100% Reading 0x7000 bytes... - [>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>] Success - Validating... Success - 0x3F80 bytes written into 0x7000 bytes memory (56.70%). ->>> dfu-programmer.exe atmega32u4 reset - -*** DFU device disconnected: Atmel Corp: ATmega32U4 (03EB:2FF4:0000) -``` - -## 使用命令行刷写固件 - -现在已经没有以前那样繁琐了,在编译固件后需要刷写时,打开终端输入如下刷写指令: - - qmk flash - -如果未通过命令行工具配置过键盘/键映射名,或有多个目标键盘,可以指定目标键盘和键映射: - - qmk flash -kb <键盘名> -km <键映射名> - -QMK将核查键盘配置,并尝试使用合适的bootloader进行刷写。也就是说,你不用关注应该使用什么bootloader,这些重活儿让qmk指令去承担就好。 - -但是,先决条件是键盘配置中已经设置了bootloader,如果未配置,或你的键盘板子不支持配置的刷写方式,你会看到这些错误信息: - - WARNING: This board's bootloader is not specified or is not supported by the ":flash" target at this time. - -此时,只能退回到需要指定bootloader的方法,具体参见[刷写固件](zh-cn/flashing.md)指引。 - -## 上手试试键盘吧! - -恭喜你,你的自定义固件成功刷写到键盘中了,快去试试吧! - -运气不差的话一切都会是正常工作的,如果不幸遇到了些问题,有一些参考方案可以帮助你排查问题原因。 -键盘测试就简单直接了,依次按一下各按键,检查它是不是发送了正确的输入。可以使用[QMK配置器](https://config.qmk.fm/#/test/)中的测试模式进行测试,即便你的键盘并不运行QMK。 - -还是不行吗?参阅一下FAQ或[通过Discord和我们聊聊](https://discord.gg/Uq7gcHh)吧。 diff --git a/docs/zh-cn/newbs_getting_started.md b/docs/zh-cn/newbs_getting_started.md deleted file mode 100644 index 7ca9871aa710..000000000000 --- a/docs/zh-cn/newbs_getting_started.md +++ /dev/null @@ -1,208 +0,0 @@ -# 配置环境 - - - -构建键映射前,有一些必须安装配置的构建工具,但无论你要编译多少个固件,这一步只需要做一次。 - -## 1. 必备工具 - -首先需要确保一些基本的软件配备。 - -* [文本编辑器](zh-cn/newbs_learn_more_resources.md#text-editor-resources) - * 你需要至少一个能编辑常规文本的软件。系统自带的编辑器通常不会如实保存(会做一些额外的处理,如回车),所以选择编辑器时需要留意。 -* [QMK工具箱(可选)](https://github.com/qmk/qmk_toolbox) - * 在Windows及macOS上可用的图形程序,用于编辑及调试你的键盘 - -?> 如果你没有Linux/Unix命令行使用经验,有些基本概念需要先学习一下。[这些资料](zh-cn/newbs_learn_more_resources.md#command-line-resources)是个使用QMK很好的参考。 - -## 2. 准备构建环境 :id=set-up-your-environment - -我们已经尽力让QMK易于配置了,你只要准备好Linux或Unix环境,剩余的交给QMK来安装。 - - - -### ** Windows ** - -QMK有维护一套基于MSYS2的软件包,所有命令行程序和依赖都是齐备的。通过 `QMK MSYS` 快捷命令可以快速启动开发环境。 - -#### 依赖项 - -需安装[QMK MSYS](https://msys.qmk.fm/),最新版在[这里](https://github.com/qmk/qmk_distro_msys/releases/latest)。 - -此外,如果想自行安装MSYS2环境,下面给出了具体的步骤。 - -
- 自行安装 - -?> 若决定使用 `QMK MSYS`,请跳过此节. - -#### 依赖项 - -遵循 https://www.msys2.org 上的指引,安装MSYS2、Git和Python。 - -在MSYS2安装完毕后,关闭所有的MSYS终端,启动新的MinGW 64-bit终端。 - -!> **注意:** MinGW 64-bit 终端*不同于*安装包最后打开的MSYS终端,窗口标题应当是紫色的"MINGW64"而不是"MSYS"。具体的差异可以[参考这里](https://www.msys2.org/wiki/MSYS2-introduction/#subsystems)。 - -执行如下命令: - - pacman --needed --noconfirm --disable-download-timeout -S git mingw-w64-x86_64-toolchain mingw-w64-x86_64-python3-pip - -#### 安装 - -安装QMK命令行程序: - - python3 -m pip install qmk - -
- -### ** macOS ** - -QMK维护了一套Homebrew tap和formula以用于自动安装命令行程序及依赖项。 - -#### 依赖项 - -须先安装Homebrew,可以参考 https://brew.sh - -#### 安装 - -安装QMK命令行程序: - - brew install qmk/qmk/qmk - -### ** Linux/WSL ** - -?> **WSL用户注意**: 默认情况下,QMK仓库会被clone到home目录下,如果想指定其它目录,务必留意要放在WSL文件系统中(即,非 `/mnt` 目录下),否则文件读写会[非常慢](https://github.com/microsoft/WSL/issues/4197). - -#### 依赖项 - -须安装Git及Python,通常你肯定已经有了,如果确实没有,请使用下面的方法尝试安装: - -* Debian / Ubuntu / Devuan: `sudo apt install -y git python3-pip` -* Fedora / Red Hat / CentOS: `sudo yum -y install git python3-pip` -* Arch / Manjaro: `sudo pacman --needed --noconfirm -S git python-pip libffi` -* Void: `sudo xbps-install -y git python3-pip` -* Solus: `sudo eopkg -y install git python3` -* Sabayon: `sudo equo install dev-vcs/git dev-python/pip` -* Gentoo: `sudo emerge dev-vcs/git dev-python/pip` - -#### 安装 - -安装QMK命令行程序: - - python3 -m pip install --user qmk - -#### 社区提供的包 - -有一些社区成员提供的包,可能版本会有落后或是功能不全的问题,如果你遇到了什么问题,请联系维护它的社区成员。 - -Arch系环境下可以使用官方源安装命令行程序(在写这份文档时,有些依赖项被标记为可选的,其实不是): - - sudo pacman -S qmk - -也可以尝试AUR的 `qmk-git`: - - yay -S qmk-git - -### ** FreeBSD ** - -#### 安装 - -使用FreeBSD包安装QMK命令行程序: - - pkg install -g "py*-qmk" - -请遵循安装后输出的指引操作进行配置(使用 `pkg info -Dg "py*-qmk"` 可以显示这份指引)。 - - - -## 3. 执行QMK配置 :id=set-up-qmk -*译注:由于setup过程中需要从github clone依赖项,请先确保科学上网* - - - -### ** Windows ** - -安装QMK后,执行: - - qmk setup - -通常所有的询问回复 `y` 就行了。 - -### ** macOS ** - -安装QMK后,执行: - - qmk setup - -通常所有的询问回复 `y` 就行了。 - -### ** Linux/WSL ** - -安装QMK后,执行: - - qmk setup - -通常所有的询问回复 `y` 就行了。 - -?>**Debian及Ubuntu系环境须留意**: -也许你会遇到 `bash: qmk: command not found` 错误,主要是因为Debian上的Bash 4.4版本引入的一个[bug](https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=839155),`$HOME/.local/bin` 被从PATH环境变量中删除了,后续版本中这个问题已被修复。 -然而Ubuntu很挫地再次引入了这个bug[且没有修复](https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1588562)。 -不过修复也很容易,在当前账户中执行:`echo 'PATH="$HOME/.local/bin:$PATH"' >> $HOME/.bashrc && source $HOME/.bashrc` - -### ** FreeBSD ** - -安装QMK后,执行: - - qmk setup - -通常所有的询问回复 `y` 就行了。 - - - -?> QMK的home目录可以在安装时通过 `qmk setup -H ` 来指定,安装后也可以通过[命令行程序来配置](zh-cn/cli_configuration.md?id=single-key-example)`user.qmk_home`变量,可以通过 `qmk setup --help` 查看所有可用配置。 - -?> 若你熟悉GitHub,[推荐阅读这份指引](zh-cn/getting_started_github.md)通过 `qmk setup /qmk_firmware` 来clone你自己的fork。如果你看不懂这一段啥意思,忽略就是了。 - -## 4. 测试你的构建环境 - -QMK构建环境搭建完成,可以尝试构建一个键盘固件。使用以下指令格式,先试试编译默认提供的键映射: - - qmk compile -kb -km default - -例如,要构建一个Clueboard 66%,就这样执行: - - qmk compile -kb clueboard/66/rev3 -km default - -你应当能看到像这样的输出信息: - -``` -Linking: .build/clueboard_66_rev3_default.elf [OK] -Creating load file for flashing: .build/clueboard_66_rev3_default.hex [OK] -Copying clueboard_66_rev3_default.hex to qmk_firmware folder [OK] -Checking file size of clueboard_66_rev3_default.hex [OK] - * The firmware size is fine - 26356/28672 (2316 bytes free) -``` - -## 5. 配置你的构建环境 (可选的) - -通过对默认配置的简单调整,QMK用起来会更有趣一些,我们来试试! - -大部分QMK新手手头只有一把键盘,可以通过 `qmk config` 命令将它设置为默认键盘,例如你想将 `clueboard/66/rev4` 设置为默认,可以这样: - - qmk config user.keyboard=clueboard/66/rev4 - -也可以调整默认的键映射名称。社区上大家常用自己的GitHub用户名,这也是我们推荐的做法。 - - qmk config user.keymap= - -完成后,这些配置就不用管了,编译键盘固件就可以直接这样执行: - - qmk compile - -# 制作你自己的键映射 - -万事俱备啦!请继续阅读[构建第一个固件](zh-cn/newbs_building_firmware.md). diff --git a/docs/zh-cn/newbs_git_best_practices.md b/docs/zh-cn/newbs_git_best_practices.md deleted file mode 100644 index af3359dfc55d..000000000000 --- a/docs/zh-cn/newbs_git_best_practices.md +++ /dev/null @@ -1,23 +0,0 @@ -# QMK所采用的Git最佳实践 - - - -*译者注:对于git相关的部分,除广为接受的名词外,会尽量保留git命令及各种术语的英文版本,部分名词及关键部分会附带中文翻译* - -## 或者讲,"怎么才能不害怕并喜欢上Git" - -本节旨在以最佳方式指导新手在为QMK做贡献时获得流畅的体验。我们将进行一次完整的QMK贡献操作流程,并在部分环节中详细讲述几种便捷的方法,之后我们会故意搞砸一些东西,并教导你如何回到正轨。 - -该章节做了如下假设: - -1. 你已有Github账号且已[fork了qmk_firmware仓库](zh-cn/getting_started_github.md)到你的账号下。 -2. 已完成了[构建环境](zh-cn/newbs_getting_started.md#set-up-your-environment)及[QMK](zh-cn/newbs_getting_started.md#set-up-qmk)配置。 - ---- - -- 第一节:[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md) -- 第二节:[解决合并冲突](zh-cn/newbs_git_resolving_merge_conflicts.md) -- 第三节:[重新同步一个脱离同步状态的Git分支](zh-cn/newbs_git_resynchronize_a_branch.md) diff --git a/docs/zh-cn/newbs_git_resolving_merge_conflicts.md b/docs/zh-cn/newbs_git_resolving_merge_conflicts.md deleted file mode 100644 index bd9702a48802..000000000000 --- a/docs/zh-cn/newbs_git_resolving_merge_conflicts.md +++ /dev/null @@ -1,86 +0,0 @@ -# 解决合并冲突 - - - -有时在你致力于一个较长周期才能完成的分支时,其它人提交的变更会与你提交的pull request中的变更发生冲突。我们将这种多个人编辑同一个模块同一个文件时产生的场景叫做 *合并冲突* - -?> 本文中的场景基于[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md)一文。如果你对那篇文章不熟悉,请先阅读它,再回来继续。 - -## 变基/衍合(rebase) - - -Git的*变基*操作会将提交历史中的提交节点摘除并回滚,然后统一提交到一个新节点上。在解决合并冲突时,可以通过对当前分支进行变基,来获取从分支拉取到当前时刻的所有变更。 - -从执行如下命令开始: - -``` -git fetch upstream -git rev-list --left-right --count HEAD...upstram/master -``` - -此处输入的 `git rev-list` 命令可以得到当前分支与QMK主干分支间的提交数量差。而先执行 `git fetch` 是为了确保我们有上游仓库(upstream repo)的最新状态。`git rev-list` 命令会返回两个数字: - -``` -$ git rev-list --left-right --count HEAD...upstream/master -7 35 -``` - -第一个数字为当前分支自创建后新增的提交数量。第二个数字为当前分支创建后在 `upstream/master` 上的提交数量,而这部分就是我们当前分支上缺失的提交记录。 - -在我们了解了当前分支以及上游仓库的状态后,可以发起变基操作了: - -``` -git rebase upstream/master -``` - -这样可以让Git回滚该分支的提交,然后基于QMK的主干版本重新应用这些提交。 - -*译注:以下内容在中文Git下大同小异,且仅作为示例,不进行翻译* -``` -$ git rebase upstream/master -First, rewinding head to replay your work on top of it... -Applying: Commit #1 -Using index info to reconstruct a base tree... -M conflicting_file_1.txt -Falling back to patching base and 3-way merge... -Auto-merging conflicting_file_1.txt -CONFLICT (content): Merge conflict in conflicting_file_1.txt -error: Failed to merge in the changes. -hint: Use 'git am --show-current-patch' to see the failed patch -Patch failed at 0001 Commit #1 - -Resolve all conflicts manually, mark them as resolved with -"git add/rm ", then run "git rebase --continue". -You can instead skip this commit: run "git rebase --skip". -To abort and get back to the state before "git rebase", run "git rebase --abort". -``` - -以上内容是在告诉我们有合并冲突存在,并给出了冲突所在的文件名。在编辑器中打开该文件,可以在某处发现类似如下形式的内容: - -``` -<<<<<<< HEAD -

For help with any issues, email us at support@webhost.us.

-======= -

Need help? Email support@webhost.us.

->>>>>>> Commit #1 -``` - -`<<<<<<< HEAD` 标记了合并冲突的起始行,直至 `>>>>>>> Commit #1` 标记的结束行,中间通过 `=======` 分隔开冲突双方。其中 `HEAD` 部分为QMK主干上的版本,标记了提交日志的部分为当前分支的本地提交。 - -由于Git存储的是*文件差异部分*而非整个文件,所以当Git无法在文件中找到一个变更发生前的内容时,就无法知道如何去进行文件变更,重新编辑一下可以解决问题。在更改完成后,保存文件。 - -``` -

Need help? Email support@webhost.us.

-``` - -之后,执行: - -``` -git add conflicting_file_1.txt -git rebase --continue -``` - -Git即会记录对文件冲突做出的变更,并继续处理剩余的提交,直至全部完成。 diff --git a/docs/zh-cn/newbs_git_resynchronize_a_branch.md b/docs/zh-cn/newbs_git_resynchronize_a_branch.md deleted file mode 100644 index 3f38138f6971..000000000000 --- a/docs/zh-cn/newbs_git_resynchronize_a_branch.md +++ /dev/null @@ -1,76 +0,0 @@ -# 重新同步已失去同步状态的Git分支 - - - -假设你在自己的 `master` 分支之上有提交,并且想和QMK仓库进行同步,可以通过 `git pull` 拉取QMK的 `master` 分支到你的库,但同时Github也会提醒你当前分支相比 `qmk:master` 有几个领先的提交,会在你向QMK发起pr时造成麻烦。 - -?> 本文中的场景基于[在你Fork的主干上:频繁更新,不要提交](zh-cn/newbs_git_using_your_master_branch.md)一文。如果你对那篇文章不熟悉,请先阅读它,再回来继续。 - -## 备份你在自己的主干分支上的所有变更(可选) - -不会有人想把有用的成果弄丢的。如果你想将你的 `master` 分支上的变更另存一份,简便的方法是直接创建一个当前“脏” `master` 分支的副本: - -``` -git branch old_master master -``` - -现在 `master` 分支拥有了一个副本分支 `old_master`。 - -## 重新同步分支 - -现在可以重新同步 `master` 分支了,这里,我们将QMK仓库设置为Git的远程仓库。通过执行 `git remote -v` 可以确认远程仓库配置,输出信息应类似于: - -``` -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -如果你只能看到一个仓库: - -``` -QMKuser ~/qmk_firmware (master) -$ git remote -v -origin https://github.com/qmk/qmk_firmware.git (fetch) -origin https://github.com/qmk/qmk_firmware.git (push) -``` - -通过如下命令添加新的远程仓库: - -``` -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -然后,重新将 `origin` 远程仓库设置为自己的fork: - -``` -git remote set-url origin https://github.com//qmk_firmware.git -``` - -在两个远程仓库配置完毕后,需要从QMK的 upstream 仓库中获取到更新,执行: - -``` -git fetch upstream -``` - -此时,重新同步你的分支到QMK的版本: - -``` -git reset --hard upstream/master -``` - -以上操作会更新你的本地仓库,而你的Github远程仓库仍然处于未同步状态,通过推送,可以让其进入已同步状态。可以通过如下命令来指引Git强行覆盖掉那些仅在你远程仓库中存在的提交: - -``` -git push --force-with-lease -``` - -!> **不要**在其它使用者也会提交的分支上执行 `git push --force-with-lease`,否则会覆盖掉他人的提交。 - -此时你的Github fork,本地文件副本,以及QMK仓库就是一致的了。之后再进行变更([在分支上!](zh-cn/newbs_git_using_your_master_branch.md#making-changes))和提交。 diff --git a/docs/zh-cn/newbs_git_using_your_master_branch.md b/docs/zh-cn/newbs_git_using_your_master_branch.md deleted file mode 100644 index 2a83fc213968..000000000000 --- a/docs/zh-cn/newbs_git_using_your_master_branch.md +++ /dev/null @@ -1,79 +0,0 @@ -# 在你Fork的主干上:频繁更新,不要提交 - - - -我们强烈推荐所有QMK开发者,无论在哪里做什么改动,频繁更新你的 `master` 分支,但***不要***在其上提交。相对地,将你所有的改动提交到开发分支上并提交一个pull request。 - -为了减少冲突 — 多人同时编辑同一个文件 — 保持你的 `master` 分支更新到最新,并在新创建的分支上进行开发。 - -## 更新master分支 - -为了保持 `master` 更新到最新,推荐将QMK固件仓库("repo")设置为git远程仓库。打开Git命令行界面并键入: - -``` -git remote add upstream https://github.com/qmk/qmk_firmware.git -``` - -?> 名称 `upstream` 部分可以任意,这里给的是常用的;你可以将QMK远程仓库名称改成你想要的。Git的 `remote` 命令语法为 `git remote add `, `` 是远程仓库的简写名称,这个名称可以在很多Git命令中使用,包括但不限于 `fetch`,`pull` 及 `push`,以指定目标远程仓库。 - -要验证是否添加成功,可以执行 `git remote -v`,输出应该类似于: - -``` -$ git remote -v -origin https://github.com//qmk_firmware.git (fetch) -origin https://github.com//qmk_firmware.git (push) -upstream https://github.com/qmk/qmk_firmware.git (fetch) -upstream https://github.com/qmk/qmk_firmware.git (push) -``` - -在以上操作完成后,可以通过执行 `git fetch upstream` 来检查仓库是否有更新。该命令从QMK仓库拉取的分支(branches)及标签(tags) — 统称为“refs(引用)” —现在也被称作 `upstream`(上游)。此时我们可以比对自己fork版本的 `origin` 与QMK维护的分支的差异了。 - -要更新你的fork的master分支,执行以下指令,每一行结束都需要按回车: - -``` -git checkout master -git fetch upstream -git pull upstream master -git push origin master -``` - -以上操作会切换到 `master` 分支,从QMK仓库拉取refs,下载QMK `master` 分支的当前版本,并上传至你的fork中。 - -## 进行编辑 :id=making-changes - -要进行编辑,通过如下命令创建一个新分支: - -``` -git checkout -b dev_branch -git push --set-upstream origin dev_branch -``` - -以上操作会创建 `dev_branch` 新分支,检出(check out)并保存到你的fork中。`--set-upstream` 参数用于告知git使用你的fork仓库来处理 `dev_branch` 分支下的 `git push` 及 `git pull` 命令,且仅需要在第一次执行push命令时指定,之后再次执行 `git push` 或是 `git pull` 都无需加入该参数了。 - -?> 在 `git push` 时,可以使用 `-u` 替代 `--set-upstram` — `-u` 为 `--set-upsream` 参数的别名。 - -你可以任意命名该分支,但仍建议对分支起一个可以描述将在该分支下要做的工作的名称。 - -默认情况下 `git checkout -b` 会基于你当前检出的分支作为新分支的基准。可以在后面追加已存在但未检出的分支名来指定新分支的基准: - -``` -git checkout -b dev_branch master -``` - -此时你便有了一个开发用分支,可以打开编辑器并进行你期望的变更了。通常推荐提交大量的小规模提交(commit),这样在需要时会更容易地定位并回滚造成问题的提交。若要提交更改,编辑并保存要更新的文件,并将其添加到*暂存区(staged area)*,然后提交到分支中: - -``` -git add path/to/updated_file -git commit -m "My commit message." -``` - -`git add` 会将更改后的文件放到Git的*暂存区*,也称作Git的“装载区”。这里留存着即将通过 `git commit` 所提交并保存到仓库中的变更。请使用确切的描述来填写提交日志,以便于快速了解改动内容。 - -?> 如果更改了多个文件,可以通过 `git add -- path/to/file1 path/to/file2 ...` 来添加所有项目。 - -## 发布变更 - -最后一步为上传你的变更到你的fork中。通过执行 `git push`,Git将发布 `dev_branch` 分支的所有变更至你的fork中。 diff --git a/docs/zh-cn/newbs_learn_more_resources.md b/docs/zh-cn/newbs_learn_more_resources.md deleted file mode 100644 index 20fed1f35811..000000000000 --- a/docs/zh-cn/newbs_learn_more_resources.md +++ /dev/null @@ -1,35 +0,0 @@ -# 学习资源 - - - -这些资源旨在让QMK社区的新成员更了解新手教程中的基础知识。 - -*译注:以下资料超出了QMK核心概念范畴,恕不另行翻译* - -### QMK参考资料 - -* [Thomas Baart's QMK Basics Blog](https://thomasbaart.nl/category/mechanical-keyboards/firmware/qmk/qmk-basics/) – 一个站在新人视角,探讨如何使用QMK固件的个人博客。 - -### 命令行操作参考资料 :id=command-line-resources - -* [Good General Tutorial on Command Line](https://www.codecademy.com/learn/learn-the-command-line) -* [Must Know Linux Commands](https://www.guru99.com/must-know-linux-commands.html)
-* [Some Basic Unix Commands](https://www.tjhsst.edu/~dhyatt/superap/unixcmd.html) - -### 文本编辑器相关参考资料 :id=text-editor-resources - -对文本编辑器有选择困难? -* [a great introduction to the subject](https://learntocodewith.me/programming/basics/text-editors/) - -更适用于编程的文本编辑器: -* [Sublime Text](https://www.sublimetext.com/) -* [VS Code](https://code.visualstudio.com/) - -### Git参考资料 - -* [Great General Tutorial](https://www.codecademy.com/learn/learn-git) -* [Flight Rules For Git](https://github.com/k88hudson/git-flight-rules) -* [Git Game To Learn From Examples](https://learngitbranching.js.org/) diff --git a/docs/zh-cn/newbs_testing_debugging.md b/docs/zh-cn/newbs_testing_debugging.md deleted file mode 100644 index 0016d3b8169c..000000000000 --- a/docs/zh-cn/newbs_testing_debugging.md +++ /dev/null @@ -1,14 +0,0 @@ -# 测试和调试 - - -## 测试 - -[已移到这里](zh-cn/faq_misc.md#testing) - -## 调试 :id=debugging - -[已移到这里](zh-cn/faq_debug.md#debugging) - diff --git a/docs/zh-cn/other_eclipse.md b/docs/zh-cn/other_eclipse.md deleted file mode 100644 index d0783c2070b0..000000000000 --- a/docs/zh-cn/other_eclipse.md +++ /dev/null @@ -1,90 +0,0 @@ -# 在Eclipse中设置QMK开发环境 - - - - -[Eclipse][1]是一款广泛用于Java开发的[集成开发环境](https://en.wikipedia.org/wiki/Integrated_development_environment)(IDE),但有着强大的插件体系允许自定义开发其它语言及用途。 - -相对于使用普通的文本编辑器,使用形如Eclipse这样的IDE有着诸多好处,例如: -* 智能代码补全 -* 快速代码跳转 -* 重构工具 -* 构建自动化(无需使用命令行) -* 图形化交互的GIT -* 静态代码分析 -* 以及大量其它工具,如调试器,代码格式化,显示调用链等。 - -本文专注于阐述如何将Eclipse配置为AVR软件开发环境,并用于基于QMK代码的开发工作。 - -注意,在本文编写时,仅在Ubuntu 16.04环境中进行过验证。 - -# 需求 -## 构建环境 -在开始之前,你需要确保遵循了新手教程中的[新手指引](zh-cn/newbs_getting_started.md)一节。通常,此时你应该具备了[通过 `qmk complile` 命令](zh-cn/newbs_building_firmware.md#build-your-firmware)构建固件文件的能力。 - -## Java -Eclipse为Java程序,因此需要安装Java 8或更高版本才能运行。你可以选择JRE或JDK,后者在进行Java开发时需要用到。 - -# 安装Eclipse及插件 -Eclipse有[多种可选安装方式](https://www.eclipse.org/downloads/eclipse-packages/),取决于你的使用目标。目前没有完备的AVR开发栈安装包,所以我们需要从Eclipse CDT(C/C++ 开发工具环境)开始并安装对应的插件。 - -## 下载安装Eclipse CDT -如果系统中已安装了Eclipse CDT,可以跳过本步骤。同时,为了确保版本支持情况,我们推荐保持其更新至最新版。 - -如果你已安装了Eclipse包,通常也可以[在上面再安装CDT插件](https://eclipse.org/cdt/downloads.php)。但是可能更好的方案是重新全新安装一下,以确保环境轻量,以及防止已安装的工具对后续的工程开发工作产生干扰。 - -安装很简单:遵循[Eclipse安装5步走](https://eclipse.org/downloads/eclipse-packages/?show_instructions=TRUE),并在第三步选择 **用于C/C++开发者的Eclipse IDE(Eclipse IDE for C/C++ Developers)**。 - -此外,也可以选择直接[下载 用于C/C++开发者的Eclipse IDE](https://www.eclipse.org/downloads/eclipse-packages/)([最新版直达链接](https://www.eclipse.org/downloads/packages/eclipse-ide-cc-developers/neonr))并解压至任意目录下(会生成 `eclipse` 目录)。 - -## 首次运行 -在安装完毕后,点击运行按钮。(如果是手动解压的,请在安装目录下双击 `eclipse` 可执行程序 - -在提示你选择工作区目录时,选择一个可用于存储Eclipse元数据及工程的目录。**不要选择 `qmk_firmware` 目录**,这是你的项目目录。可以使用其父目录,或其它(最好是空)目录(默认目标目录如果未作他用亦可使用)。 - -启动后,点击右上角的工作台(Workbench)按钮切换到工作台视图(启动时的欢迎页最下方有个确认框可以在下次启动时不再展示欢迎页)。 - -## 安装必要的插件 -注意:无需在每个插件安装完成时重启Eclipse,全部安装完毕后重启一次即可。 - -### [AVR插件](https://avr-eclipse.sourceforge.net/) -这是最重要的一个插件,可以帮助Eclipse理解AVR下的C语言代码。参照执行[更新网址使用指引](https://avr-eclipse.sourceforge.net/wiki/index.php/Plugin_Download#Update_Site),并允许那些未签名内容产生的警告。 - -### [ANSI Escape in Console(命令行下的ANSI转义符)](https://marketplace.eclipse.org/content/ansi-escape-console) -该插件可以允许QMK makefile产生的具有颜色标记的构建输出信息能够正确显示。 - -1. 打开帮助 > Eclipse插件市场… -2. 搜索_ANSI Escape in Console_ -3. 点击插件的安装按钮 -4. 跟随安装指引并再次允许那些未签名的内容产生的警告。 - -在插件皆安装完毕后,依照提示重启Eclipse。 - -# 配置Eclipse QMK环境 -## 导入工程 -1. 点击文件 > 新建 > 现有的Makefile工程代码 -2. 在之后这一页中: - * 选择仓库所克隆到的目录位置作为 _现有代码位置_; - * (可选地)指定一个不同的工程名,如 _QMK_ 或 _Quantum_ ; - * 选择 _AVR-GCC Toolchain_; - * 其它选项保留不动,点击完成 - - ![Importing QMK in Eclipse](https://i.imgur.com/oHYR1yW.png) - -3. 工程即完成加载及分析,其下的文件可以方便地在左侧的 _Project Explorer_ 中查看了。 - -¹ 导入工程时若自定义名称有时会遇到些问题,如果行不通,保留默认的工程名(即目录名,通常是 `qmk_firmware`)再试一次。 - -## 构建你的键盘 - -我们将默认构建目标从 `all` 调整到我们期望构建的键盘及键映射组合上,即 `kinesis/kint36:stapelberg`。此时,形如清理、构建等工程级别的操作可以很快地执行完毕,而不至于耗费大量时间且导致Eclipse卡住。 - -1. 焦点置于工程下的任一编辑器tab中 -2. 打开`工程` > `属性`窗口, 选择 `C/C++构建` 菜单项并切至 `Behavior` 标签。 -3. 将 `Make build target`选项中的全量构建 `all` 改为 `kinesis/kint41:stapelberg`。 -4. 点击 `工程` > `清理...` 以确认配置正确。 - - [1]: https://en.wikipedia.org/wiki/Eclipse_(software) diff --git a/docs/zh-cn/other_vscode.md b/docs/zh-cn/other_vscode.md deleted file mode 100644 index 5f66eb65922e..000000000000 --- a/docs/zh-cn/other_vscode.md +++ /dev/null @@ -1,120 +0,0 @@ -# 在Visual Studio Code中设置QMK开发环境 - - - -[Visual Studio Code](https://code.visualstudio.com/) (VS Code) 是一款支援非常多种不同编程语言的开源编辑器。 - -相比于使用简陋的文本编辑器,形如VS Code这样的多功能编辑器有诸多优势,比如: -* 智能的代码补全 -* 便捷的代码导航 -* 重构工具 -* 自动化构建支持(不再需要命令行操作) -* 图形化的GIT界面 -* 调试器、代码格式化、显示调用层级等多种工具 - -本章节旨在阐述如何配置VS Code以在其上进行QMK固件开发。 - -这份指引提供了在Windows及Ubuntu 18.04下所有的配置方法。 - -# 配置VS Code -一开始,你需要首先确认所有的构建工具已经安装配置完成,且QMK Firmware仓库已拷贝至本地。前往参阅[新人指引](zh-cn/newbs_getting_started.md)确保已完成初始配置。 - -## Windows - -### 依赖项 - -* [Git for Windows](https://git-scm.com/download/win) (该链接会自动提示你保存或运行安装包) - - 1. 除 `Git LFS (Large File Support)(大文件支援)` 及 `Check daily for Git for Windows updates(每天检查更新)` 外取消所有可选项。 - 2. 将默认编辑器改为 `Use Visual Studio Code as Git's default editor(将VS Code作为默认编辑器)` - 3. 选择 `Use Git from Git Bash only(仅在Git Bash中使用Git)`,这是应使用的方案。 - 4. 在 `Choosing HTTPS transport backend(选择HTTPS传输服务)` 选项上,皆可。 - 5. 选择 `Checkout as-is, commit Unix-style line endings(检出不作更改,提交时使用Unix风格换行符)`,QMK仓库使用的是Unix style提交。 - 6. 在额外选项页,保持默认选择即可。 - - 该软件是VS Code支持Git的所需项目,是有可能不去使用它,但直接用它会省很多事。 - -* [Git Credential Manager for Windows(Windows版Git凭据管理器)](https://github.com/Microsoft/Git-Credential-Manager-for-Windows/releases) (可选) - - 该软件提供了更好的git 凭据加密存储、多因素身份认证(MFA)及私有访问token生成器。 - - 这个不是严格必须的,但我们依旧推荐使用。 - - -### 安装VS Code - -1. 到[VS Code](https://code.visualstudio.com/)下载安装包 -2. 运行安装包 - -很简单的操作。然而,仍有一些配置我们需要确保是设置正确的。 - -### VS Code设置 - -首先来配置IntelliSense,虽不是严格必要的,但能让你后续使用便捷**很多**。首先,在QMK Firmware目录下创建文件 `.vscode/c_cpp_properties.json`,之后的操作可以手动完成,但我已经完成了大部分。 - -获取[这份文件](https://gist.github.com/drashna/48e2c49ce877be592a1650f91f8473e8),如果你的MSYS2没有安装在默认路径,或在用WSL/LxSS,你可能需要做一下编辑修改。 - -在保存妥当后,如果你有已打开的VS Code,你需要reload一下。 - -?> 在 `.vscode` 目录下你应该还能看到 `extensions.json` 和 `settings.json` 文件。 - -现在,我们配置MSYS2作为VSCode的集成终端。这么做有很多好处,最主要的是可以通过按住control点击错误消息直接跳转到文件,调试起来会简单得多,另外的好处是,你不用在窗口间切换。 - -1. 点击 文件 > 首选项 > > 设置 -2. 点击上方右侧的 {} 按钮,打开 `settings.json` 文件。 -3. 将文件改为: - - ```json - { - "terminal.integrated.profiles.windows": { - "QMK_MSYS": { - "path": "C:/QMK_MSYS/usr/bin/bash.exe", - "env": { - "MSYSTEM": "MINGW64", - "CHERE_INVOKING": "1" - }, - "args": ["--login"] - } - }, - - "terminal.integrated.cursorStyle": "line" - } - ``` - - 如果该文件内已经有一些配置项,将上面的内容粘贴在最外层的花括号内,并用一个逗号将新旧内容分隔开。 - -?> 如果你的MSYS2安装在不同的目录下,你需要将 `terminal.integrated.shell.windows` 更改为你系统中正确的目录。 - -4. 点击Ctrl-` (Grave) 或在 视图 > 终端 可以打开终端界面 (`workbench.action.terminal.toggleTerminal` 命令)。如果没有终端它会自动打开一个。 - - 终端应启动于工程目录中(即 `qmk_firmware` 目录),之后你可以构建键盘了。 - - -## 其它系统 - -1. 到[VS Code](https://code.visualstudio.com/)下载安装包 -2. 运行安装包 -3. 搞定 - -是的,确实是搞定了。安装的时候所有所需的路径配置都会被包含进来,在检查当前工程文件并进行IntelliSense解析上表现也会更好。 - -## 插件 - -有一些你可能感兴趣的扩展可以安装: - -* [Git Extension Pack](https://marketplace.visualstudio.com/items?itemName=donjayamanne.git-extension-pack) - 提供了一系列的Git工具可以让你在QMK Firmware中使用Git便捷一些。 -* [EditorConfig for VS Code](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) - _[可选]_ - 可以让你的代码更符合QMK规范。 -* [GitHub Markdown Preview](https://marketplace.visualstudio.com/items?itemName=bierner.github-markdown-preview) - _[可选]_ - 使得VS Code下的markdown预览更符合Github的效果。 -* [VS Live Share Extension Pack](https://marketplace.visualstudio.com/items?itemName=MS-vsliveshare.vsliveshare-pack) - _[可选]_ - 这个扩展允许他人访问你的工作区(或反之)进行协作,在你遇到问题需要他人帮助时挺有用。 - -安装扩展后需要重启VS Code。 - -# 配置VS Code下的QMK -1. 点击 文件 > 打开目录 -2. 打开你从Github克隆的QMK固件仓库所在目录。 -3. 点击 文件 > 保存工作区为... - -此时你已完成了在VS Code下编写QMK固件的准备工作。 diff --git a/docs/zh-cn/reference_configurator_support.md b/docs/zh-cn/reference_configurator_support.md deleted file mode 100644 index bd842871a0fe..000000000000 --- a/docs/zh-cn/reference_configurator_support.md +++ /dev/null @@ -1,200 +0,0 @@ -# 在QMK配置器中支持您的键盘 - - - -本章节详述了如何在[QMK配置器](https://config.qmk.fm/)中对键盘进行支持。 - - -## 配置器如何理解键盘 - -若要了解配置器如何理解键盘,须先理解配列的宏定义。这里有一份练习,假设这里有一个17键的小键盘PCB方案,就叫做 `numpad`。 - -``` -|---------------| -|NLk| / | * | - | -|---+---+---+---| -|7 |8 |9 | + | -|---+---+---| | -|4 |5 |6 | | -|---+---+---+---| -|1 |2 |3 |Ent| -|-------+---| | -|0 | . | | -|---------------| -``` - -?> 配列宏定义的更多资料,参见[理解QMK:矩阵扫描](zh-cn/understanding_qmk.md?id=matrix-scanning)及[理解QMK:矩阵到物理配列的映射](zh-cn/understanding_qmk.md?id=matrix-to-physical-layout-map)。 - -配置器的API会从 `qmk_firmware/keyboards//.h` 中读取键盘定义的 `.h` 文件。在上面的小键盘示例中,对应文件应为 `qmk_firmware/keyboards/numpad/numpad.h`: - -```c -#pragma once - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, KC_NO }, \ - { k30, k31, k32, k33 }, \ - { k40, KC_NO, k42, KC_NO } \ -} -``` - -QMK使用 `KC_NO` 去标记开关矩阵中的空位。有时也会因方便或调试用途而使用 `XXX`,`___` 或 `____` 来替代。通产定义写在 `.h` 文件起始位置附近: - -```c -#pragma once - -#define XXX KC_NO - -#define LAYOUT( \ - k00, k01, k02, k03, \ - k10, k11, k12, k13, \ - k20, k21, k22, \ - k30, k31, k32, k33, \ - k40, k42 \ - ) { \ - { k00, k01, k02, k03 }, \ - { k10, k11, k12, k13 }, \ - { k20, k21, k22, XXX }, \ - { k30, k31, k32, k33 }, \ - { k40, XXX, k42, XXX } \ -} -``` - -!> 注意这里的使用模式与键映射中的宏完全不同,后者几乎都在用 `XXXXXXX`(7个大写X)替代 `KC_NO`,用 `_______`(7个下划线)替代 `KC_TRNS`。 - -!> 为避免混淆,推荐使用 `KC_NO`。 - -配列宏定义描述该键盘有17个按键,分布在五行四列。我们将这些开关命名为 `k<行号><列号>`,从0计起。命名成什么不太重要,但须确保负责从键映射中接收键码的上半段,与描述矩阵中按键位置的下半段定义匹配一致。 - -为了能够重现键盘的物理组成样式,须构建并提供一份用于描述按键物理位置和尺寸与开关矩阵绑定关系的JSON文件,以告知配置器程序这些信息。 - -## 构建JSON文件 - -构建该JSON描述文件最简便的办法是使用[Keyboard Layout Editor](https://www.keyboard-layout-editor.com/) ("KLE"), 从中获取的原始数据(Raw Data)可以经QMK工具转换为配置器可用的JSON格式数据。由于KLE默认打开显示的是一个小键盘配列,请移除新手引导部分,从剩余部分开始使用。 - -在配列编辑完毕后,从KLE的原始数据(Raw Data tab)页中拷贝类似如下的内容: - -``` -["Num Lock","/","*","-"], -["7\nHome","8\n↑","9\nPgUp",{h:2},"+"], -["4\n←","5","6\n→"], -["1\nEnd","2\n↓","3\nPgDn",{h:2},"Enter"], -[{w:2},"0\nIns",".\nDel"] -``` - -要将这份数据转换为我们可用的JSON格式,请跳转至[QMK KLE-JSON转换工具](https://qmk.fm/converter/)页面并粘贴到输入框,点击转换按钮。稍后输出框中即可看到所需的JSON数据。将输出数据拷贝到文本文档中,并命名为 `info.json`,保存到 `numpad.h` 所在目录。 - -可以通过 `keyboard_name` 元素来指定键盘名称。这里为了演示,会将每个按键独立分行,以更方便于阅读,这不影响配置器的功能。 - -```json -{ - "keyboard_name": "Numpad", - "url": "", - "maintainer": "qmk", - "tags": { - "form_factor": "numpad" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label":"Num Lock", "x":0, "y":0}, - {"label":"/", "x":1, "y":0}, - {"label":"*", "x":2, "y":0}, - {"label":"-", "x":3, "y":0}, - {"label":"7", "x":0, "y":1}, - {"label":"8", "x":1, "y":1}, - {"label":"9", "x":2, "y":1}, - {"label":"+", "x":3, "y":1, "h":2}, - {"label":"4", "x":0, "y":2}, - {"label":"5", "x":1, "y":2}, - {"label":"6", "x":2, "y":2}, - {"label":"1", "x":0, "y":3}, - {"label":"2", "x":1, "y":3}, - {"label":"3", "x":2, "y":3}, - {"label":"Enter", "x":3, "y":3, "h":2}, - {"label":"0", "x":0, "y":4, "w":2}, - {"label":".", "x":2, "y":4} - ] - } - } -} -``` - -`layouts` 对象描述了键盘的物理配列信息,其下的 `LAYOUT` 对象命名须与 `numpad.h` 中的一致,而 `LAYOUT` 下的 `layout` 对象,其下每个JSON对象描述了各物理按键,格式如下: - -``` - 按键名,不会在配置器中展现。 - | - | 按键的X坐标,从键盘左侧开始数。 - | | - | | - | | 按键的Y坐标,从键盘上侧(后视角)开始数。 - | | | - ↓ ↓ ↓ -{"label":"Num Lock", "x":0, "y":0}, -``` - -部分对象包含 `"w"` 和 `"h"` 字段,用以描述按键的宽高值。 - -?> 关于 `info.json` 文件的详细信息,参见[`info.json` 文件格式](zh-cn/reference_info_json.md)。 - - -## 配置器如何配置按键 - -配置器API基于配列宏定义及JSON描述文件创建出键盘的可视化展现,并将每个可视化元素依序绑定到指定的按键: - -配列宏定义中的键 | 所使用的JSON对象 -:---: | :---- -k00 | {"label":"Num Lock", "x":0, "y":0} -k01 | {"label":"/", "x":1, "y":0} -k02 | {"label":"*", "x":2, "y":0} -k03 | {"label":"-", "x":3, "y":0} -k10 | {"label":"7", "x":0, "y":1} -k11 | {"label":"8", "x":1, "y":1} -k12 | {"label":"9", "x":2, "y":1} -k13 | {"label":"+", "x":3, "y":1, "h":2} -k20 | {"label":"4", "x":0, "y":2} -k21 | {"label":"5", "x":1, "y":2} -k22 | {"label":"6", "x":2, "y":2} -k30 | {"label":"1", "x":0, "y":3} -k31 | {"label":"2", "x":1, "y":3} -k32 | {"label":"3", "x":2, "y":3} -k33 | {"label":"Enter", "x":3, "y":3, "h":2} -k40 | {"label":"0", "x":0, "y":4, "w":2} -k42 | {"label":".", "x":2, "y":4} - -当用户在配置器中选中左上角的按键,并赋予数字区锁定键(NumLock)时,配置器会将 `KC_NUM` 作为第一个按键进行键映射文件的构建工作,其它按键逻辑类似。其中 `label` 键值未被用到,其用于用户在调试 `info.json` 文件时,可以参考辨认出各按键。 - - -## 问题及副作用 - -目前配置器还不支持按键偏转及类似ISO回车键这种非矩形按键。另外,对于纵向上偏离其行的按键 — 特别是像[TKC1800](https://github.com/qmk/qmk_firmware/tree/4ac48a61a66206beaf2fdd5f2939d8bbedd0004c/keyboards/tkc1800/)这种1800配列的键盘中的方向键 — 如果 `info.json` 文件的贡献者没有做出修正,KLE转JSON数据工具将会不知如何处理。 - -### 解决方案 - -#### 非矩阵形状的按键 - -针对ISO回车键的情况,QMK会将其定制化显示成一个矩形键,宽1.25u高2u,按键矩阵的右边与字母区的右边对齐。 - -![](https://i.imgur.com/JKngtTw.png) -*一款60% ISO配列的键盘, 在QMK配置器中的渲染样式。* - -#### 纵向偏移的按键 - -对于纵向偏移的按键,将其视作未偏移的样子放入KLE,最后在转换后的JSON文件中,按需编辑其Y偏移值。 - -![](https://i.imgur.com/fmDvDzR.png) -*一款1800配列键盘在KLE中的渲染样式,方向键未进行纵向偏移移动。* - -![](https://i.imgur.com/8beYMBR.png) -*这份Unix差异文件,展示了我们需要在JSON文件中进行的纵向偏移改动。* diff --git a/docs/zh-cn/reference_glossary.md b/docs/zh-cn/reference_glossary.md deleted file mode 100644 index e1dfccddd216..000000000000 --- a/docs/zh-cn/reference_glossary.md +++ /dev/null @@ -1,198 +0,0 @@ -# QMK术语表 - - - -## ARM -多家公司生产的32位单片机系列,例如Atmel, Cypress, Kinetis, NXP, ST, 和 TI等公司。 - -## AVR -[Atmel](https://www.microchip.com/)公司的单片机系列。 AVR是TMK的初始支持平台。 - -## AZERTY -Français (法语)标准键盘布局。用键盘的前六个字母命名。 - -## Backlight(背光) -键盘上照明的通称。背光通常是一组LED灯,穿过键帽或者轴体发光,但也不总是这样。 - -## Bluetooth(蓝牙) -一种短距离点对点无线传输协议。许多无线键盘使用此协议。 - -## Bootloader(引导加载程序) -一种写到你单片机保护区的特殊程序,该程序可以使单片机升级自己的固件,通常是通过USB来升级。 - -## Bootmagic(热改键) -允许各种键盘行为动态变化的功能,如交换或禁用常用键。 - -## C -一种适用于系统代码的低级编程语言。大多数qmk代码是用C编写的。 - -## Colemak -一种流行的键盘布局。 - -## Compile(编译) -把人可读的代码转换成你的单片机可以运行的机器代码的过程。 - -## Dvorak -一个由August Dvorak博士在20世纪30年代创建的布局。Dvorak简化键盘(Dvorak Simplified Keyboard)的缩写。 - -## Dynamic Macro(动态宏) -一种记录在键盘上的宏,当键盘拔出或计算机重新启动时,宏将丢失。 - -* [动态宏文档](zh-cn/feature_dynamic_macros.md) - -## Eclipse -是一种受C语言开发者追捧的集成开发环境(IDE)。 - -* [Eclipse安装说明](zh-cn/other_eclipse.md) - -## Firmware(固件) -用来控制单片机的软件。 - -## git -命令行版本控制软件 - -## GitHub -负责大多数QMK项目的网站。它是Git、问题跟踪和其他帮助我们运行qmk的功能的集成平台。 - -## ISP(在线系统编程) -在线系统编程(In-system programming), 使用外部硬件和JTAG管脚对AVR芯片进行编程的一种方法。 - -## hid_listen -从键盘接收调试消息的接口。 您可以使用[QMK Flasher](https://github.com/qmk/qmk_flasher)或[PJRC's hid_listen](https://www.pjrc.com/teensy/hid_listen.html)查看这些消息 - -## Keycode(键码) -表示特定键的2字节数据。`0x00`-`0xFF`用于[基本键码](zh-cn/keycodes_basic.md)而`0x100`-`0xFFFF`用于[量子键码](zh-cn/quantum_keycodes.md). - -## Key Down -一个键按下尚未抬起时触发的事件。 - -## Key Up -一个键抬起时触发的事件。 - -## Keymap(键映射) -映射到物理键盘布局的一组键码,在按键和按键释放时进行处理。有时翻译为布局,意为软件上表示的布局,即映射。 - -## Layer(层) -为了让一个键实现多个功能的抽象结构。可用层数有上限。 - -## Leader Key(前导键、设置菜单键) -本功能允许您点击前导键,然后按顺序按1-3个键子来激活按键或其他量子功能。 - -* [前导键文档](zh-cn/feature_leader_key.md) - -## LED -发光二极管,键盘上最常用的指示灯装置。 - -## Make -用于编译所有源文件的软件包。可以使用`make`命令和其他参数来编译你的固件。 - -## Matrix(矩阵) -一种由列和行组成的接线模式,使单片机能够用较少的引脚检测按键。矩阵通常包含二极管,以达到全键无冲。 - -## Macro(宏) -本功能可以在敲击单个键后发送多个按键事件(hid报告)。 - -* [宏文档](zh-cn/feature_macros.md) - -## MCU(单片机、微控制单元) -微控制单元,键盘的处理器。 - -## Modifier(修饰键、修改键、功能键) -按住该键将会改变其他键的功能,修饰键包括 Ctrl, Alt, 和 Shift。 - -## Mousekeys(鼠标键) -本功能在您敲击键盘时会控制鼠标光标。 - -* [鼠标键文档](zh-cn/feature_mouse_keys.md) - -## N-Key Rollover (NKRO、全键无冲) -一种术语,适用于能够同时报告任意数量按键的键盘。 - -## Oneshot Modifier(粘滞键) -一种能让你的功能键一直保持按下,直到你按下其他键的功能。它叫做粘滞键或叫做粘连键,该功能由软件实现而非机械结构。 - -## ProMicro -一种低成本AVR开发板。这种板子很容易在购物网站找到(价格不到20RMB),但是据说刷写pro micro有点令人抓狂。 - -## Pull Request(拉请求、PR) -向QMK请求提交代码。我们鼓励所有用户提交你们自己的键盘的代码。 - -## QWERTY -标准英文键盘,通常也用于其他语言,例如中文。是用键盘前6个字母命名的。 - -## QWERTZ -标准Deutsche(德语)键盘布局。使用前6个字母明名。 - -## Rollover(允许翻转、无冲形式) -该术语表示在一个键已按下时按下另一个键。形式包括2KRO(双键无冲),6KRO(6键无冲),和NKRO(全键无冲),无冲表示可同时按下而不产生冲突的键的数量。 - -## Scancode(扫描码) -HID报告中的一个1字节的数字,表示一个键子。这些数字在下列文档中[HID Usage Tables](https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf)该文档发布于[USB-IF](https://www.usb.org/)。 - -## Space Cadet键盘的shift键 -一种特殊的shift设置,能让你通过敲击左或右shift一次或多次键入不同的括号。 - -* [Space Cadet键盘文档](zh-cn/feature_space_cadet.md) - -## Tap(敲击、单击) -按下并抬起一个键。在某些情况下您需要区分键按下和键抬起,但是单击把两个事件都包括了。 - -## Tap Dance(多击键) -本功能允许向同一个键子分配多个键码,并根据按键次数区分。 - -* [多击键文档](zh-cn/feature_tap_dance.md) - -## Teensy -一种低成本AVR开发板,通常用于手工连线键盘。这个teensy是有点小贵但是halfkay bootloader会让它刷写十分简单,所以也很常用。 - -## Underlight(背光) -用于照亮电路板底面的LED的总称。这些LED通常从印刷电路板的底部向键盘所在的表面发光。 - -## Unicode -在广阔的计算机世界中,Unicode是一组编码方案,用于表示任何语言中的字符。 与qmk相关的是,它意味着使用各种操作系统方案来发送Unicode码点,而不是扫描码。 - -* [Unicode文档](zh-cn/feature_unicode.md) - -## Unit Testing(单元测试) -针对qmk的自动测试框架。单元测试帮助我们确信我们的更改不会破坏任何东西。 - -* [单元测试文档](zh-cn/unit_testing.md) - -## USB -通用串行总线,键盘最常见的有线接口。 - -## USB 主机 (简称主机) -USB主机就是你的电脑,或者你的键盘所插的任何设备。 - -# 并没有找到你想找到的术语? - -[新建一个issue](https://github.com/qmk/qmk_firmware/issues) ,想好你的问题,或许你所问的术语就会添加到这里。创建一个PR帮我们添加需要添加的术语当然坠吼了:) - -## 中文翻译术语特别说明(terms of Chinese translation):id=terms-of-zh-cn-translate -!>如果你对QMK文档翻译中的细节不关心,请跳过该节 - -由于语言及文化差异,QMK英文文档中的部分内容,很难在**保持原句结构**的情况下,完美地翻译为中文,而保持翻译前后的语句结构一致对于开源代码的文档翻译来讲十分重要,这样才能确保不同的文档贡献者不会*夹带私货*,防止不同的翻译风格、不同的翻译水准、不同的理解与润色最终产生糟糕的混合。 -因此,这里会对一些词组的的翻译进行规范化,并希望阅读者及后续文档翻译维护者,维持这种统一的范式。 - -### keyboard(键盘)及keymap(键映射) -QMK文档中使用最多的两个术语是keyboard及keymap -* 键盘:在中文语境下,我们提及键盘,基本是在指物理键盘,而在QMK文档中到处可见的“键盘”一词,多对应的是代码中 `keyboards\` 目录下的键盘定义,其更接近于我们讲的“配列”的概念,主要描述了键盘的大体结构,物理键数量及排列。 -* 键映射:keymap的作用是定义物理键盘到实际输出键值(keycode)的映射关系,也是QMK最重要、涉及最多的概念。QMK很多功能就是为了能够在不改变键盘物理排列/电路组成/芯片程序的情况下,动态地改变物理按键输出的键值。如,通过层切换,将原先的wasd键,切换到可以上下左右的模式,或是一键切换CapsLock和Control,实现这些功能的核心工作就是一套动态的keymap,即键映射逻辑。这里不使用“布局”一词作为keymap的翻译,是因为该词过于宽泛。键映射即便是不好听,至少解释了意思且语境中不容易误解。 - -### mod-tap -倾向于不翻译,直接使用原词。因为找不到合适的译法 - -### dead key -直译为死键,西语体系下使用的特殊符号,中文中无对应概念。 - -### flashing(firmware) -使用“刷写”而非容易迷惑的“刷新” - -### option/configuration/setting -根据上下文灵活考虑。对于组件化配置的概念,如一个功能支持与否,使用“配置”一词;对于客观上一定存在的某项设置值,使用“设置”一词。 - -### commit/push/pull等Git术语 -倾向于不翻译。这些词语的对应中文词语过于宽泛或词性不明,非常容易混淆上下文。 diff --git a/docs/zh-cn/support.md b/docs/zh-cn/support.md deleted file mode 100644 index e636d29c9724..000000000000 --- a/docs/zh-cn/support.md +++ /dev/null @@ -1,22 +0,0 @@ -# 寻求帮助 - - - -你可以从很多渠道获取QMK帮助。 - -在你前往社区进行沟通前,请先阅览我们的社区[行为守则](https://qmk.fm/coc/) - -## 实时沟通 - -在你需要帮助时,最便捷的办法是通过我们的[Discord服务器](https://discord.gg/Uq7gcHh)进行沟通,通常会有人在线,也有很多乐于助人的人。 - -## OLKB Subreddit - -QMK的官方论坛是[reddit.com](https://reddit.com)上的[/r/olkb](https://reddit.com/r/olkb). - -## GitHub Issues - -你可以在[Github上发Issue](https://github.com/qmk/qmk_firmware/issues),对于需要深入讨论或需要调试的问题,会方便得多。 diff --git a/docs/zh-cn/syllabus.md b/docs/zh-cn/syllabus.md deleted file mode 100644 index d0b861530ae8..000000000000 --- a/docs/zh-cn/syllabus.md +++ /dev/null @@ -1,77 +0,0 @@ -# QMK大纲 - - - -这一页旨在帮你建立关于QMK的相关基础知识,并提供能引导你成为QMK大师所需的所有概念。 - -# 基本概念 - -如果你还没有看其它部分,先阅读这一节吧。在阅读了[介绍](zh-cn/newbs.md)之后,你可以制作、编译、刷写一个简单的键映射了,以下文档可以助你充实各系列的知识。 - -* **了解如何使用QMK** - * [介绍](zh-cn/newbs.md) - * [CLI](zh-cn/cli.md) - * [GIT](zh-cn/newbs_git_best_practices.md) -* **了解键映射** - * [层](zh-cn/feature_layers.md) - * [键码](zh-cn/keycodes.md) - * 含所有可用键码,一些会涉及进阶或高级的话题。 -* **配置IDE** - 可选的 - * [Eclipse](zh-cn/other_eclipse.md) - * [VS Code](zh-cn/other_vscode.md) - -# 进阶话题 - -包含窥探QMK主要功能内部原理的话题。你可以不用阅读这些,然而,跳过这些话题的话,去看高级话题的时候会让你很迷惑。 - -* **各功能的配置** - - * [音频](zh-cn/feature_audio.md) - * 灯光 - * [背光](zh-cn/feature_backlight.md) - * [LED矩阵](zh-cn/feature_led_matrix.md) - * [RGB灯光](zh-cn/feature_rgblight.md) - * [RGB矩阵](zh-cn/feature_rgb_matrix.md) - * [点按配置](zh-cn/tap_hold.md) - * [充分利用AVR的存储空间](zh-cn/squeezing_avr.md) -* **深入键映射** - * [键映射](zh-cn/keymap.md) - * [键码与自定义函数](zh-cn/custom_quantum_functions.md) - * 宏 - * [动态宏](zh-cn/feature_dynamic_macros.md) - * [宏](zh-cn/feature_macros.md) - * [Tap Dance](zh-cn/feature_tap_dance.md) - * [组合键](zh-cn/feature_combo.md) - * [用户空间](zh-cn/feature_userspace.md) - * [按键重定义](zh-cn/feature_key_overrides.md) - -# 高级话题 - -这些话题需要较多基础知识,使用这些高级功能前,你应该对如何通过 `config.h` 和 `rules.mk` 来配置键盘选项非常熟悉。 - -* **维护QMK键盘** - * [飞线指南](zh-cn/hand_wire.md) - * [键盘开发指引](zh-cn/hardware_keyboard_guidelines.md) - * [info.json参考资料](zh-cn/reference_info_json.md) - * [防抖API](zh-cn/feature_debounce_type.md) -* **高级功能** - * [Unicode](zh-cn/feature_unicode.md) - * [API](zh-cn/api_overview.md) - * [Bootmagic Lite](zh-cn/feature_bootmagic.md) -* **硬件相关** - * [键盘工作原理](zh-cn/how_keyboards_work.md) - * [键盘矩阵原理](zh-cn/how_a_matrix_works.md) - * [分体键盘](zh-cn/feature_split_keyboard.md) - * [速记](zh-cn/feature_stenography.md) - * [光标设备](zh-cn/feature_pointing_device.md) -* **开发核心知识** - * [C编码规范](zh-cn/coding_conventions_c.md) - * [兼容的微处理器](zh-cn/compatible_microcontrollers.md) - * [自定义矩阵](zh-cn/custom_matrix.md) - * [理解QMK](zh-cn/understanding_qmk.md) -* **CLI开发** - * [编码规范](zh-cn/coding_conventions_python.md) - * [CLI开发总览](zh-cn/cli_development.md) diff --git a/docs/zh-cn/translating.md b/docs/zh-cn/translating.md deleted file mode 100644 index fa80ffd7f85a..000000000000 --- a/docs/zh-cn/translating.md +++ /dev/null @@ -1,60 +0,0 @@ -# 翻译QMK文档 - - - -根目录下(`docs/`)的所有文件应当是英语的 - 其它语言应使用 ISO 639-1 中定义的语言编码建立子目录,后跟随一个 `-` 以及必要的国家编码。[常见的语言编码可见这里](https://www.andiamo.co.uk/resources/iso-language-codes/)。如果此目录不存在,可以新建。每个翻译过的文件的文件名,都应保持与英语版本的一致,以确保超链接的退化兼容性。 - -文件夹下的 `_summary.md` 文件中,有链接向其它文件的地址,在翻译过的名称后,跟随的链接前应添加该语言的目录名: - -```markdown - * [QMK简介](zh-cn/getting_started_introduction.md) -``` - -所有导向其它文档页面的链接也必须有语言目录名前缀,若还指向了页面指定位置(即特定的标题),必须使用标题的英文ID,如: - -```markdown -[建立你的环境](zh-cn/newbs-getting-started.md#set-up-your-environment) - -## 建立你的环境 :id=set-up-your-environment -``` - -在翻译后,以下文件也需要进行修改: - -* [`docs/_langs.md`](https://github.com/qmk/qmk_firmware/blob/master/docs/_langs.md) - 中的每一行应包含该语言国家国旗的[GitHub emoji编码](https://github.com/ikatyang/emoji-cheat-sheet/blob/master/README.md#country-flag)标志: - - ```markdown - - [:cn: 中文](/zh-cn/) - ``` - -* [`docs/index.html`](https://github.com/qmk/qmk_firmware/blob/master/docs/index.html) - `placeholder` 及 `noData` 对象应有一个指向对应语言的入口项: - - ```js - '/zh-cn/': '没有结果!', - ``` - - 用于 "QMK固件" 边栏标题链接的 `nameLink` 同样需要添加对应配置: - - ```js - '/zh-cn/': '/#/zh-cn/', - ``` - - 最后确保在 `fallbackLanguages` 列表中添加该语言项,这样未翻译的文档链接将回退到英文版,而不是出现404页面: - - ```js - fallbackLanguages: [ - // ... - 'zh-cn', - // ... - ], - ``` - -## 预览你的翻译成果 - -请阅读[文档预览](zh-cn/contributing.md#previewing-the-documentation)来设置文档的本地预览 - 在页面右上角的 "Translations" 菜单中应当可以看到你翻译的语言的入口。 - -当你觉得一切就绪了,请发起pull request给我们吧! diff --git a/docs/zh-cn/zh_cn_doc_status.sh b/docs/zh-cn/zh_cn_doc_status.sh deleted file mode 100644 index 84693e54618a..000000000000 --- a/docs/zh-cn/zh_cn_doc_status.sh +++ /dev/null @@ -1,35 +0,0 @@ -#! /bin/sh -# -# Script to display Simplified Chinese translation status of documents -# Copied from the japanese one -# -if [ ! -d docs/zh-cn ]; then - echo "'docs/zh-cn' not found." - echo "do:" - echo " cd \$(QMK_TOP)" - echo " ./docs/zh-cn/zh-cn_doc_status.sh" - exit 1 -fi - -en_docs=`cd docs;ls -1 [a-z]*.md` -zh_cn_docs=`cd docs/zh-cn;ls -1 [a-z]*.md` -en_count=`echo $en_docs | wc -w` -zh_cn_count=`echo $zh_cn_docs | wc -w` -echo "English documents $en_count files." -echo "Simplified Chinese documents $zh_cn_count files." - -echo "Files that have not been translated yet:" -for docfile in $en_docs -do - if [ ! -f docs/zh-cn/$docfile ]; then - wc docs/$docfile - fi -done | sort -echo "Files that have not been updated yet:" -grep --no-filename "^[ ]*git diff" docs/zh-cn/*.md | while read cmd -do - cline=`echo $cmd | sh | wc -l` - if [ $cline -gt 0 ]; then - echo "$cline $cmd" - fi -done | sort diff --git a/keyboards/a_dux/keymaps/daliusd/keymap.c b/keyboards/a_dux/keymaps/daliusd/keymap.c index 7dec77b01e45..dcc41a36ee2c 100644 --- a/keyboards/a_dux/keymaps/daliusd/keymap.c +++ b/keyboards/a_dux/keymaps/daliusd/keymap.c @@ -126,28 +126,28 @@ const uint32_t unicode_map[] PROGMEM = { [LT_CB] = 0x201c, // “ }; -#define K_SNEK X(SNEK) -#define K_EURO X(EURO) -#define K_LT_A XP(LT_S_A, LT_L_A) -#define K_LT_AU X(LT_L_A) -#define K_LT_C XP(LT_S_C, LT_L_C) -#define K_LT_CU X(LT_L_C) -#define K_LT_E1 XP(LT_S_E1, LT_L_E1) -#define K_LT_E1U X(LT_L_E1) -#define K_LT_E2 XP(LT_S_E2, LT_L_E2) -#define K_LT_E2U X(LT_L_E2) -#define K_LT_I XP(LT_S_I, LT_L_I) -#define K_LT_IU X(LT_L_I) -#define K_LT_S XP(LT_S_S, LT_L_S) -#define K_LT_SU X(LT_L_S) -#define K_LT_U1 XP(LT_S_U1, LT_L_U1) -#define K_LT_U1U X(LT_L_U1) -#define K_LT_U2 XP(LT_S_U2, LT_L_U2) -#define K_LT_U2U X(LT_L_U2) -#define K_LT_Z XP(LT_S_Z, LT_L_Z) -#define K_LT_ZU X(LT_L_Z) -#define K_LT_OB X(LT_OB) -#define K_LT_CB X(LT_CB) +#define K_SNEK UM(SNEK) +#define K_EURO UM(EURO) +#define K_LT_A UP(LT_S_A, LT_L_A) +#define K_LT_AU UM(LT_L_A) +#define K_LT_C UP(LT_S_C, LT_L_C) +#define K_LT_CU UM(LT_L_C) +#define K_LT_E1 UP(LT_S_E1, LT_L_E1) +#define K_LT_E1U UM(LT_L_E1) +#define K_LT_E2 UP(LT_S_E2, LT_L_E2) +#define K_LT_E2U UM(LT_L_E2) +#define K_LT_I UP(LT_S_I, LT_L_I) +#define K_LT_IU UM(LT_L_I) +#define K_LT_S UP(LT_S_S, LT_L_S) +#define K_LT_SU UM(LT_L_S) +#define K_LT_U1 UP(LT_S_U1, LT_L_U1) +#define K_LT_U1U UM(LT_L_U1) +#define K_LT_U2 UP(LT_S_U2, LT_L_U2) +#define K_LT_U2U UM(LT_L_U2) +#define K_LT_Z UP(LT_S_Z, LT_L_Z) +#define K_LT_ZU UM(LT_L_Z) +#define K_LT_OB UM(LT_OB) +#define K_LT_CB UM(LT_CB) const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { diff --git a/keyboards/abacus/keymaps/unicodemap/keymap.c b/keyboards/abacus/keymaps/unicodemap/keymap.c index 0e6ab0d6479b..46e2219f0bd1 100644 --- a/keyboards/abacus/keymaps/unicodemap/keymap.c +++ b/keyboards/abacus/keymaps/unicodemap/keymap.c @@ -76,7 +76,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_LOWER] = LAYOUT( NICKURL, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, _______, _______, KC_F11, KC_F12, RGB_MODE_PLAIN, RGB_MODE_BREATHE, RGB_MODE_RAINBOW, RGB_MODE_SWIRL, RGB_MODE_SNAKE, RGB_MODE_KNIGHT, RGB_MODE_GRADIENT, XXXXXXX, RGB_TOG, - _______, X(LOVEEYES), X(THINK), X(UPSIDEDOWN), X(NOMOUTH), X(PARTY), X(PEACH), X(HEART), X(EGGPLANT), X(EMOJI100), X(EMOJIB), RGB_HUI, + _______, UM(LOVEEYES), UM(THINK), UM(UPSIDEDOWN), UM(NOMOUTH), UM(PARTY), UM(PEACH), UM(HEART), UM(EGGPLANT), UM(EMOJI100), UM(EMOJIB), RGB_HUI, KC_CAPS, _______, _______, _______, _______, _______, _______, _______, _______ ) diff --git a/keyboards/aleblazer/zodiark/config.h b/keyboards/aleblazer/zodiark/config.h index 900836e4a80c..05e593fa260c 100644 --- a/keyboards/aleblazer/zodiark/config.h +++ b/keyboards/aleblazer/zodiark/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE #define RGBLED_NUM 68 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 34, 34 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/aleblazer/zodiark/info.json b/keyboards/aleblazer/zodiark/info.json index 0052d39844ee..46d697750655 100644 --- a/keyboards/aleblazer/zodiark/info.json +++ b/keyboards/aleblazer/zodiark/info.json @@ -12,7 +12,8 @@ "pin": "B5" }, "rgblight": { - "max_brightness": 170 + "max_brightness": 170, + "split_count": [34, 34] }, "rgb_matrix": { "driver": "WS2812" diff --git a/keyboards/andean_condor/info.json b/keyboards/andean_condor/info.json new file mode 100644 index 000000000000..cfc3eefa8773 --- /dev/null +++ b/keyboards/andean_condor/info.json @@ -0,0 +1,89 @@ +{ + "manufacturer": "Guido Bartolucci", + "keyboard_name": "andean_condor", + "maintainer": "guidoism", + "bootloader": "rp2040", + "diode_direction": "COL2ROW", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + "cols": ["GP9", "GP8", "GP7", "GP5", "GP4", "GP3"], + "rows": ["GP2", "GP6", "GP10", "GP15", "GP22", "GP21", "GP20", "GP16"] + }, + "processor": "RP2040", + "url": "https://github.com/guidoism/andean-condor/tree/pico-w", + "usb": { + "device_version": "1.0.0", + "pid": "0x0000", + "vid": "0xFEED" + }, + "layouts": { + "LAYOUT": { + "layout": [ + {"matrix": [0,0], "x":0, "y":0, "label":"TAB"}, + {"matrix": [0,1], "x":1, "y":0, "label":"Q"}, + {"matrix": [0,2], "x":2, "y":0, "label":"W"}, + {"matrix": [0,3], "x":3, "y":0, "label":"E"}, + {"matrix": [0,4], "x":4, "y":0, "label":"R"}, + {"matrix": [0,5], "x":5, "y":0, "label":"T"}, + + {"matrix": [4,5], "x":10, "y":0, "label":"Y"}, + {"matrix": [4,4], "x":11, "y":0, "label":"U"}, + {"matrix": [4,3], "x":12, "y":0, "label":"I"}, + {"matrix": [4,2], "x":13, "y":0, "label":"O"}, + {"matrix": [4,1], "x":14, "y":0, "label":"P"}, + {"matrix": [4,0], "x":15, "y":0, "label":"BS"}, + + {"matrix": [1,0], "x":0, "y":1, "label":"CTRL"}, + {"matrix": [1,1], "x":1, "y":1, "label":"A"}, + {"matrix": [1,2], "x":2, "y":1, "label":"S"}, + {"matrix": [1,3], "x":3, "y":1, "label":"D"}, + {"matrix": [1,4], "x":4, "y":1, "label":"F"}, + {"matrix": [1,5], "x":5, "y":1, "label":"G"}, + + {"matrix": [5,5], "x":10, "y":1, "label":"H"}, + {"matrix": [5,4], "x":11, "y":1, "label":"J"}, + {"matrix": [5,3], "x":12, "y":1, "label":"K"}, + {"matrix": [5,2], "x":13, "y":1, "label":"L"}, + {"matrix": [5,1], "x":14, "y":1, "label":":"}, + {"matrix": [5,0], "x":15, "y":1, "label":"RET"}, + + {"matrix": [2,0], "x":0, "y":2, "label":"SHIFT"}, + {"matrix": [2,1], "x":1, "y":2, "label":"Z"}, + {"matrix": [2,2], "x":2, "y":2, "label":"X"}, + {"matrix": [2,3], "x":3, "y":2, "label":"C"}, + {"matrix": [2,4], "x":4, "y":2, "label":"V"}, + {"matrix": [2,5], "x":5, "y":2, "label":"B"}, + + {"matrix": [6,5], "x":10, "y":2, "label":"N"}, + {"matrix": [6,4], "x":11, "y":2, "label":"M"}, + {"matrix": [6,3], "x":12, "y":2, "label":","}, + {"matrix": [6,2], "x":13, "y":2, "label":"."}, + {"matrix": [6,1], "x":14, "y":2, "label":"/"}, + {"matrix": [6,0], "x":15, "y":2, "label":";"}, + + {"matrix": [3,4], "x":6.5, "y":3, "label":"lt2"}, + {"matrix": [3,5], "x":5.5, "y":3, "label":"lt1"}, + + {"matrix": [7,5], "x":9.5, "y":3, "label":"rt2"}, + {"matrix": [7,4], "x":8.5, "y":3, "label":"rt1"}, + + {"matrix": [3,0], "x":3.5, "y":4, "label":"lb1"}, + {"matrix": [3,1], "x":4.5, "y":4, "label":"lb2"}, + {"matrix": [3,2], "x":5.5, "y":4, "label":"lb3"}, + {"matrix": [3,3], "x":6.5, "y":4, "label":"lb4"}, + + {"matrix": [7,3], "x":8.5, "y":4, "label":"rb3"}, + {"matrix": [7,2], "x":9.5, "y":4, "label":"rb4"}, + {"matrix": [7,1], "x":10.5, "y":4, "label":"rb5"}, + {"matrix": [7,0], "x":11.5, "y":4, "label":"rb6"} + ] + } + } +} diff --git a/keyboards/andean_condor/keymaps/default/keymap.c b/keyboards/andean_condor/keymaps/default/keymap.c new file mode 100644 index 000000000000..4d00610897f7 --- /dev/null +++ b/keyboards/andean_condor/keymaps/default/keymap.c @@ -0,0 +1,14 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_BACKSPACE, + KC_LCTL, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SEMICOLON, KC_ENTER, + KC_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, KC_SLASH, LSFT(KC_SEMICOLON), + KC_5, KC_6, KC_7, KC_8, + KC_1, KC_2, KC_3, KC_4, KC_9, KC_0, KC_MINUS, KC_EQUAL + ) +}; diff --git a/keyboards/andean_condor/readme.md b/keyboards/andean_condor/readme.md new file mode 100644 index 000000000000..8e961e3cb038 --- /dev/null +++ b/keyboards/andean_condor/readme.md @@ -0,0 +1,33 @@ +# Andean Condor (andean_condor) + +![Pic](https://i.imgur.com/woaDob6.jpg) + +The Andean Condor is a monoblock split keyboard in the spirit of the Kyria. + +* Keyboard Maintainer: [Guido Bartolucci](https://github.com/guidoism) +* Hardware Supported: Raspberry Pi Pico (only QMK), Nice!Nano (only ZMK) +* Hardware Availability: [Pico PCB](https://github.com/guidoism/andean-condor/tree/pico-w), [Nice!Nano PCB](https://github.com/guidoism/andean-condor) + +Make example for this keyboard (after setting up your build environment): + + make andean_condor:default + +or + + qmk compile -kb andean_condor -km default + +Flashing example for this keyboard: + + make andean_condor: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 +&g + diff --git a/keyboards/andean_condor/rules.mk b/keyboards/andean_condor/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/andean_condor/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/arabica37/rev1/config.h b/keyboards/arabica37/rev1/config.h index 07d567be6540..b2cbbade075c 100644 --- a/keyboards/arabica37/rev1/config.h +++ b/keyboards/arabica37/rev1/config.h @@ -19,7 +19,6 @@ along with this program. If not, see . #pragma once #define RGBLED_NUM 50 // Number of LEDs -#define RGBLED_SPLIT {25, 25} /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboards/arabica37/rev1/info.json b/keyboards/arabica37/rev1/info.json index a543a83fd9ad..ed04e5eb1416 100644 --- a/keyboards/arabica37/rev1/info.json +++ b/keyboards/arabica37/rev1/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [25, 25] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/atreus/keymaps/ridingqwerty/keymap.c b/keyboards/atreus/keymaps/ridingqwerty/keymap.c index 1eeb17fd1751..9b0826402ec8 100644 --- a/keyboards/atreus/keymaps/ridingqwerty/keymap.c +++ b/keyboards/atreus/keymaps/ridingqwerty/keymap.c @@ -46,7 +46,7 @@ { K75, K74, K73, K72, K71, K70 } \ } -//#define ALPHA XP(UCM_LDEL, UCM_UDEL) +//#define ALPHA UP(UCM_LDEL, UCM_UDEL) const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_QWERTY] = LAYOUT_atreus_wrapper( /* Qwerty */ diff --git a/keyboards/avalanche/v2/config.h b/keyboards/avalanche/v2/config.h index 5d7c1c2047bc..e460f21459b2 100644 --- a/keyboards/avalanche/v2/config.h +++ b/keyboards/avalanche/v2/config.h @@ -4,5 +4,4 @@ #pragma once #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_SPLIT diff --git a/keyboards/avalanche/v2/info.json b/keyboards/avalanche/v2/info.json index 92f02721de41..c96839ee3947 100644 --- a/keyboards/avalanche/v2/info.json +++ b/keyboards/avalanche/v2/info.json @@ -18,6 +18,9 @@ {"pin_a": "B5", "pin_b": "F4", "resolution": 2} ] }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/avalanche/v3/config.h b/keyboards/avalanche/v3/config.h index c6042255e3d4..e460f21459b2 100644 --- a/keyboards/avalanche/v3/config.h +++ b/keyboards/avalanche/v3/config.h @@ -4,5 +4,4 @@ #pragma once #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 7, 7 } #define RGBLIGHT_SPLIT diff --git a/keyboards/avalanche/v3/info.json b/keyboards/avalanche/v3/info.json index ed507485f5d1..4c8a8e4f8910 100644 --- a/keyboards/avalanche/v3/info.json +++ b/keyboards/avalanche/v3/info.json @@ -21,6 +21,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [7, 7] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/avalanche/v4/config.h b/keyboards/avalanche/v4/config.h index 51b7cb7537fb..d60748d9bcdd 100644 --- a/keyboards/avalanche/v4/config.h +++ b/keyboards/avalanche/v4/config.h @@ -5,7 +5,6 @@ #ifdef RGBLIGHT_ENABLE # define RGBLED_NUM 64 -# define RGBLED_SPLIT { 32, 32 } # define RGBLIGHT_SPLIT # define RGBLIGHT_HUE_STEP 10 # define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/avalanche/v4/info.json b/keyboards/avalanche/v4/info.json index 235bb122201e..399ebb82a344 100644 --- a/keyboards/avalanche/v4/info.json +++ b/keyboards/avalanche/v4/info.json @@ -25,7 +25,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [32, 32] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/basekeys/slice/rev1_rgb/config.h b/keyboards/basekeys/slice/rev1_rgb/config.h index 996e538ae3b3..c2b975620181 100644 --- a/keyboards/basekeys/slice/rev1_rgb/config.h +++ b/keyboards/basekeys/slice/rev1_rgb/config.h @@ -29,7 +29,6 @@ along with this program. If not, see . /* RGB LED */ #ifdef RGBLIGHT_ENABLE #define RGBLED_NUM 69 // Number of LEDs. backlight x69 -#define RGBLED_SPLIT { 34, 35 } #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 diff --git a/keyboards/basekeys/slice/rev1_rgb/info.json b/keyboards/basekeys/slice/rev1_rgb/info.json index 38a6e8398a9b..94fff43071d0 100644 --- a/keyboards/basekeys/slice/rev1_rgb/info.json +++ b/keyboards/basekeys/slice/rev1_rgb/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [34, 35] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/bastardkb/dilemma/3x5_3/config.h b/keyboards/bastardkb/dilemma/3x5_3/config.h index c5fa0dc192b1..16f48788c1e2 100644 --- a/keyboards/bastardkb/dilemma/3x5_3/config.h +++ b/keyboards/bastardkb/dilemma/3x5_3/config.h @@ -43,14 +43,12 @@ /* RGB settings. */ #define RGBLED_NUM 36 -#define RGBLED_SPLIT \ - { 18, 18 } /* RGB matrix support. */ #ifdef RGB_MATRIX_ENABLE # define SPLIT_TRANSPORT_MIRROR # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 18, 18 } # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 50 # define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS # define RGB_DISABLE_WHEN_USB_SUSPENDED diff --git a/keyboards/bastardkb/dilemma/3x5_3/info.json b/keyboards/bastardkb/dilemma/3x5_3/info.json index 57ea2c16dff2..2ee5d5ea4aaa 100644 --- a/keyboards/bastardkb/dilemma/3x5_3/info.json +++ b/keyboards/bastardkb/dilemma/3x5_3/info.json @@ -15,6 +15,9 @@ "split": { "soft_serial_pin": "GP1" }, + "rgblight": { + "split_count": [18, 18] + }, "ws2812": { "pin": "GP0", "driver": "vendor" diff --git a/keyboards/bastardkb/scylla/config.h b/keyboards/bastardkb/scylla/config.h index 0ad3ecd17bcc..7270ee253a82 100644 --- a/keyboards/bastardkb/scylla/config.h +++ b/keyboards/bastardkb/scylla/config.h @@ -20,14 +20,12 @@ /* RGB settings. */ #define RGBLED_NUM 58 -#define RGBLED_SPLIT \ - { 29, 29 } /* RGB matrix support. */ #ifdef RGB_MATRIX_ENABLE # define SPLIT_TRANSPORT_MIRROR # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 29, 29 } # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 50 # define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS # define RGB_DISABLE_WHEN_USB_SUSPENDED diff --git a/keyboards/bastardkb/scylla/info.json b/keyboards/bastardkb/scylla/info.json index 682b2dc6dbda..95f1de9ff189 100644 --- a/keyboards/bastardkb/scylla/info.json +++ b/keyboards/bastardkb/scylla/info.json @@ -3,6 +3,9 @@ "usb": { "pid": "0x1829" }, + "rgblight": { + "split_count": [29, 29] + }, "layouts": { "LAYOUT_split_4x6_5": { "layout": [ diff --git a/keyboards/bastardkb/skeletyl/config.h b/keyboards/bastardkb/skeletyl/config.h index 3e282f0f15ee..76e75a04e6a1 100644 --- a/keyboards/bastardkb/skeletyl/config.h +++ b/keyboards/bastardkb/skeletyl/config.h @@ -20,14 +20,12 @@ /* RGB settings. */ #define RGBLED_NUM 36 -#define RGBLED_SPLIT \ - { 18, 18 } /* RGB matrix support. */ #ifdef RGB_MATRIX_ENABLE # define SPLIT_TRANSPORT_MIRROR # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 18, 18 } # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 50 # define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS # define RGB_DISABLE_WHEN_USB_SUSPENDED diff --git a/keyboards/bastardkb/skeletyl/info.json b/keyboards/bastardkb/skeletyl/info.json index b325ca719686..4373d641098f 100644 --- a/keyboards/bastardkb/skeletyl/info.json +++ b/keyboards/bastardkb/skeletyl/info.json @@ -3,6 +3,9 @@ "usb": { "pid": "0x1830" }, + "rgblight": { + "split_count": [18, 18] + }, "community_layouts": ["split_3x5_3"], "layouts": { "LAYOUT_split_3x5_3": { diff --git a/keyboards/bastardkb/tbk/config.h b/keyboards/bastardkb/tbk/config.h index 40a9b2cbeb84..c5dd67e1053e 100644 --- a/keyboards/bastardkb/tbk/config.h +++ b/keyboards/bastardkb/tbk/config.h @@ -18,7 +18,6 @@ #pragma once #define RGBLED_NUM 38 -#define RGBLED_SPLIT { 19, 19 } #define RGBLIGHT_SPLIT #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/bastardkb/tbk/info.json b/keyboards/bastardkb/tbk/info.json index 7da2d56ad538..2256365a7651 100644 --- a/keyboards/bastardkb/tbk/info.json +++ b/keyboards/bastardkb/tbk/info.json @@ -5,6 +5,9 @@ "device_version": "0.0.1", "pid": "0x1828" }, + "rgblight": { + "split_count": [19, 19] + }, "ws2812": { "pin": "D2" }, diff --git a/keyboards/bastardkb/tbkmini/config.h b/keyboards/bastardkb/tbkmini/config.h index 06c6e3ada400..8774c0bbdeaf 100644 --- a/keyboards/bastardkb/tbkmini/config.h +++ b/keyboards/bastardkb/tbkmini/config.h @@ -20,14 +20,12 @@ /* RGB settings. */ #define RGBLED_NUM 42 -#define RGBLED_SPLIT \ - { 21, 21 } /* RGB matrix support. */ #ifdef RGB_MATRIX_ENABLE # define SPLIT_TRANSPORT_MIRROR # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 21, 21 } # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 50 # define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS # define RGB_DISABLE_WHEN_USB_SUSPENDED diff --git a/keyboards/bastardkb/tbkmini/info.json b/keyboards/bastardkb/tbkmini/info.json index 94c357cd3b56..518cfbf801f9 100644 --- a/keyboards/bastardkb/tbkmini/info.json +++ b/keyboards/bastardkb/tbkmini/info.json @@ -3,6 +3,9 @@ "usb": { "pid": "0x1828" }, + "rgblight": { + "split_count": [21, 21] + }, "community_layouts": ["split_3x6_3"], "layouts": { "LAYOUT_split_3x6_3": { diff --git a/keyboards/bioi/g60/matrix_diagram.md b/keyboards/bioi/g60/matrix_diagram.md index 5f7af98daf55..8ac1d9b0d3fe 100644 --- a/keyboards/bioi/g60/matrix_diagram.md +++ b/keyboards/bioi/g60/matrix_diagram.md @@ -12,9 +12,9 @@ ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┤ └──────┴───┴───┘ │40 │41 │42 │45 │4A │4B │48 │4C │4D │ └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┘ -┌────────┐ -│30 │ 2.25u LShift -└────────┘ +┌────────┐ ┌─────────────┐ +│30 │ 2.25u LShift │3D │ 2.75u RShift +└────────┘ └─────────────┘ ┌────┬────┬────┬────────────────────────┬────┬────┬────┬────┐ │40 │41 │42 │45 │4A │4B │4C │4D │ Standard └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ diff --git a/keyboards/bioi/g60ble/config.h b/keyboards/bioi/g60ble/config.h index d58c58713c6b..24ced1fc0a21 100644 --- a/keyboards/bioi/g60ble/config.h +++ b/keyboards/bioi/g60ble/config.h @@ -1,11 +1,6 @@ #pragma once -/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ -#define LOCKING_SUPPORT_ENABLE - -/* Locking resynchronize hack */ -#define LOCKING_RESYNC_ENABLE - +/* RGB Underglow */ #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL @@ -21,5 +16,11 @@ #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 +/* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ +#define LOCKING_SUPPORT_ENABLE +/* Locking resynchronize hack */ +#define LOCKING_RESYNC_ENABLE + +/* key combination for magic key command */ #define KEYBOARD_LOCK_ENABLE #define MAGIC_KEY_LOCK L diff --git a/keyboards/bioi/g60ble/keymaps/chemicalwill/keymap.c b/keyboards/bioi/g60ble/keymaps/chemicalwill/keymap.c new file mode 100644 index 000000000000..680c96879573 --- /dev/null +++ b/keyboards/bioi/g60ble/keymaps/chemicalwill/keymap.c @@ -0,0 +1,206 @@ +/* Copyright 2023 Will Hedges (@will-hedges) + * + * 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 . + */ + +#include QMK_KEYBOARD_H + +enum layers { + _WORK, + _QWER, + _FN1 +}; + +enum custom_keycodes { + BASE_QWER = SAFE_RANGE, + BASE_WORK +}; + +// Tap Dance enum +enum { + N8_F8, + N9_F9, + N0_F10, + MINS_F11, + EQL_F12, + DEL_BSLS, + G_END, + H_HOME, + LALT_PGUP, + RALT_PGDN +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + + [_WORK] = LAYOUT_60_ansi( + QK_GESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, TD(N8_F8), TD(N9_F9), TD(N0_F10), TD(MINS_F11), TD(EQL_F12), KC_BSPC, + 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, TD(DEL_BSLS), + LT(_FN1, KC_CAPS), KC_A, KC_S, KC_D, KC_F, TD(G_END), TD(H_HOME), KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_ENT, + 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_LCTL, KC_LGUI, LALT_T(KC_PGUP), KC_SPC, RALT_T(KC_PGDN), KC_APP, MO(_FN1), KC_RCTL + ), + + [_QWER] = LAYOUT_60_ansi( + QK_GESC, 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_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, TD(DEL_BSLS), + LT(_FN1, 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_LSFT, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_APP, MO(_FN1), KC_RCTL + ), + + [_FN1] = LAYOUT_60_ansi( + _______, 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_PGUP, _______, QK_RBT, _______, _______, _______, KC_UP, _______, _______, _______, _______, _______, + _______, KC_HOME, KC_PGDN, KC_END, _______, _______, _______, KC_LEFT, KC_DOWN, KC_RGHT, _______, _______, _______, + _______, _______, _______, _______, _______, QK_BOOT, _______, _______, _______, _______, _______, _______, + _______, C(A(KC_DEL)), _______, _______, _______, BASE_WORK, _______, BASE_QWER + ) + +}; + + +// Tap Dance tap vs. hold docs @ https://docs.qmk.fm/#/feature_tap_dance?id=example-3 +// Macros are also used with process_record_user @ https://docs.qmk.fm/#/feature_macros?id=using-macros-in-c-keymaps +typedef struct { + uint16_t tap; + uint16_t hold; + uint16_t held; +} tap_dance_tap_hold_t; + +bool process_record_user(uint16_t keycode, keyrecord_t *record) { + tap_dance_action_t *action; + + switch (keycode) { + // MACROS + case BASE_QWER: + if (record->event.pressed) { + set_single_persistent_default_layer(_QWER); + } + break; + + case BASE_WORK: + if (record->event.pressed) { + set_single_persistent_default_layer(_WORK); + } + break; + + // TAP DANCES + case TD(N8_F8): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(N9_F9): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(N0_F10): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(MINS_F11): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(EQL_F12): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(DEL_BSLS): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(G_END): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + case TD(H_HOME): + action = &tap_dance_actions[TD_INDEX(keycode)]; + if (!record->event.pressed && action->state.count && !action->state.finished) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)action->user_data; + tap_code16(tap_hold->tap); + } + break; + + } + return true; +} + +void tap_dance_tap_hold_finished(tap_dance_state_t *state, void *user_data) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data; + + if (state->pressed) { + if (state->count == 1 +#ifndef PERMISSIVE_HOLD + && !state->interrupted +#endif + ) { + register_code16(tap_hold->hold); + tap_hold->held = tap_hold->hold; + } else { + register_code16(tap_hold->tap); + tap_hold->held = tap_hold->tap; + } + } +} + +void tap_dance_tap_hold_reset(tap_dance_state_t *state, void *user_data) { + tap_dance_tap_hold_t *tap_hold = (tap_dance_tap_hold_t *)user_data; + + if (tap_hold->held) { + unregister_code16(tap_hold->held); + tap_hold->held = 0; + } +} + +#define ACTION_TAP_DANCE_TAP_HOLD(tap, hold) \ + { .fn = {NULL, tap_dance_tap_hold_finished, tap_dance_tap_hold_reset}, .user_data = (void *)&((tap_dance_tap_hold_t){tap, hold, 0}), } + +tap_dance_action_t tap_dance_actions[] = { + [N8_F8] = ACTION_TAP_DANCE_TAP_HOLD(KC_8, KC_F8), + [N9_F9] = ACTION_TAP_DANCE_TAP_HOLD(KC_9, KC_F9), + [N0_F10] = ACTION_TAP_DANCE_TAP_HOLD(KC_0, KC_F10), + [MINS_F11] = ACTION_TAP_DANCE_TAP_HOLD(KC_MINS, KC_F11), + [EQL_F12] = ACTION_TAP_DANCE_TAP_HOLD(KC_EQL, KC_F12), + [DEL_BSLS] = ACTION_TAP_DANCE_TAP_HOLD(KC_DEL, KC_BSLS), + [G_END] = ACTION_TAP_DANCE_TAP_HOLD(KC_G, KC_END), + [H_HOME] = ACTION_TAP_DANCE_TAP_HOLD(KC_H, KC_HOME) +}; diff --git a/keyboards/bioi/g60ble/keymaps/chemicalwill/rules.mk b/keyboards/bioi/g60ble/keymaps/chemicalwill/rules.mk new file mode 100644 index 000000000000..c86c7b33406d --- /dev/null +++ b/keyboards/bioi/g60ble/keymaps/chemicalwill/rules.mk @@ -0,0 +1,7 @@ +# features enabled by default that I want to turn off +BACKLIGHT_ENABLE = no +MOUSEKEY_ENABLE = no +RGBLIGHT_ENABLE = no + +# features I want to add +TAP_DANCE_ENABLE = yes diff --git a/keyboards/bioi/g60ble/matrix_diagram.md b/keyboards/bioi/g60ble/matrix_diagram.md new file mode 100644 index 000000000000..b7cfaa768698 --- /dev/null +++ b/keyboards/bioi/g60ble/matrix_diagram.md @@ -0,0 +1,24 @@ +# Matrix Diagram for Basic IO Instruments G60BLE + +``` +┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ ┌───────┐ +│00 │01 │02 │03 │04 │05 │06 │07 │08 │09 │0A │0B │0C │0D │49 │ │0D │ 2u Backspace +├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ └─┬─────┤ +│10 │11 │12 │13 │14 │15 │16 │17 │18 │19 │1A │1B │1C │1D │ │ │ +├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ ┌──┴┐2D │ ISO Enter +│20 │21 │22 │23 │24 │25 │26 │27 │28 │29 │2A │2B │2D │ │2C │ │ +├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────┬───┤ ┌─────┴┬──┴┬───┤ +│30 │31 │32 │33 │34 │35 │36 │37 │38 │39 │3A │3B │3D │3C │ │3D │47 │3C │ 1.75u/1u/1u RShift +├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬┴──┬───┼───┤ └──────┴───┴───┘ +│40 │41 │42 │45 │4A │4B │48 │4C │4D │ +└────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┘ +┌────────┐ ┌─────────────┐ +│30 │ 2.25u LShift │3D │ 2.75u RShift +└────────┘ └─────────────┘ +┌────┬────┬────┬────────────────────────┬────┬────┬────┬────┐ +│40 │41 │42 │45 │4A │4B │4C │4D │ Standard +└────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ +┌─────┬───┬─────┬───────────────────────────┬─────┬───┬─────┐ +│40 │41 │42 │45 │4B │4C │4D │ Tsangan/WKL/HHKB +└─────┴───┴─────┴───────────────────────────┴─────┴───┴─────┘ +``` diff --git a/keyboards/bioi/g60ble/rules.mk b/keyboards/bioi/g60ble/rules.mk index e3420b4a28a0..d1edb6882dac 100644 --- a/keyboards/bioi/g60ble/rules.mk +++ b/keyboards/bioi/g60ble/rules.mk @@ -4,12 +4,18 @@ F_CPU = 8000000 # Build Options # change yes to no to disable # -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite +BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite MOUSEKEY_ENABLE = yes # Mouse keys EXTRAKEY_ENABLE = yes # Audio control and System control CONSOLE_ENABLE = no # Console for debug COMMAND_ENABLE = yes # Commands for debug and configuration -NKRO_ENABLE = yes # Enable N-Key Rollover BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality RGBLIGHT_ENABLE = yes LTO_ENABLE = yes + +# these lines are all for bluetooth +BLUETOOTH_ENABLE = yes +BLUETOOTH_DRIVER = custom +SRC += usart.c ble.c +OPT_DEFS += -DUART_RX1_BUFFER_SIZE=16 -DUART_TX1_BUFFER_SIZE=16 +OPT_DEFS += -DUSART1_ENABLED diff --git a/keyboards/bluebell/swoop/config.h b/keyboards/bluebell/swoop/config.h index c34ab85ecfd6..a502e8b62bbb 100644 --- a/keyboards/bluebell/swoop/config.h +++ b/keyboards/bluebell/swoop/config.h @@ -29,8 +29,6 @@ #define RGBLIGHT_EFFECT_STATIC_GRADIENT #define RGBLIGHT_EFFECT_BREATHING #define RGBLED_NUM 36 - #define RGBLED_SPLIT \ - { 18, 18 } #define RGBLIGHT_SPLIT #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 diff --git a/keyboards/bluebell/swoop/info.json b/keyboards/bluebell/swoop/info.json index e319754f7854..1f32562f679c 100644 --- a/keyboards/bluebell/swoop/info.json +++ b/keyboards/bluebell/swoop/info.json @@ -12,7 +12,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 150 + "max_brightness": 150, + "split_count": [18, 18] }, "matrix_pins": { "cols": ["B1", "F7", "F6", "F5", "F4"], diff --git a/keyboards/cablecardesigns/phoenix/info.json b/keyboards/cablecardesigns/phoenix/info.json new file mode 100755 index 000000000000..effa8836b9b8 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/info.json @@ -0,0 +1,497 @@ +{ + "keyboard_name": "Phoenix", + "manufacturer": "Yiancar-Designs", + "maintainer": "Yiancar-Designs", + "url": "https://yiancar-designs.com", + "processor": "STM32F072", + "bootloader": "stm32-dfu", + "diode_direction": "COL2ROW", + "matrix_pins": { + "cols": ["A1", "B9", "A3", "A4", "A5", "A6", "A7", "B0", "B1", "B2", "B10", "B11", "B12", "B13", "B14", "B15", "A8"], + "rows": ["A2", "A14", "A15", "B3", "B4", "B5"] + }, + "usb": { + "vid": "0x8968", + "pid": "0x5048", + "device_version": "0.0.1" + }, + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "indicators": { + "caps_lock": "B6", + "on_state": 0 + }, + "community_layouts": ["tkl_f13_ansi_tsangan", "tkl_f13_ansi_tsangan_split_bs_rshift", "tkl_f13_iso_tsangan", "tkl_f13_iso_tsangan_split_bs_rshift"], + "layouts": { + "LAYOUT_all": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1.25, "y": 0 }, + { "matrix": [0, 2], "x": 2.25, "y": 0 }, + { "matrix": [0, 3], "x": 3.25, "y": 0 }, + { "matrix": [0, 4], "x": 4.25, "y": 0 }, + { "matrix": [0, 5], "x": 5.5, "y": 0 }, + { "matrix": [0, 6], "x": 6.5, "y": 0 }, + { "matrix": [0, 7], "x": 7.5, "y": 0 }, + { "matrix": [0, 8], "x": 8.5, "y": 0 }, + { "matrix": [0, 9], "x": 9.75, "y": 0 }, + { "matrix": [0, 10], "x": 10.75, "y": 0 }, + { "matrix": [0, 11], "x": 11.75, "y": 0 }, + { "matrix": [0, 12], "x": 12.75, "y": 0 }, + { "matrix": [0, 13], "x": 14, "y": 0 }, + { "matrix": [0, 14], "x": 15.25, "y": 0 }, + { "matrix": [0, 15], "x": 16.25, "y": 0 }, + { "matrix": [0, 16], "x": 17.25, "y": 0 }, + { "matrix": [1, 0], "x": 0, "y": 1.25 }, + { "matrix": [1, 1], "x": 1, "y": 1.25 }, + { "matrix": [1, 2], "x": 2, "y": 1.25 }, + { "matrix": [1, 3], "x": 3, "y": 1.25 }, + { "matrix": [1, 4], "x": 4, "y": 1.25 }, + { "matrix": [1, 5], "x": 5, "y": 1.25 }, + { "matrix": [1, 6], "x": 6, "y": 1.25 }, + { "matrix": [1, 7], "x": 7, "y": 1.25 }, + { "matrix": [1, 8], "x": 8, "y": 1.25 }, + { "matrix": [1, 9], "x": 9, "y": 1.25 }, + { "matrix": [1, 10], "x": 10, "y": 1.25 }, + { "matrix": [1, 11], "x": 11, "y": 1.25 }, + { "matrix": [1, 12], "x": 12, "y": 1.25 }, + { "matrix": [1, 13], "x": 13, "y": 1.25 }, + { "matrix": [2, 13], "x": 14, "y": 1.25 }, + { "matrix": [1, 14], "x": 15.25, "y": 1.25 }, + { "matrix": [1, 15], "x": 16.25, "y": 1.25 }, + { "matrix": [1, 16], "x": 17.25, "y": 1.25 }, + { "matrix": [2, 0], "x": 0, "y": 2.25 }, + { "matrix": [2, 1], "x": 1.5, "y": 2.25 }, + { "matrix": [2, 2], "x": 2.5, "y": 2.25 }, + { "matrix": [2, 3], "x": 3.5, "y": 2.25 }, + { "matrix": [2, 4], "x": 4.5, "y": 2.25 }, + { "matrix": [2, 5], "x": 5.5, "y": 2.25 }, + { "matrix": [2, 6], "x": 6.5, "y": 2.25 }, + { "matrix": [2, 7], "x": 7.5, "y": 2.25 }, + { "matrix": [2, 8], "x": 8.5, "y": 2.25 }, + { "matrix": [2, 9], "x": 9.5, "y": 2.25 }, + { "matrix": [2, 10], "x": 10.5, "y": 2.25 }, + { "matrix": [2, 11], "x": 11.5, "y": 2.25 }, + { "matrix": [2, 12], "x": 12.5, "y": 2.25 }, + { "matrix": [3, 12], "x": 13.5, "y": 2.25 }, + { "matrix": [2, 14], "x": 15.25, "y": 2.25 }, + { "matrix": [2, 15], "x": 16.25, "y": 2.25 }, + { "matrix": [2, 16], "x": 17.25, "y": 2.25 }, + { "matrix": [3, 0], "x": 0, "y": 3.25 }, + { "matrix": [3, 1], "x": 1.75, "y": 3.25 }, + { "matrix": [3, 2], "x": 2.75, "y": 3.25 }, + { "matrix": [3, 3], "x": 3.75, "y": 3.25 }, + { "matrix": [3, 4], "x": 4.75, "y": 3.25 }, + { "matrix": [3, 5], "x": 5.75, "y": 3.25 }, + { "matrix": [3, 6], "x": 6.75, "y": 3.25 }, + { "matrix": [3, 7], "x": 7.75, "y": 3.25 }, + { "matrix": [3, 8], "x": 8.75, "y": 3.25 }, + { "matrix": [3, 9], "x": 9.75, "y": 3.25 }, + { "matrix": [3, 10], "x": 10.75, "y": 3.25 }, + { "matrix": [3, 11], "x": 11.75, "y": 3.25 }, + { "matrix": [3, 13], "x": 12.75, "y": 3.25 }, + { "matrix": [4, 0], "x": 0, "y": 4.25 }, + { "matrix": [4, 1], "x": 1.25, "y": 4.25 }, + { "matrix": [4, 2], "x": 2.25, "y": 4.25 }, + { "matrix": [4, 3], "x": 3.25, "y": 4.25 }, + { "matrix": [4, 4], "x": 4.25, "y": 4.25 }, + { "matrix": [4, 5], "x": 5.25, "y": 4.25 }, + { "matrix": [4, 6], "x": 6.25, "y": 4.25 }, + { "matrix": [4, 7], "x": 7.25, "y": 4.25 }, + { "matrix": [4, 8], "x": 8.25, "y": 4.25 }, + { "matrix": [4, 9], "x": 9.25, "y": 4.25 }, + { "matrix": [4, 10], "x": 10.25, "y": 4.25 }, + { "matrix": [4, 11], "x": 11.25, "y": 4.25 }, + { "matrix": [4, 12], "x": 12.25, "y": 4.25 }, + { "matrix": [4, 13], "x": 14, "y": 4.25 }, + { "matrix": [4, 15], "x": 16.25, "y": 4.25 }, + { "matrix": [5, 0], "x": 0, "y": 5.25 }, + { "matrix": [5, 1], "x": 1.5, "y": 5.25 }, + { "matrix": [5, 2], "x": 2.5, "y": 5.25 }, + { "matrix": [5, 6], "x": 4, "y": 5.25 }, + { "matrix": [5, 11], "x": 11, "y": 5.25 }, + { "matrix": [5, 12], "x": 12.5, "y": 5.25 }, + { "matrix": [5, 13], "x": 13.5, "y": 5.25 }, + { "matrix": [5, 14], "x": 15.25, "y": 5.25 }, + { "matrix": [5, 15], "x": 16.25, "y": 5.25 }, + { "matrix": [5, 16], "x": 17.25, "y": 5.25 } + ] + }, + "LAYOUT_tkl_f13_ansi_tsangan": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1.25, "y": 0 }, + { "matrix": [0, 2], "x": 2.25, "y": 0 }, + { "matrix": [0, 3], "x": 3.25, "y": 0 }, + { "matrix": [0, 4], "x": 4.25, "y": 0 }, + { "matrix": [0, 5], "x": 5.5, "y": 0 }, + { "matrix": [0, 6], "x": 6.5, "y": 0 }, + { "matrix": [0, 7], "x": 7.5, "y": 0 }, + { "matrix": [0, 8], "x": 8.5, "y": 0 }, + { "matrix": [0, 9], "x": 9.75, "y": 0 }, + { "matrix": [0, 10], "x": 10.75, "y": 0 }, + { "matrix": [0, 11], "x": 11.75, "y": 0 }, + { "matrix": [0, 12], "x": 12.75, "y": 0 }, + { "matrix": [0, 13], "x": 14, "y": 0 }, + { "matrix": [0, 14], "x": 15.25, "y": 0 }, + { "matrix": [0, 15], "x": 16.25, "y": 0 }, + { "matrix": [0, 16], "x": 17.25, "y": 0 }, + { "matrix": [1, 0], "x": 0, "y": 1.25 }, + { "matrix": [1, 1], "x": 1, "y": 1.25 }, + { "matrix": [1, 2], "x": 2, "y": 1.25 }, + { "matrix": [1, 3], "x": 3, "y": 1.25 }, + { "matrix": [1, 4], "x": 4, "y": 1.25 }, + { "matrix": [1, 5], "x": 5, "y": 1.25 }, + { "matrix": [1, 6], "x": 6, "y": 1.25 }, + { "matrix": [1, 7], "x": 7, "y": 1.25 }, + { "matrix": [1, 8], "x": 8, "y": 1.25 }, + { "matrix": [1, 9], "x": 9, "y": 1.25 }, + { "matrix": [1, 10], "x": 10, "y": 1.25 }, + { "matrix": [1, 11], "x": 11, "y": 1.25 }, + { "matrix": [1, 12], "x": 12, "y": 1.25 }, + { "matrix": [1, 13], "x": 13, "y": 1.25 }, + { "matrix": [1, 14], "x": 15.25, "y": 1.25 }, + { "matrix": [1, 15], "x": 16.25, "y": 1.25 }, + { "matrix": [1, 16], "x": 17.25, "y": 1.25 }, + { "matrix": [2, 0], "x": 0, "y": 2.25 }, + { "matrix": [2, 1], "x": 1.5, "y": 2.25 }, + { "matrix": [2, 2], "x": 2.5, "y": 2.25 }, + { "matrix": [2, 3], "x": 3.5, "y": 2.25 }, + { "matrix": [2, 4], "x": 4.5, "y": 2.25 }, + { "matrix": [2, 5], "x": 5.5, "y": 2.25 }, + { "matrix": [2, 6], "x": 6.5, "y": 2.25 }, + { "matrix": [2, 7], "x": 7.5, "y": 2.25 }, + { "matrix": [2, 8], "x": 8.5, "y": 2.25 }, + { "matrix": [2, 9], "x": 9.5, "y": 2.25 }, + { "matrix": [2, 10], "x": 10.5, "y": 2.25 }, + { "matrix": [2, 11], "x": 11.5, "y": 2.25 }, + { "matrix": [2, 12], "x": 12.5, "y": 2.25 }, + { "matrix": [3, 12], "x": 13.5, "y": 2.25 }, + { "matrix": [2, 14], "x": 15.25, "y": 2.25 }, + { "matrix": [2, 15], "x": 16.25, "y": 2.25 }, + { "matrix": [2, 16], "x": 17.25, "y": 2.25 }, + { "matrix": [3, 0], "x": 0, "y": 3.25 }, + { "matrix": [3, 1], "x": 1.75, "y": 3.25 }, + { "matrix": [3, 2], "x": 2.75, "y": 3.25 }, + { "matrix": [3, 3], "x": 3.75, "y": 3.25 }, + { "matrix": [3, 4], "x": 4.75, "y": 3.25 }, + { "matrix": [3, 5], "x": 5.75, "y": 3.25 }, + { "matrix": [3, 6], "x": 6.75, "y": 3.25 }, + { "matrix": [3, 7], "x": 7.75, "y": 3.25 }, + { "matrix": [3, 8], "x": 8.75, "y": 3.25 }, + { "matrix": [3, 9], "x": 9.75, "y": 3.25 }, + { "matrix": [3, 10], "x": 10.75, "y": 3.25 }, + { "matrix": [3, 11], "x": 11.75, "y": 3.25 }, + { "matrix": [3, 13], "x": 12.75, "y": 3.25 }, + { "matrix": [4, 0], "x": 0, "y": 4.25 }, + { "matrix": [4, 2], "x": 2.25, "y": 4.25 }, + { "matrix": [4, 3], "x": 3.25, "y": 4.25 }, + { "matrix": [4, 4], "x": 4.25, "y": 4.25 }, + { "matrix": [4, 5], "x": 5.25, "y": 4.25 }, + { "matrix": [4, 6], "x": 6.25, "y": 4.25 }, + { "matrix": [4, 7], "x": 7.25, "y": 4.25 }, + { "matrix": [4, 8], "x": 8.25, "y": 4.25 }, + { "matrix": [4, 9], "x": 9.25, "y": 4.25 }, + { "matrix": [4, 10], "x": 10.25, "y": 4.25 }, + { "matrix": [4, 11], "x": 11.25, "y": 4.25 }, + { "matrix": [4, 12], "x": 12.25, "y": 4.25 }, + { "matrix": [4, 15], "x": 16.25, "y": 4.25 }, + { "matrix": [5, 0], "x": 0, "y": 5.25 }, + { "matrix": [5, 1], "x": 1.5, "y": 5.25 }, + { "matrix": [5, 2], "x": 2.5, "y": 5.25 }, + { "matrix": [5, 6], "x": 4, "y": 5.25 }, + { "matrix": [5, 11], "x": 11, "y": 5.25 }, + { "matrix": [5, 12], "x": 12.5, "y": 5.25 }, + { "matrix": [5, 13], "x": 13.5, "y": 5.25 }, + { "matrix": [5, 14], "x": 15.25, "y": 5.25 }, + { "matrix": [5, 15], "x": 16.25, "y": 5.25 }, + { "matrix": [5, 16], "x": 17.25, "y": 5.25 } + ] + }, + "LAYOUT_tkl_f13_ansi_tsangan_split_bs_rshift": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1.25, "y": 0 }, + { "matrix": [0, 2], "x": 2.25, "y": 0 }, + { "matrix": [0, 3], "x": 3.25, "y": 0 }, + { "matrix": [0, 4], "x": 4.25, "y": 0 }, + { "matrix": [0, 5], "x": 5.5, "y": 0 }, + { "matrix": [0, 6], "x": 6.5, "y": 0 }, + { "matrix": [0, 7], "x": 7.5, "y": 0 }, + { "matrix": [0, 8], "x": 8.5, "y": 0 }, + { "matrix": [0, 9], "x": 9.75, "y": 0 }, + { "matrix": [0, 10], "x": 10.75, "y": 0 }, + { "matrix": [0, 11], "x": 11.75, "y": 0 }, + { "matrix": [0, 12], "x": 12.75, "y": 0 }, + { "matrix": [0, 13], "x": 14, "y": 0 }, + { "matrix": [0, 14], "x": 15.25, "y": 0 }, + { "matrix": [0, 15], "x": 16.25, "y": 0 }, + { "matrix": [0, 16], "x": 17.25, "y": 0 }, + { "matrix": [1, 0], "x": 0, "y": 1.25 }, + { "matrix": [1, 1], "x": 1, "y": 1.25 }, + { "matrix": [1, 2], "x": 2, "y": 1.25 }, + { "matrix": [1, 3], "x": 3, "y": 1.25 }, + { "matrix": [1, 4], "x": 4, "y": 1.25 }, + { "matrix": [1, 5], "x": 5, "y": 1.25 }, + { "matrix": [1, 6], "x": 6, "y": 1.25 }, + { "matrix": [1, 7], "x": 7, "y": 1.25 }, + { "matrix": [1, 8], "x": 8, "y": 1.25 }, + { "matrix": [1, 9], "x": 9, "y": 1.25 }, + { "matrix": [1, 10], "x": 10, "y": 1.25 }, + { "matrix": [1, 11], "x": 11, "y": 1.25 }, + { "matrix": [1, 12], "x": 12, "y": 1.25 }, + { "matrix": [1, 13], "x": 13, "y": 1.25 }, + { "matrix": [2, 13], "x": 14, "y": 1.25 }, + { "matrix": [1, 14], "x": 15.25, "y": 1.25 }, + { "matrix": [1, 15], "x": 16.25, "y": 1.25 }, + { "matrix": [1, 16], "x": 17.25, "y": 1.25 }, + { "matrix": [2, 0], "x": 0, "y": 2.25 }, + { "matrix": [2, 1], "x": 1.5, "y": 2.25 }, + { "matrix": [2, 2], "x": 2.5, "y": 2.25 }, + { "matrix": [2, 3], "x": 3.5, "y": 2.25 }, + { "matrix": [2, 4], "x": 4.5, "y": 2.25 }, + { "matrix": [2, 5], "x": 5.5, "y": 2.25 }, + { "matrix": [2, 6], "x": 6.5, "y": 2.25 }, + { "matrix": [2, 7], "x": 7.5, "y": 2.25 }, + { "matrix": [2, 8], "x": 8.5, "y": 2.25 }, + { "matrix": [2, 9], "x": 9.5, "y": 2.25 }, + { "matrix": [2, 10], "x": 10.5, "y": 2.25 }, + { "matrix": [2, 11], "x": 11.5, "y": 2.25 }, + { "matrix": [2, 12], "x": 12.5, "y": 2.25 }, + { "matrix": [3, 12], "x": 13.5, "y": 2.25 }, + { "matrix": [2, 14], "x": 15.25, "y": 2.25 }, + { "matrix": [2, 15], "x": 16.25, "y": 2.25 }, + { "matrix": [2, 16], "x": 17.25, "y": 2.25 }, + { "matrix": [3, 0], "x": 0, "y": 3.25 }, + { "matrix": [3, 1], "x": 1.75, "y": 3.25 }, + { "matrix": [3, 2], "x": 2.75, "y": 3.25 }, + { "matrix": [3, 3], "x": 3.75, "y": 3.25 }, + { "matrix": [3, 4], "x": 4.75, "y": 3.25 }, + { "matrix": [3, 5], "x": 5.75, "y": 3.25 }, + { "matrix": [3, 6], "x": 6.75, "y": 3.25 }, + { "matrix": [3, 7], "x": 7.75, "y": 3.25 }, + { "matrix": [3, 8], "x": 8.75, "y": 3.25 }, + { "matrix": [3, 9], "x": 9.75, "y": 3.25 }, + { "matrix": [3, 10], "x": 10.75, "y": 3.25 }, + { "matrix": [3, 11], "x": 11.75, "y": 3.25 }, + { "matrix": [3, 13], "x": 12.75, "y": 3.25 }, + { "matrix": [4, 0], "x": 0, "y": 4.25 }, + { "matrix": [4, 2], "x": 2.25, "y": 4.25 }, + { "matrix": [4, 3], "x": 3.25, "y": 4.25 }, + { "matrix": [4, 4], "x": 4.25, "y": 4.25 }, + { "matrix": [4, 5], "x": 5.25, "y": 4.25 }, + { "matrix": [4, 6], "x": 6.25, "y": 4.25 }, + { "matrix": [4, 7], "x": 7.25, "y": 4.25 }, + { "matrix": [4, 8], "x": 8.25, "y": 4.25 }, + { "matrix": [4, 9], "x": 9.25, "y": 4.25 }, + { "matrix": [4, 10], "x": 10.25, "y": 4.25 }, + { "matrix": [4, 11], "x": 11.25, "y": 4.25 }, + { "matrix": [4, 12], "x": 12.25, "y": 4.25 }, + { "matrix": [4, 13], "x": 14, "y": 4.25 }, + { "matrix": [4, 15], "x": 16.25, "y": 4.25 }, + { "matrix": [5, 0], "x": 0, "y": 5.25 }, + { "matrix": [5, 1], "x": 1.5, "y": 5.25 }, + { "matrix": [5, 2], "x": 2.5, "y": 5.25 }, + { "matrix": [5, 6], "x": 4, "y": 5.25 }, + { "matrix": [5, 11], "x": 11, "y": 5.25 }, + { "matrix": [5, 12], "x": 12.5, "y": 5.25 }, + { "matrix": [5, 13], "x": 13.5, "y": 5.25 }, + { "matrix": [5, 14], "x": 15.25, "y": 5.25 }, + { "matrix": [5, 15], "x": 16.25, "y": 5.25 }, + { "matrix": [5, 16], "x": 17.25, "y": 5.25 } + ] + }, + "LAYOUT_tkl_f13_iso_tsangan": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1.25, "y": 0 }, + { "matrix": [0, 2], "x": 2.25, "y": 0 }, + { "matrix": [0, 3], "x": 3.25, "y": 0 }, + { "matrix": [0, 4], "x": 4.25, "y": 0 }, + { "matrix": [0, 5], "x": 5.5, "y": 0 }, + { "matrix": [0, 6], "x": 6.5, "y": 0 }, + { "matrix": [0, 7], "x": 7.5, "y": 0 }, + { "matrix": [0, 8], "x": 8.5, "y": 0 }, + { "matrix": [0, 9], "x": 9.75, "y": 0 }, + { "matrix": [0, 10], "x": 10.75, "y": 0 }, + { "matrix": [0, 11], "x": 11.75, "y": 0 }, + { "matrix": [0, 12], "x": 12.75, "y": 0 }, + { "matrix": [0, 13], "x": 14, "y": 0 }, + { "matrix": [0, 14], "x": 15.25, "y": 0 }, + { "matrix": [0, 15], "x": 16.25, "y": 0 }, + { "matrix": [0, 16], "x": 17.25, "y": 0 }, + { "matrix": [1, 0], "x": 0, "y": 1.25 }, + { "matrix": [1, 1], "x": 1, "y": 1.25 }, + { "matrix": [1, 2], "x": 2, "y": 1.25 }, + { "matrix": [1, 3], "x": 3, "y": 1.25 }, + { "matrix": [1, 4], "x": 4, "y": 1.25 }, + { "matrix": [1, 5], "x": 5, "y": 1.25 }, + { "matrix": [1, 6], "x": 6, "y": 1.25 }, + { "matrix": [1, 7], "x": 7, "y": 1.25 }, + { "matrix": [1, 8], "x": 8, "y": 1.25 }, + { "matrix": [1, 9], "x": 9, "y": 1.25 }, + { "matrix": [1, 10], "x": 10, "y": 1.25 }, + { "matrix": [1, 11], "x": 11, "y": 1.25 }, + { "matrix": [1, 12], "x": 12, "y": 1.25 }, + { "matrix": [1, 13], "x": 13, "y": 1.25 }, + { "matrix": [1, 14], "x": 15.25, "y": 1.25 }, + { "matrix": [1, 15], "x": 16.25, "y": 1.25 }, + { "matrix": [1, 16], "x": 17.25, "y": 1.25 }, + { "matrix": [2, 0], "x": 0, "y": 2.25 }, + { "matrix": [2, 1], "x": 1.5, "y": 2.25 }, + { "matrix": [2, 2], "x": 2.5, "y": 2.25 }, + { "matrix": [2, 3], "x": 3.5, "y": 2.25 }, + { "matrix": [2, 4], "x": 4.5, "y": 2.25 }, + { "matrix": [2, 5], "x": 5.5, "y": 2.25 }, + { "matrix": [2, 6], "x": 6.5, "y": 2.25 }, + { "matrix": [2, 7], "x": 7.5, "y": 2.25 }, + { "matrix": [2, 8], "x": 8.5, "y": 2.25 }, + { "matrix": [2, 9], "x": 9.5, "y": 2.25 }, + { "matrix": [2, 10], "x": 10.5, "y": 2.25 }, + { "matrix": [2, 11], "x": 11.5, "y": 2.25 }, + { "matrix": [2, 12], "x": 12.5, "y": 2.25 }, + { "matrix": [2, 14], "x": 13.75, "y": 2.25 }, + { "matrix": [2, 15], "x": 15.25, "y": 2.25 }, + { "matrix": [2, 16], "x": 16.25, "y": 2.25 }, + { "matrix": [3, 0], "x": 17.25, "y": 2.25 }, + { "matrix": [3, 1], "x": 0, "y": 3.25 }, + { "matrix": [3, 2], "x": 1.75, "y": 3.25 }, + { "matrix": [3, 3], "x": 2.75, "y": 3.25 }, + { "matrix": [3, 4], "x": 3.75, "y": 3.25 }, + { "matrix": [3, 5], "x": 4.75, "y": 3.25 }, + { "matrix": [3, 6], "x": 5.75, "y": 3.25 }, + { "matrix": [3, 7], "x": 6.75, "y": 3.25 }, + { "matrix": [3, 8], "x": 7.75, "y": 3.25 }, + { "matrix": [3, 9], "x": 8.75, "y": 3.25 }, + { "matrix": [3, 10], "x": 9.75, "y": 3.25 }, + { "matrix": [3, 11], "x": 10.75, "y": 3.25 }, + { "matrix": [3, 12], "x": 11.75, "y": 3.25 }, + { "matrix": [3, 13], "x": 12.75, "y": 3.25 }, + { "matrix": [4, 0], "x": 0, "y": 4.25 }, + { "matrix": [4, 1], "x": 1.25, "y": 4.25 }, + { "matrix": [4, 2], "x": 2.25, "y": 4.25 }, + { "matrix": [4, 3], "x": 3.25, "y": 4.25 }, + { "matrix": [4, 4], "x": 4.25, "y": 4.25 }, + { "matrix": [4, 5], "x": 5.25, "y": 4.25 }, + { "matrix": [4, 6], "x": 6.25, "y": 4.25 }, + { "matrix": [4, 7], "x": 7.25, "y": 4.25 }, + { "matrix": [4, 8], "x": 8.25, "y": 4.25 }, + { "matrix": [4, 9], "x": 9.25, "y": 4.25 }, + { "matrix": [4, 10], "x": 10.25, "y": 4.25 }, + { "matrix": [4, 11], "x": 11.25, "y": 4.25 }, + { "matrix": [4, 12], "x": 12.25, "y": 4.25 }, + { "matrix": [4, 15], "x": 16.25, "y": 4.25 }, + { "matrix": [5, 0], "x": 0, "y": 5.25 }, + { "matrix": [5, 1], "x": 1.5, "y": 5.25 }, + { "matrix": [5, 2], "x": 2.5, "y": 5.25 }, + { "matrix": [5, 6], "x": 4, "y": 5.25 }, + { "matrix": [5, 11], "x": 11, "y": 5.25 }, + { "matrix": [5, 12], "x": 12.5, "y": 5.25 }, + { "matrix": [5, 13], "x": 13.5, "y": 5.25 }, + { "matrix": [5, 14], "x": 15.25, "y": 5.25 }, + { "matrix": [5, 15], "x": 16.25, "y": 5.25 }, + { "matrix": [5, 16], "x": 17.25, "y": 5.25 } + ] + }, + "LAYOUT_tkl_f13_iso_tsangan_split_bs_rshift": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0 }, + { "matrix": [0, 1], "x": 1.25, "y": 0 }, + { "matrix": [0, 2], "x": 2.25, "y": 0 }, + { "matrix": [0, 3], "x": 3.25, "y": 0 }, + { "matrix": [0, 4], "x": 4.25, "y": 0 }, + { "matrix": [0, 5], "x": 5.5, "y": 0 }, + { "matrix": [0, 6], "x": 6.5, "y": 0 }, + { "matrix": [0, 7], "x": 7.5, "y": 0 }, + { "matrix": [0, 8], "x": 8.5, "y": 0 }, + { "matrix": [0, 9], "x": 9.75, "y": 0 }, + { "matrix": [0, 10], "x": 10.75, "y": 0 }, + { "matrix": [0, 11], "x": 11.75, "y": 0 }, + { "matrix": [0, 12], "x": 12.75, "y": 0 }, + { "matrix": [0, 13], "x": 14, "y": 0 }, + { "matrix": [0, 14], "x": 15.25, "y": 0 }, + { "matrix": [0, 15], "x": 16.25, "y": 0 }, + { "matrix": [0, 16], "x": 17.25, "y": 0 }, + { "matrix": [1, 0], "x": 0, "y": 1.25 }, + { "matrix": [1, 1], "x": 1, "y": 1.25 }, + { "matrix": [1, 2], "x": 2, "y": 1.25 }, + { "matrix": [1, 3], "x": 3, "y": 1.25 }, + { "matrix": [1, 4], "x": 4, "y": 1.25 }, + { "matrix": [1, 5], "x": 5, "y": 1.25 }, + { "matrix": [1, 6], "x": 6, "y": 1.25 }, + { "matrix": [1, 7], "x": 7, "y": 1.25 }, + { "matrix": [1, 8], "x": 8, "y": 1.25 }, + { "matrix": [1, 9], "x": 9, "y": 1.25 }, + { "matrix": [1, 10], "x": 10, "y": 1.25 }, + { "matrix": [1, 11], "x": 11, "y": 1.25 }, + { "matrix": [1, 12], "x": 12, "y": 1.25 }, + { "matrix": [1, 13], "x": 13, "y": 1.25 }, + { "matrix": [2, 13], "x": 14, "y": 1.25 }, + { "matrix": [1, 14], "x": 15.25, "y": 1.25 }, + { "matrix": [1, 15], "x": 16.25, "y": 1.25 }, + { "matrix": [1, 16], "x": 17.25, "y": 1.25 }, + { "matrix": [2, 0], "x": 0, "y": 2.25 }, + { "matrix": [2, 1], "x": 1.5, "y": 2.25 }, + { "matrix": [2, 2], "x": 2.5, "y": 2.25 }, + { "matrix": [2, 3], "x": 3.5, "y": 2.25 }, + { "matrix": [2, 4], "x": 4.5, "y": 2.25 }, + { "matrix": [2, 5], "x": 5.5, "y": 2.25 }, + { "matrix": [2, 6], "x": 6.5, "y": 2.25 }, + { "matrix": [2, 7], "x": 7.5, "y": 2.25 }, + { "matrix": [2, 8], "x": 8.5, "y": 2.25 }, + { "matrix": [2, 9], "x": 9.5, "y": 2.25 }, + { "matrix": [2, 10], "x": 10.5, "y": 2.25 }, + { "matrix": [2, 11], "x": 11.5, "y": 2.25 }, + { "matrix": [2, 12], "x": 12.5, "y": 2.25 }, + { "matrix": [2, 14], "x": 13.75, "y": 2.25 }, + { "matrix": [2, 15], "x": 15.25, "y": 2.25 }, + { "matrix": [2, 16], "x": 16.25, "y": 2.25 }, + { "matrix": [3, 0], "x": 17.25, "y": 2.25 }, + { "matrix": [3, 1], "x": 0, "y": 3.25 }, + { "matrix": [3, 2], "x": 1.75, "y": 3.25 }, + { "matrix": [3, 3], "x": 2.75, "y": 3.25 }, + { "matrix": [3, 4], "x": 3.75, "y": 3.25 }, + { "matrix": [3, 5], "x": 4.75, "y": 3.25 }, + { "matrix": [3, 6], "x": 5.75, "y": 3.25 }, + { "matrix": [3, 7], "x": 6.75, "y": 3.25 }, + { "matrix": [3, 8], "x": 7.75, "y": 3.25 }, + { "matrix": [3, 9], "x": 8.75, "y": 3.25 }, + { "matrix": [3, 10], "x": 9.75, "y": 3.25 }, + { "matrix": [3, 11], "x": 10.75, "y": 3.25 }, + { "matrix": [3, 12], "x": 11.75, "y": 3.25 }, + { "matrix": [3, 13], "x": 12.75, "y": 3.25 }, + { "matrix": [4, 0], "x": 0, "y": 4.25 }, + { "matrix": [4, 1], "x": 1.25, "y": 4.25 }, + { "matrix": [4, 2], "x": 2.25, "y": 4.25 }, + { "matrix": [4, 3], "x": 3.25, "y": 4.25 }, + { "matrix": [4, 4], "x": 4.25, "y": 4.25 }, + { "matrix": [4, 5], "x": 5.25, "y": 4.25 }, + { "matrix": [4, 6], "x": 6.25, "y": 4.25 }, + { "matrix": [4, 7], "x": 7.25, "y": 4.25 }, + { "matrix": [4, 8], "x": 8.25, "y": 4.25 }, + { "matrix": [4, 9], "x": 9.25, "y": 4.25 }, + { "matrix": [4, 10], "x": 10.25, "y": 4.25 }, + { "matrix": [4, 11], "x": 11.25, "y": 4.25 }, + { "matrix": [4, 12], "x": 12.25, "y": 4.25 }, + { "matrix": [4, 13], "x": 14, "y": 4.25 }, + { "matrix": [4, 15], "x": 16.25, "y": 4.25 }, + { "matrix": [5, 0], "x": 0, "y": 5.25 }, + { "matrix": [5, 1], "x": 1.5, "y": 5.25 }, + { "matrix": [5, 2], "x": 2.5, "y": 5.25 }, + { "matrix": [5, 6], "x": 4, "y": 5.25 }, + { "matrix": [5, 11], "x": 11, "y": 5.25 }, + { "matrix": [5, 12], "x": 12.5, "y": 5.25 }, + { "matrix": [5, 13], "x": 13.5, "y": 5.25 }, + { "matrix": [5, 14], "x": 15.25, "y": 5.25 }, + { "matrix": [5, 15], "x": 16.25, "y": 5.25 }, + { "matrix": [5, 16], "x": 17.25, "y": 5.25 } + ] + } + } +} diff --git a/keyboards/cablecardesigns/phoenix/keymaps/default/keymap.c b/keyboards/cablecardesigns/phoenix/keymaps/default/keymap.c new file mode 100644 index 000000000000..e008bee3b1d6 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/keymaps/default/keymap.c @@ -0,0 +1,27 @@ +/* Copyright 2023 Yiancar-Designs + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT_all( /* Base */ + KC_ESC, 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_F13, KC_PSCR, KC_SCRL, KC_PAUS, + + KC_GRV, 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_DEL, KC_INS, KC_HOME, KC_PGUP, + 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_END, KC_PGDN, + 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_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT) +}; diff --git a/keyboards/cablecardesigns/phoenix/keymaps/via/keymap.c b/keyboards/cablecardesigns/phoenix/keymaps/via/keymap.c new file mode 100644 index 000000000000..e008bee3b1d6 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/keymaps/via/keymap.c @@ -0,0 +1,27 @@ +/* Copyright 2023 Yiancar-Designs + * + * 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 . + */ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[0] = LAYOUT_all( /* Base */ + KC_ESC, 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_F13, KC_PSCR, KC_SCRL, KC_PAUS, + + KC_GRV, 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_DEL, KC_INS, KC_HOME, KC_PGUP, + 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_END, KC_PGDN, + 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_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_RSFT, KC_UP, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT) +}; diff --git a/keyboards/cablecardesigns/phoenix/keymaps/via/rules.mk b/keyboards/cablecardesigns/phoenix/keymaps/via/rules.mk new file mode 100755 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/quantum/process_keycode/process_key_lock.h b/keyboards/cablecardesigns/phoenix/phoenix.c old mode 100644 new mode 100755 similarity index 79% rename from quantum/process_keycode/process_key_lock.h rename to keyboards/cablecardesigns/phoenix/phoenix.c index 5159b0ba023c..251f79a953d9 --- a/quantum/process_keycode/process_key_lock.h +++ b/keyboards/cablecardesigns/phoenix/phoenix.c @@ -1,4 +1,4 @@ -/* Copyright 2017 Fredric Silberberg +/* Copyright 2023 Yiancar-Designs * * 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 @@ -14,9 +14,9 @@ * along with this program. If not, see . */ -#pragma once - #include "quantum.h" -void cancel_key_lock(void); -bool process_key_lock(uint16_t *keycode, keyrecord_t *record); +void led_init_ports(void) { + // Set our LED pins as open drain outputs + palSetLineMode(LED_CAPS_LOCK_PIN, PAL_MODE_OUTPUT_OPENDRAIN); +} diff --git a/keyboards/cablecardesigns/phoenix/readme.md b/keyboards/cablecardesigns/phoenix/readme.md new file mode 100755 index 000000000000..0574da435174 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/readme.md @@ -0,0 +1,32 @@ +# Phoenix + +This is a standard TKL F13 layout PCB. It supports VIA. + +* Keyboard Maintainer: [Yiancar](http://yiancar-designs.com/) and on [GitHub](https://github.com/yiancar) +* Hardware Supported: A TKL keyboard with STM32F072CB +* Hardware Availability: https://cablecardesigns.co + +## Instructions + +### Build + +Make example for this keyboard (after setting up your build environment): + + make cablecardesigns/phoenix:default + +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). + +### Reset + +- Unplug +- Hold Escape +- Plug In +- Unplug +- Release Escape + +### Flash + +- Unplug +- Hold Escape +- Plug In +- Flash using QMK Toolbox or CLI (`make cablecardesigns/phoenix::flash`) diff --git a/keyboards/cablecardesigns/phoenix/rules.mk b/keyboards/cablecardesigns/phoenix/rules.mk new file mode 100755 index 000000000000..7ce6edcba902 --- /dev/null +++ b/keyboards/cablecardesigns/phoenix/rules.mk @@ -0,0 +1,7 @@ +# Wildcard to allow APM32 MCU +DFU_SUFFIX_ARGS = -v FFFF -p FFFF + +# Do not put the microcontroller into power saving mode +# when we get USB suspend event. We want it to keep updating +# backlight effects. +OPT_DEFS += -DCORTEX_ENABLE_WFI_IDLE=TRUE diff --git a/keyboards/churrosoft/deck8/info.json b/keyboards/churrosoft/deck8/info.json new file mode 100644 index 000000000000..00fc2d1bad76 --- /dev/null +++ b/keyboards/churrosoft/deck8/info.json @@ -0,0 +1,43 @@ +{ + "keyboard_name": "Deck-8", + "manufacturer": "Churrosoft", + "url": "https://churrosoft.ar/deck", + "maintainer": "Polsaker", + "usb": { + "vid": "0xCBBC", + "device_version": "1.0.0" + }, + "build": { + "lto": true + }, + "features": { + "bootmagic": true, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + + }, + "processor": "RP2040", + "bootloader": "rp2040", + "matrix_pins": { + "direct": [ + ["GP15", "GP18", "GP22", "GP24"], + ["GP13", "GP11", "GP0", "GP2"] + ] + }, + "layouts": { + "LAYOUT": { + "layout": [ + {"x":0, "y":0, "matrix": [0, 0]}, + {"x":1, "y":0, "matrix": [0, 1]}, + {"x":2, "y":0, "matrix": [0, 2]}, + {"x":3, "y":0, "matrix": [0, 3]}, + {"x":0, "y":1, "matrix": [1, 0]}, + {"x":1, "y":1, "matrix": [1, 1]}, + {"x":2, "y":1, "matrix": [1, 2]}, + {"x":3, "y":1, "matrix": [1, 3]} + ] + } + } +} \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/keymaps/default/keymap.c b/keyboards/churrosoft/deck8/keymaps/default/keymap.c new file mode 100644 index 000000000000..cc1bcea1097b --- /dev/null +++ b/keyboards/churrosoft/deck8/keymaps/default/keymap.c @@ -0,0 +1,25 @@ +/* Copyright 2023 Churrosoft +* +* 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 . +*/ + + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + MEH(KC_A), MEH(KC_B), MEH(KC_C), MEH(KC_D), + MEH(KC_E), MEH(KC_F), MEH(KC_G), MEH(KC_H) + ) +}; \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/keymaps/via/keymap.c b/keyboards/churrosoft/deck8/keymaps/via/keymap.c new file mode 100644 index 000000000000..2a1b10d442bf --- /dev/null +++ b/keyboards/churrosoft/deck8/keymaps/via/keymap.c @@ -0,0 +1,24 @@ +/* Copyright 2023 Churrosoft +* +* 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 . + */ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + MEH(KC_A), MEH(KC_B), MEH(KC_C), MEH(KC_D), + MEH(KC_E), MEH(KC_F), MEH(KC_G), MEH(KC_H) + ) +}; \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/keymaps/via/rules.mk b/keyboards/churrosoft/deck8/keymaps/via/rules.mk new file mode 100644 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/churrosoft/deck8/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/churrosoft/deck8/noleds/info.json b/keyboards/churrosoft/deck8/noleds/info.json new file mode 100644 index 000000000000..fa1e2a420d84 --- /dev/null +++ b/keyboards/churrosoft/deck8/noleds/info.json @@ -0,0 +1,5 @@ +{ + "usb": { + "pid": "0xC100" + } +} \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/noleds/readme.md b/keyboards/churrosoft/deck8/noleds/readme.md new file mode 100644 index 000000000000..c4e8d70c810a --- /dev/null +++ b/keyboards/churrosoft/deck8/noleds/readme.md @@ -0,0 +1,27 @@ +# Churrosoft Deck-8 (No LEDs version) + +![ChurroDeck-8](https://i.imgur.com/NNmq8hzh.png) + +A small 8-key macropad + +* Keyboard Maintainer: [Polsaker](https://github.com/Polsaker) +* Hardware Supported: ChurroDeck PCV rev. 1b, 1c and 1d +* Hardware Availability: [churrosoft.ar](https://churrosoft.ar/deck) + +Make example for this keyboard (after setting up your build environment): + + make churrosoft/deck8/noleds:default + +Flashing example for this keyboard: + + make churrosoft/deck8/noleds: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 (the top left key) and plug in the keyboard +* **Physical reset button**: Short the `JP1` jumper in the back side of the PCB. +* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/noleds/rules.mk b/keyboards/churrosoft/deck8/noleds/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/churrosoft/deck8/noleds/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/churrosoft/deck8/rgb/config.h b/keyboards/churrosoft/deck8/rgb/config.h new file mode 100644 index 000000000000..2454c42fbabf --- /dev/null +++ b/keyboards/churrosoft/deck8/rgb/config.h @@ -0,0 +1,74 @@ +/* Copyright 2023 Churrosoft +* +* 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 . + */ + +#pragma once + +#define RGB_MATRIX_LED_COUNT 8 +#define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_SOLID_COLOR +#define RGB_MATRIX_DEFAULT_HUE 152 +#define RGB_MATRIX_DEFAULT_SAT 232 +#define RGB_MATRIX_DEFAULT_VAL 180 +#define RGB_DISABLE_WHEN_USB_SUSPENDED + +#define RGB_MATRIX_FRAMEBUFFER_EFFECTS +#define RGB_MATRIX_KEYPRESSES + +#define ENABLE_RGB_MATRIX_SOLID_COLOR +#define ENABLE_RGB_MATRIX_ALPHAS_MODS +#define ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN +#define ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT +#define ENABLE_RGB_MATRIX_BREATHING +#define ENABLE_RGB_MATRIX_BAND_SAT +#define ENABLE_RGB_MATRIX_BAND_VAL +#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT +#define ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL +#define ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT +#define ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL +#define ENABLE_RGB_MATRIX_CYCLE_ALL +#define ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT +#define ENABLE_RGB_MATRIX_CYCLE_UP_DOWN +#define ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON +#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN +#define ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL +#define ENABLE_RGB_MATRIX_CYCLE_PINWHEEL +#define ENABLE_RGB_MATRIX_CYCLE_SPIRAL +#define ENABLE_RGB_MATRIX_DUAL_BEACON +#define ENABLE_RGB_MATRIX_RAINBOW_BEACON +#define ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS +#define ENABLE_RGB_MATRIX_RAINDROPS +#define ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS +#define ENABLE_RGB_MATRIX_HUE_BREATHING +#define ENABLE_RGB_MATRIX_HUE_PENDULUM +#define ENABLE_RGB_MATRIX_HUE_WAVE +#define ENABLE_RGB_MATRIX_PIXEL_RAIN +#define ENABLE_RGB_MATRIX_PIXEL_FLOW +#define ENABLE_RGB_MATRIX_PIXEL_FRACTAL +// enabled only if RGB_MATRIX_FRAMEBUFFER_EFFECTS is defined +#define ENABLE_RGB_MATRIX_TYPING_HEATMAP +#define ENABLE_RGB_MATRIX_DIGITAL_RAIN +// enabled only of RGB_MATRIX_KEYPRESSES or RGB_MATRIX_KEYRELEASES is defined +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS +#define ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS +#define ENABLE_RGB_MATRIX_SPLASH +#define ENABLE_RGB_MATRIX_MULTISPLASH +#define ENABLE_RGB_MATRIX_SOLID_SPLASH +#define ENABLE_RGB_MATRIX_SOLID_MULTISPLASH diff --git a/keyboards/churrosoft/deck8/rgb/info.json b/keyboards/churrosoft/deck8/rgb/info.json new file mode 100644 index 000000000000..43f273be58c9 --- /dev/null +++ b/keyboards/churrosoft/deck8/rgb/info.json @@ -0,0 +1,27 @@ +{ + "keyboard_name": "Deck-8 RGB", + "usb": { + "pid": "0xC101" + }, + "ws2812": { + "pin": "GP17", + "driver": "vendor" + }, + "features": { + "rgb_matrix": true + }, + "rgb_matrix": { + "driver": "WS2812", + "max_brightness": 200, + "layout": [ + {"flags": 4, "matrix": [0, 0], "x": 45, "y": 21}, + {"flags": 4, "matrix": [0, 1], "x": 90, "y": 21}, + {"flags": 4, "matrix": [0, 2], "x": 135, "y": 21}, + {"flags": 4, "matrix": [0, 3], "x": 180, "y": 21}, + {"flags": 4, "matrix": [1, 0], "x": 45, "y": 42}, + {"flags": 4, "matrix": [1, 1], "x": 90, "y": 42}, + {"flags": 4, "matrix": [1, 2], "x": 135, "y": 42}, + {"flags": 4, "matrix": [1, 3], "x": 180, "y": 42} + ] + } +} \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/rgb/readme.md b/keyboards/churrosoft/deck8/rgb/readme.md new file mode 100644 index 000000000000..87fe400c243b --- /dev/null +++ b/keyboards/churrosoft/deck8/rgb/readme.md @@ -0,0 +1,27 @@ +# Churrosoft Deck-8 (RGB Version) + +![ChurroDeck-8](https://i.imgur.com/NNmq8hzh.png) + +A small 8-key macropad with RGB + +* Keyboard Maintainer: [Polsaker](https://github.com/Polsaker) +* Hardware Supported: ChurroDeck PCV rev. 1b, 1c and 1d +* Hardware Availability: [churrosoft.ar](https://churrosoft.ar/deck) + +Make example for this keyboard (after setting up your build environment): + + make churrosoft/deck8/rgb:default + +Flashing example for this keyboard: + + make churrosoft/deck8/rgb: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 (the top left key) and plug in the keyboard +* **Physical reset button**: Short the `JP1` jumper in the back side of the PCB. +* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available \ No newline at end of file diff --git a/keyboards/churrosoft/deck8/rgb/rules.mk b/keyboards/churrosoft/deck8/rgb/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/churrosoft/deck8/rgb/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/contra/keymaps/bramver/README.md b/keyboards/contra/keymaps/bramver/README.md index 3c7028a933f2..c5a887ce2c13 100644 --- a/keyboards/contra/keymaps/bramver/README.md +++ b/keyboards/contra/keymaps/bramver/README.md @@ -22,9 +22,9 @@ LOWER layer { _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ }, EMOJI layer - { _______ , X(CLAP) , X(CUM) , X(BNIS) , X(BUTT) , X(CAR) , X(FIRE) , X(REDB) , X(MONY) , X(HNDR) , X(SOS) , _______ }, - { _______ , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , _______ }, - { _______ , X(TRIU) , X(SCRM) , X(VOMI) , X(DTIV) , X(EXPL) , X(HAIR) , X(DANC) , X(STRN) , X(LEFT) , X(RGHT) , _______ }, + { _______ , UM(CLAP) , UM(CUM) , UM(BNIS) , UM(BUTT) , UM(CAR) , UM(FIRE) , UM(REDB) , UM(MONY) , UM(HNDR) , UM(SOS) , _______ }, + { _______ , UM(CELE) , UM(PRAY) , UM(NAIL) , UM(OK) , UM(THNK) , UM(UNAM) , UM(HEYE) , UM(COOL) , UM(EYES) , UM(SMIR) , _______ }, + { _______ , UM(TRIU) , UM(SCRM) , UM(VOMI) , UM(DTIV) , UM(EXPL) , UM(HAIR) , UM(DANC) , UM(STRN) , UM(LEFT) , UM(RGHT) , _______ }, { _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ }, MOUSE layer diff --git a/keyboards/contra/keymaps/bramver/keymap.c b/keyboards/contra/keymaps/bramver/keymap.c index 3816ee629e2c..08f25119c272 100644 --- a/keyboards/contra/keymaps/bramver/keymap.c +++ b/keyboards/contra/keymaps/bramver/keymap.c @@ -106,9 +106,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [_EMOJI] = LAYOUT_ortho_4x12( - _______ , X(CLAP) , X(CUM) , X(BNIS) , X(BUTT) , X(CAR) , X(FIRE) , X(REDB) , X(MONY) , X(HNDR) , X(SOS) , _______ , - _______ , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , _______ , - _______ , X(TRIU) , X(SCRM) , X(VOMI) , X(DTIV) , X(EXPL) , X(HAIR) , X(DANC) , X(STRN) , X(LEFT) , X(RGHT) , _______ , + _______ , UM(CLAP) , UM(CUM) , UM(BNIS) , UM(BUTT) , UM(CAR) , UM(FIRE) , UM(REDB) , UM(MONY) , UM(HNDR) , UM(SOS) , _______ , + _______ , UM(CELE) , UM(PRAY) , UM(NAIL) , UM(OK) , UM(THNK) , UM(UNAM) , UM(HEYE) , UM(COOL) , UM(EYES) , UM(SMIR) , _______ , + _______ , UM(TRIU) , UM(SCRM) , UM(VOMI) , UM(DTIV) , UM(EXPL) , UM(HAIR) , UM(DANC) , UM(STRN) , UM(LEFT) , UM(RGHT) , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ), diff --git a/keyboards/converter/ibm_terminal/keymaps/priyadi/keymap.c b/keyboards/converter/ibm_terminal/keymaps/priyadi/keymap.c index 0e11fa677975..3645dd7da723 100644 --- a/keyboards/converter/ibm_terminal/keymaps/priyadi/keymap.c +++ b/keyboards/converter/ibm_terminal/keymaps/priyadi/keymap.c @@ -226,9 +226,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY), X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV),XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN), X(HEART),X(BYE), X(KISS), X(CELEB),X(COOL), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,X(SLEEP),X(CLAP), X(CRY), X(VIC), X(BHART),X(SUN), X(SMEYE),X(WINK), X(MOON), X(CONFU), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, UM(CRY2),UM(WEARY),UM(EYERT),UM(SMIRK), UM(TJOY), UM(RECYC),UM(UNAMU),UM(MUSIC),UM(OKHND),UM(PENSV),XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, UM(PRAY),UM(SMILE),UM(SMIL2),UM(FLUSH), UM(GRIN), UM(HEART),UM(BYE), UM(KISS), UM(CELEB),UM(COOL), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX,UM(SLEEP),UM(CLAP), UM(CRY), UM(VIC), UM(BHART),UM(SUN), UM(SMEYE),UM(WINK), UM(MOON), UM(CONFU), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX ), diff --git a/keyboards/crkbd/r2g/config.h b/keyboards/crkbd/r2g/config.h index e44626739d49..455f179e9005 100644 --- a/keyboards/crkbd/r2g/config.h +++ b/keyboards/crkbd/r2g/config.h @@ -33,8 +33,6 @@ along with this program. If not, see . # define RGBLIGHT_EFFECT_TWINKLE # define RGBLED_NUM 54 -# define RGBLED_SPLIT \ - { 27, 27 } #endif #ifdef RGB_MATRIX_ENABLE diff --git a/keyboards/crkbd/r2g/info.json b/keyboards/crkbd/r2g/info.json index cfd29368e61e..1de40c039515 100644 --- a/keyboards/crkbd/r2g/info.json +++ b/keyboards/crkbd/r2g/info.json @@ -5,6 +5,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [27, 27] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/crkbd/rev1/config.h b/keyboards/crkbd/rev1/config.h index 2378a8637fb4..f3e3bc4c51d4 100644 --- a/keyboards/crkbd/rev1/config.h +++ b/keyboards/crkbd/rev1/config.h @@ -20,8 +20,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE # define RGBLED_NUM 54 // Number of LEDs -# define RGBLED_SPLIT \ - { 27, 27 } # define RGBLIGHT_SPLIT #endif diff --git a/keyboards/crkbd/rev1/info.json b/keyboards/crkbd/rev1/info.json index 4f63c95170c4..e9114e903ca4 100644 --- a/keyboards/crkbd/rev1/info.json +++ b/keyboards/crkbd/rev1/info.json @@ -5,6 +5,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [27, 27] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/doppelganger/config.h b/keyboards/doppelganger/config.h index bc64bd9001c0..b61d89058394 100644 --- a/keyboards/doppelganger/config.h +++ b/keyboards/doppelganger/config.h @@ -23,7 +23,6 @@ along with this program. If not, see . #define RGBLED_NUM 2 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 1, 1 } /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ #define LOCKING_SUPPORT_ENABLE diff --git a/keyboards/doppelganger/info.json b/keyboards/doppelganger/info.json index 83a3e68be750..49c3ac1bfac7 100644 --- a/keyboards/doppelganger/info.json +++ b/keyboards/doppelganger/info.json @@ -22,6 +22,9 @@ } } }, + "rgblight": { + "split_count": [1, 1] + }, "ws2812": { "pin": "B4" }, diff --git a/keyboards/durgod/k320/keymaps/kuenhlee/keymap.c b/keyboards/durgod/k320/keymaps/kuenhlee/keymap.c index 7f49352de45f..4092126d7fa6 100644 --- a/keyboards/durgod/k320/keymaps/kuenhlee/keymap.c +++ b/keyboards/durgod/k320/keymaps/kuenhlee/keymap.c @@ -132,11 +132,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_UL] = LAYOUT_tkl_ansi( /* Unicode Layer */ XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - X(APPR), X(NEQU), X(POW2), X(POW3), XXXXXXX, XXXXXXX, X(BSQR), X(WSQR), X(INFI), X(BDOT), X(WDOT), XXXXXXX, X(PONE), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, X(SUM), XXXXXXX, X(MYU), X(SAME), XXXXXXX, X(OHM), X(DLAR), X(DRAR), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, X(SQRT), X(DELT), XXXXXXX, XXXXXXX, X(THFR), XXXXXXX, XXXXXXX, XXXXXXX, X(THET), X(DEGR), XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, X(COPY), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, X(LTOE), X(MTOE), X(DIV), XXXXXXX, X(UARR), - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_TRNS, KC_TRNS, XXXXXXX, X(LARR), X(DARR), X(RARR) + UM(APPR), UM(NEQU), UM(POW2), UM(POW3), XXXXXXX, XXXXXXX, UM(BSQR), UM(WSQR), UM(INFI), UM(BDOT), UM(WDOT), XXXXXXX, UM(PONE), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, UM(SUM), XXXXXXX, UM(MYU), UM(SAME), XXXXXXX, UM(OHM), UM(DLAR), UM(DRAR), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, UM(SQRT), UM(DELT), XXXXXXX, XXXXXXX, UM(THFR), XXXXXXX, XXXXXXX, XXXXXXX, UM(THET), UM(DEGR), XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, UM(COPY), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, UM(LTOE), UM(MTOE), UM(DIV), XXXXXXX, UM(UARR), + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_TRNS, KC_TRNS, XXXXXXX, UM(LARR), UM(DARR), UM(RARR) ) }; diff --git a/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c b/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c index d4e1851f68cb..7b4e9ab72884 100644 --- a/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c +++ b/keyboards/dztech/dz65rgb/keymaps/catrielmuller/keymap.c @@ -166,10 +166,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(_INDEX), KC_NO, KC_MPRV, KC_VOLD, KC_MNXT ), [_EMOJI] = LAYOUT_65_ansi( - TO(_MAIN), X(UC_GRINNING_FACE), X(UC_BEAMING_FACE), X(UC_GRINNING_FACE_WITH_SWEAT), X(UC_ROLLING_LAUGHING), X(UC_FACE_TEARS_JOY), X(UC_WINKING_FACE), X(UC_SMILING_FACE_HALO), X(UC_SMILING_FACE_HEARTS), X(UC_SMILING_FACE_HEART_EYES), X(UC_FACE_BLOWING_KISS), X(UC_FACE_SAVORING_FOOD), X(UC_ZANY_FACE), KC_BSPC, KC_HOME, - KC_TAB, X(UC_HUGGING_FACE), X(UC_SHUSHING_FACE), X(UC_THINKING_FACE), X(UC_FACE_RAISED_EYEBROW), X(UC_NEUTRAL_FACE), X(UC_SMIRKING_FACE), X(UC_FACE_ROLLING_EYES), X(UC_PENSIVE_FACE), X(UC_FACE_VOMITING), X(UC_WOOZY_FACE), X(UC_PLEADING_FACE), X(UC_LOUDLY_CRYING_FACE), X(UC_THUMBSUP), KC_END, - KC_APP, X(UC_DISAPPOINTED_FACE), X(UC_FACE_SYMBOLS_MOUTH), X(UC_SMILING_FACE_HORNS), X(UC_SKULL), X(UC_PILE_POO), X(UC_GHOST), X(UC_ALIEN_MONSTER), X(UC_RED_HEART), X(UC_BOMB), X(UC_WAVING_HAND), X(UC_OK_HAND), KC_ENT, KC_PGUP, - KC_LSFT, X(UC_CLAPPING_HANDS), X(UC_EYES), X(UC_MAN_FACEPALMING), X(UC_TURTLE), X(UC_SNAKE), X(UC_SPOUTING_WHALE), X(UC_DRAGON), X(UC_TREX), X(UC_ARGENTINA_A), X(UC_ARGENTINA_R), X(UC_THUMBSDOWN), KC_UP, KC_PGDN, + TO(_MAIN), UM(UC_GRINNING_FACE), UM(UC_BEAMING_FACE), UM(UC_GRINNING_FACE_WITH_SWEAT), UM(UC_ROLLING_LAUGHING), UM(UC_FACE_TEARS_JOY), UM(UC_WINKING_FACE), UM(UC_SMILING_FACE_HALO), UM(UC_SMILING_FACE_HEARTS), UM(UC_SMILING_FACE_HEART_EYES), UM(UC_FACE_BLOWING_KISS), UM(UC_FACE_SAVORING_FOOD), UM(UC_ZANY_FACE), KC_BSPC, KC_HOME, + KC_TAB, UM(UC_HUGGING_FACE), UM(UC_SHUSHING_FACE), UM(UC_THINKING_FACE), UM(UC_FACE_RAISED_EYEBROW), UM(UC_NEUTRAL_FACE), UM(UC_SMIRKING_FACE), UM(UC_FACE_ROLLING_EYES), UM(UC_PENSIVE_FACE), UM(UC_FACE_VOMITING), UM(UC_WOOZY_FACE), UM(UC_PLEADING_FACE), UM(UC_LOUDLY_CRYING_FACE), UM(UC_THUMBSUP), KC_END, + KC_APP, UM(UC_DISAPPOINTED_FACE), UM(UC_FACE_SYMBOLS_MOUTH), UM(UC_SMILING_FACE_HORNS), UM(UC_SKULL), UM(UC_PILE_POO), UM(UC_GHOST), UM(UC_ALIEN_MONSTER), UM(UC_RED_HEART), UM(UC_BOMB), UM(UC_WAVING_HAND), UM(UC_OK_HAND), KC_ENT, KC_PGUP, + KC_LSFT, UM(UC_CLAPPING_HANDS), UM(UC_EYES), UM(UC_MAN_FACEPALMING), UM(UC_TURTLE), UM(UC_SNAKE), UM(UC_SPOUTING_WHALE), UM(UC_DRAGON), UM(UC_TREX), UM(UC_ARGENTINA_A), UM(UC_ARGENTINA_R), UM(UC_THUMBSDOWN), KC_UP, KC_PGDN, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, QK_LEAD, TO(_INDEX), TO(_MAIN), KC_LEFT, KC_DOWN, KC_RGHT ), [_EXT1] = LAYOUT_65_ansi( diff --git a/keyboards/ebastler/e80_1800/info.json b/keyboards/ebastler/e80_1800/info.json index c735adc927d9..dfb669e72e6f 100644 --- a/keyboards/ebastler/e80_1800/info.json +++ b/keyboards/ebastler/e80_1800/info.json @@ -113,7 +113,7 @@ {"matrix": [4, 11], "label": ";", "x": 10.75, "y": 4}, {"matrix": [4, 12], "label": "'", "x": 11.75, "y": 4}, {"matrix": [4, 13], "label": "#", "x": 12.75, "y": 4}, - {"matrix": [4, 14], "label": "Enter", "x": 13.75, "y": 3, "w": 1.25}, + {"matrix": [4, 14], "label": "Enter", "x": 13.75, "y": 4, "w": 1.25}, {"matrix": [4, 15], "label": "4", "x": 15.5, "y": 4}, {"matrix": [4, 16], "label": "5", "x": 16.5, "y": 4}, {"matrix": [4, 17], "label": "6", "x": 17.5, "y": 4}, @@ -452,7 +452,7 @@ {"matrix": [4, 10], "label": "L", "x": 9.75, "y": 4}, {"matrix": [4, 11], "label": ";", "x": 10.75, "y": 4}, {"matrix": [4, 12], "label": "'", "x": 11.75, "y": 4}, - {"matrix": [4, 14], "label": "Enter", "x": 12.75, "y": 3, "w": 2.25}, + {"matrix": [4, 14], "label": "Enter", "x": 12.75, "y": 4, "w": 2.25}, {"matrix": [4, 15], "label": "4", "x": 15.5, "y": 4}, {"matrix": [4, 16], "label": "5", "x": 16.5, "y": 4}, {"matrix": [4, 17], "label": "6", "x": 17.5, "y": 4}, @@ -565,7 +565,7 @@ {"matrix": [4, 10], "label": "L", "x": 9.75, "y": 4}, {"matrix": [4, 11], "label": ";", "x": 10.75, "y": 4}, {"matrix": [4, 12], "label": "'", "x": 11.75, "y": 4}, - {"matrix": [4, 14], "label": "Enter", "x": 12.75, "y": 3, "w": 2.25}, + {"matrix": [4, 14], "label": "Enter", "x": 12.75, "y": 4, "w": 2.25}, {"matrix": [4, 15], "label": "4", "x": 15.5, "y": 4}, {"matrix": [4, 16], "label": "5", "x": 16.5, "y": 4}, {"matrix": [4, 17], "label": "6", "x": 17.5, "y": 4}, diff --git a/keyboards/eggsworks/egg58/config.h b/keyboards/eggsworks/egg58/config.h new file mode 100644 index 000000000000..50d95fae1e5c --- /dev/null +++ b/keyboards/eggsworks/egg58/config.h @@ -0,0 +1,6 @@ +// Copyright 2022-2023 Travis Mick (@tmick0) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#define RGB_MATRIX_LED_COUNT 58 diff --git a/keyboards/eggsworks/egg58/info.json b/keyboards/eggsworks/egg58/info.json new file mode 100644 index 000000000000..14e62cdf59d1 --- /dev/null +++ b/keyboards/eggsworks/egg58/info.json @@ -0,0 +1,172 @@ +{ + "keyboard_name": "egg58", + "manufacturer": "eggsworks", + "url": "https://github.com/eggsworks/egg58", + "maintainer": "tmick0", + "usb": { + "vid": "0x4557", + "pid": "0x3665", + "device_version": "2.1.1" + }, + "features": { + "bootmagic": true, + "extrakey": true, + "mousekey": true, + "rgb_matrix": true + }, + "development_board": "promicro", + "diode_direction": "COL2ROW", + "matrix_pins": { + "rows": ["C6", "D7", "E6", "B4", "B5"], + "cols": ["F6", "F7", "B1", "B3", "B2", "B6"] + }, + "split": { + "enabled": true, + "transport": { + "protocol": "i2c" + }, + "usb_detect": { + "enabled": true + } + }, + "ws2812": { + "pin": "D3" + }, + "rgb_matrix": { + "driver": "WS2812", + "split": true, + "split_count": [29, 29], + "max_brightness": 160, + "animations": { + "gradient_up_down": true, + "gradient_left_right": true, + "breathing": true, + "band_sat": true, + "band_val": true + }, + "layout": [ + { "matrix": [0, 5], "x": 93, "y": 3, "flags": 4 }, + { "matrix": [0, 4], "x": 74, "y": 1, "flags": 4 }, + { "matrix": [0, 3], "x": 56, "y": 0, "flags": 4 }, + { "matrix": [0, 2], "x": 37, "y": 2, "flags": 4 }, + { "matrix": [0, 1], "x": 18, "y": 4, "flags": 4 }, + { "matrix": [0, 0], "x": 0, "y": 12, "flags": 4 }, + { "matrix": [1, 0], "x": 0, "y": 26, "flags": 4 }, + { "matrix": [1, 1], "x": 18, "y": 17, "flags": 4 }, + { "matrix": [1, 2], "x": 37, "y": 15, "flags": 4 }, + { "matrix": [1, 3], "x": 56, "y": 13, "flags": 4 }, + { "matrix": [1, 4], "x": 74, "y": 15, "flags": 4 }, + { "matrix": [1, 5], "x": 93, "y": 17, "flags": 4 }, + { "matrix": [2, 5], "x": 93, "y": 30, "flags": 4 }, + { "matrix": [2, 4], "x": 74, "y": 28, "flags": 4 }, + { "matrix": [2, 3], "x": 56, "y": 26, "flags": 4 }, + { "matrix": [2, 2], "x": 37, "y": 29, "flags": 4 }, + { "matrix": [2, 1], "x": 18, "y": 31, "flags": 4 }, + { "matrix": [2, 0], "x": 0, "y": 39, "flags": 4 }, + { "matrix": [3, 0], "x": 0, "y": 52, "flags": 4 }, + { "matrix": [3, 1], "x": 18, "y": 44, "flags": 4 }, + { "matrix": [3, 2], "x": 37, "y": 42, "flags": 4 }, + { "matrix": [3, 3], "x": 56, "y": 40, "flags": 4 }, + { "matrix": [3, 4], "x": 74, "y": 42, "flags": 4 }, + { "matrix": [3, 5], "x": 93, "y": 44, "flags": 4 }, + { "matrix": [4, 5], "x": 102, "y": 64, "flags": 4 }, + { "matrix": [4, 4], "x": 84, "y": 60, "flags": 4} , + { "matrix": [4, 3], "x": 56, "y": 53, "flags": 4 }, + { "matrix": [4, 2], "x": 37, "y": 56, "flags": 4 }, + { "matrix": [4, 1], "x": 18, "y": 58, "flags": 4 }, + { "matrix": [5, 5], "x": 149, "y": 3, "flags": 4 }, + { "matrix": [5, 4], "x": 168, "y": 1, "flags": 4 }, + { "matrix": [5, 3], "x": 186, "y": 0, "flags": 4 }, + { "matrix": [5, 2], "x": 205, "y": 2, "flags": 4 }, + { "matrix": [5, 1], "x": 224, "y": 4, "flags": 4 }, + { "matrix": [5, 0], "x": 242, "y": 12, "flags": 4 }, + { "matrix": [6, 0], "x": 242, "y": 26, "flags": 4 }, + { "matrix": [6, 1], "x": 224, "y": 17, "flags": 4 }, + { "matrix": [6, 2], "x": 205, "y": 15, "flags": 4 }, + { "matrix": [6, 3], "x": 186, "y": 13, "flags": 4 }, + { "matrix": [6, 4], "x": 168, "y": 15, "flags": 4 }, + { "matrix": [6, 5], "x": 149, "y": 17, "flags": 4 }, + { "matrix": [7, 5], "x": 149, "y": 30, "flags": 4 }, + { "matrix": [7, 4], "x": 168, "y": 28, "flags": 4 }, + { "matrix": [7, 3], "x": 186, "y": 26, "flags": 4 }, + { "matrix": [7, 2], "x": 205, "y": 29, "flags": 4 }, + { "matrix": [7, 1], "x": 224, "y": 31, "flags": 4 }, + { "matrix": [7, 0], "x": 242, "y": 39, "flags": 4 }, + { "matrix": [8, 0], "x": 242, "y": 52, "flags": 4 }, + { "matrix": [8, 1], "x": 224, "y": 44, "flags": 4 }, + { "matrix": [8, 2], "x": 205, "y": 42, "flags": 4 }, + { "matrix": [8, 3], "x": 186, "y": 40, "flags": 4 }, + { "matrix": [8, 4], "x": 168, "y": 42, "flags": 4 }, + { "matrix": [8, 5], "x": 149, "y": 44, "flags": 4 }, + { "matrix": [9, 5], "x": 140, "y": 64, "flags": 4 }, + { "matrix": [9, 4], "x": 158, "y": 60, "flags": 4 }, + { "matrix": [9, 3], "x": 186, "y": 53, "flags": 4 }, + { "matrix": [9, 2], "x": 205, "y": 56, "flags": 4 }, + { "matrix": [9, 1], "x": 224, "y": 58, "flags": 4 } + ] + }, + "layouts": { + "LAYOUT": { + "layout": [ + { "matrix": [0, 0], "x": 0, "y": 0.93 }, + { "matrix": [0, 1], "x": 1, "y": 0.32 }, + { "matrix": [0, 2], "x": 2, "y": 0.18 }, + { "matrix": [0, 3], "x": 3, "y": 0 }, + { "matrix": [0, 4], "x": 4, "y": 0.14 }, + { "matrix": [0, 5], "x": 5, "y": 0.28 }, + { "matrix": [5, 5], "x": 8, "y": 0.28 }, + { "matrix": [5, 4], "x": 9, "y": 0.14 }, + { "matrix": [5, 3], "x": 10, "y": 0 }, + { "matrix": [5, 2], "x": 11, "y": 0.18 }, + { "matrix": [5, 1], "x": 12, "y": 0.32 }, + { "matrix": [5, 0], "x": 13, "y": 0.93 }, + { "matrix": [1, 0], "x": 0, "y": 1.93 }, + { "matrix": [1, 1], "x": 1, "y": 1.32 }, + { "matrix": [1, 2], "x": 2, "y": 1.18 }, + { "matrix": [1, 3], "x": 3, "y": 1 }, + { "matrix": [1, 4], "x": 4, "y": 1.14 }, + { "matrix": [1, 5], "x": 5, "y": 1.28 }, + { "matrix": [6, 5], "x": 8, "y": 1.28 }, + { "matrix": [6, 4], "x": 9, "y": 1.14 }, + { "matrix": [6, 3], "x": 10, "y": 1 }, + { "matrix": [6, 2], "x": 11, "y": 1.18 }, + { "matrix": [6, 1], "x": 12, "y": 1.32 }, + { "matrix": [6, 0], "x": 13, "y": 1.93 }, + { "matrix": [2, 0], "x": 0, "y": 2.93 }, + { "matrix": [2, 1], "x": 1, "y": 2.32 }, + { "matrix": [2, 2], "x": 2, "y": 2.18 }, + { "matrix": [2, 3], "x": 3, "y": 2 }, + { "matrix": [2, 4], "x": 4, "y": 2.14 }, + { "matrix": [2, 5], "x": 5, "y": 2.28 }, + { "matrix": [7, 5], "x": 8, "y": 2.28 }, + { "matrix": [7, 4], "x": 9, "y": 2.14 }, + { "matrix": [7, 3], "x": 10, "y": 2 }, + { "matrix": [7, 2], "x": 11, "y": 2.18 }, + { "matrix": [7, 1], "x": 12, "y": 2.32 }, + { "matrix": [7, 0], "x": 13, "y": 2.93 }, + { "matrix": [3, 0], "x": 0, "y": 3.93 }, + { "matrix": [3, 1], "x": 1, "y": 3.32 }, + { "matrix": [3, 2], "x": 2, "y": 3.18 }, + { "matrix": [3, 3], "x": 3, "y": 3 }, + { "matrix": [3, 4], "x": 4, "y": 3.14 }, + { "matrix": [3, 5], "x": 5, "y": 3.28 }, + { "matrix": [8, 5], "x": 8, "y": 3.28 }, + { "matrix": [8, 4], "x": 9, "y": 3.14 }, + { "matrix": [8, 3], "x": 10, "y": 3 }, + { "matrix": [8, 2], "x": 11, "y": 3.18 }, + { "matrix": [8, 1], "x": 12, "y": 3.32 }, + { "matrix": [8, 0], "x": 13, "y": 3.93 }, + { "matrix": [4, 1], "x": 1, "y": 4.32 }, + { "matrix": [4, 2], "x": 2, "y": 4.18 }, + { "matrix": [4, 3], "x": 3, "y": 4 }, + { "matrix": [4, 4], "x": 4.5, "y": 4.5, "h": 1.5 }, + { "matrix": [4, 5], "x": 5.5, "y": 4.75, "h": 1.5 }, + { "matrix": [9, 5], "x": 7.5, "y": 4.75, "h": 1.5 }, + { "matrix": [9, 4], "x": 8.5, "y": 4.5, "h": 1.5 }, + { "matrix": [9, 3], "x": 10, "y": 4 }, + { "matrix": [9, 2], "x": 11, "y": 4.18 }, + { "matrix": [9, 1], "x": 12, "y": 4.32 } + ] + } + } +} diff --git a/keyboards/eggsworks/egg58/keymaps/default/keymap.c b/keyboards/eggsworks/egg58/keymaps/default/keymap.c new file mode 100644 index 000000000000..482a34c1291e --- /dev/null +++ b/keyboards/eggsworks/egg58/keymaps/default/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2022-2023 Travis Mick (@tmick0) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +enum layer_names { + _BASE, + _FN +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[_BASE] = LAYOUT( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_EQL, + KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSPC, + KC_LGUI, KC_LALT, OSL(1), MO(1), KC_SPC, KC_ENT, MO(1), KC_LBRC, KC_RBRC, KC_BSLS +), + +[_FN] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, + KC_TRNS, KC_PGUP, KC_UP, KC_PGDN, KC_TRNS, KC_VOLU, KC_TRNS, KC_TRNS, KC_INS, KC_TRNS, KC_PSCR, KC_F12, + KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_VOLD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_HOME, KC_TRNS, KC_END, KC_TRNS, KC_MUTE, KC_TRNS, KC_TRNS, RGB_HUI, RGB_SAI, RGB_VAI, KC_DEL, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_SPI, RGB_MOD, RGB_TOG +) +}; diff --git a/keyboards/eggsworks/egg58/keymaps/via/keymap.c b/keyboards/eggsworks/egg58/keymaps/via/keymap.c new file mode 100644 index 000000000000..482a34c1291e --- /dev/null +++ b/keyboards/eggsworks/egg58/keymaps/via/keymap.c @@ -0,0 +1,27 @@ +// Copyright 2022-2023 Travis Mick (@tmick0) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +enum layer_names { + _BASE, + _FN +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { +[_BASE] = LAYOUT( + KC_GRV, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_MINS, + KC_TAB, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_EQL, + KC_LSFT, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + KC_LCTL, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_BSPC, + KC_LGUI, KC_LALT, OSL(1), MO(1), KC_SPC, KC_ENT, MO(1), KC_LBRC, KC_RBRC, KC_BSLS +), + +[_FN] = LAYOUT( + KC_ESC, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_F11, + KC_TRNS, KC_PGUP, KC_UP, KC_PGDN, KC_TRNS, KC_VOLU, KC_TRNS, KC_TRNS, KC_INS, KC_TRNS, KC_PSCR, KC_F12, + KC_TRNS, KC_LEFT, KC_DOWN, KC_RGHT, KC_TRNS, KC_VOLD, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, + KC_TRNS, KC_HOME, KC_TRNS, KC_END, KC_TRNS, KC_MUTE, KC_TRNS, KC_TRNS, RGB_HUI, RGB_SAI, RGB_VAI, KC_DEL, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, RGB_SPI, RGB_MOD, RGB_TOG +) +}; diff --git a/keyboards/eggsworks/egg58/keymaps/via/rules.mk b/keyboards/eggsworks/egg58/keymaps/via/rules.mk new file mode 100644 index 000000000000..ca9fed0e6b53 --- /dev/null +++ b/keyboards/eggsworks/egg58/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +LTO_ENABLE = yes +VIA_ENABLE = yes diff --git a/keyboards/eggsworks/egg58/readme.md b/keyboards/eggsworks/egg58/readme.md new file mode 100644 index 000000000000..fe9b1819eee1 --- /dev/null +++ b/keyboards/eggsworks/egg58/readme.md @@ -0,0 +1,23 @@ +# egg58 + +* Keyboard Maintainer: [Travis Mick](https://github.com/tmick0) +* Hardware Supported: egg58 (v1-v2.x) PCB, with Pro Micro or compatible MCU +* Hardware Availability: https://eggs.works/ or https://github.com/eggsworks/egg58 + +Make example for this keyboard (after setting up your build environment): + + make eggsworks/egg58:default + +Flashing example for this keyboard: + + make eggsworks/egg58: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 diff --git a/keyboards/eggsworks/egg58/rules.mk b/keyboards/eggsworks/egg58/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/eggsworks/egg58/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/elephant42/config.h b/keyboards/elephant42/config.h index dc1f568fc4c5..ebc0b1049745 100644 --- a/keyboards/elephant42/config.h +++ b/keyboards/elephant42/config.h @@ -17,7 +17,6 @@ along with this program. If not, see . #pragma once -# define RGBLED_SPLIT { 27, 27 } # define RGBLED_NUM 54 // backlight x42 + underglow x12 # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 @@ -36,7 +35,7 @@ along with this program. If not, see . #ifdef RGB_MATRIX_ENABLE # define SPLIT_TRANSPORT_MIRROR # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 27, 27 } # define RGB_MATRIX_MAXIMUM_BRIGHTNESS 170 # define RGB_MATRIX_HUE_STEP RGBLIGHT_HUE_STEP # define RGB_MATRIX_SAT_STEP RGBLIGHT_SAT_STEP diff --git a/keyboards/elephant42/info.json b/keyboards/elephant42/info.json index 8c4440805506..bcfc374531c2 100644 --- a/keyboards/elephant42/info.json +++ b/keyboards/elephant42/info.json @@ -12,7 +12,8 @@ "driver": "WS2812" }, "rgblight": { - "max_brightness": 170 + "max_brightness": 170, + "split_count": [27, 27] }, "matrix_pins": { "cols": ["F4", "F5", "F6", "F7", "B1", "B3"], diff --git a/keyboards/ergoslab/rev1/config.h b/keyboards/ergoslab/rev1/config.h index 414de0ed1580..7846e281545e 100644 --- a/keyboards/ergoslab/rev1/config.h +++ b/keyboards/ergoslab/rev1/config.h @@ -18,10 +18,6 @@ along with this program. If not, see . #pragma once #define RGBLED_NUM 2 // Number of LEDs -// FIXME this following line should enable our layer status LEDs to work on both -// sides without need to wire them into a chain. It doesn't though. Uncommenting -// means the slave side of the keyboard stops working (and the LEDs don't work). -// #define RGBLED_SPLIT {1,1} /* * Feature disable options diff --git a/keyboards/flxlb/zplit/config.h b/keyboards/flxlb/zplit/config.h index 55edfade8275..9c1d35d13641 100644 --- a/keyboards/flxlb/zplit/config.h +++ b/keyboards/flxlb/zplit/config.h @@ -31,7 +31,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 16 #define RGBLIGHT_LED_MAP { 0, 1, 2, 3, 4, 5, 6, 7, 15, 14, 13, 12, 11, 10, 9, 8} -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_SPLIT #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/flxlb/zplit/info.json b/keyboards/flxlb/zplit/info.json index a2c27492cf49..dbd075a2e482 100644 --- a/keyboards/flxlb/zplit/info.json +++ b/keyboards/flxlb/zplit/info.json @@ -18,6 +18,9 @@ {"pin_a": "B0", "pin_b": "D2"} ] }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/gh60/satan/keymaps/addcninblue/rules.mk b/keyboards/gh60/satan/keymaps/addcninblue/rules.mk index b8c05a5984ca..fe07e497f9c2 100644 --- a/keyboards/gh60/satan/keymaps/addcninblue/rules.mk +++ b/keyboards/gh60/satan/keymaps/addcninblue/rules.mk @@ -12,7 +12,7 @@ NKRO_ENABLE = yes # Nkey Rollover - if this doesn't work, see here: htt BACKLIGHT_ENABLE = yes # Enable keyboard backlight functionality MIDI_ENABLE = no # MIDI controls AUDIO_ENABLE = no # Audio output on port C6 -UNICODEMAP_ENABLE = no # This allows sending unicode symbols using X() in your keymap. +UNICODEMAP_ENABLE = no UNICODE_ENABLE = no # Unicode UCIS_ENABLE = no # Keep in mind that not all will work (See WinCompose for details on Windows). BLUETOOTH_ENABLE = no # Enable Bluetooth with the Adafruit EZ-Key HID diff --git a/keyboards/giabalanai/config.h b/keyboards/giabalanai/config.h index aa0095aebd49..fda301537fb9 100644 --- a/keyboards/giabalanai/config.h +++ b/keyboards/giabalanai/config.h @@ -36,11 +36,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE # define RGBLED_NUM 123 -// Do not define "RGBLED_SPLIT" since somehow it doesn't work well yet. -// Even thhough "#define RGBLED_SPLIT { 60, 63 }" was set, LEDs on the sub keyboad side didn't turn on. -// Not sure but rgblight_sethsv_at() might not support RGBLED_SPLIT yet. -// Instead, LED data is tranferred from right side to the left via TRRS cable. - # define RGBLIGHT_LAYERS // By default, LEDs of the buttons which are pressed turn on. diff --git a/keyboards/giabalanai/giabalanai.c b/keyboards/giabalanai/giabalanai.c deleted file mode 100644 index 6f8e359479a6..000000000000 --- a/keyboards/giabalanai/giabalanai.c +++ /dev/null @@ -1,255 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ - -#include "giabalanai.h" - -// the velocity difference from the velocity of the root note. -#define UNISON_VELOCITY_OFFSET 30 - -#ifdef RGBLIGHT_ENABLE -# define NO_LED 255 -/* Conversion map from keylocation (MATRIX_ROWS x2(split) x MATRIX_COLS) to led IDs. - led IDs are the number starts "0" from upper left corner of left side, - enumerated from left to right, from top to bottom. - Then emumeration follows to the right side, starting from "60". - - Note that the conversion from physical LED serial alighment to - the led IDs is done with RGBLIGHT_LED_MAP beforehand. */ - -# ifdef GIABARINAIX2 -const uint8_t PROGMEM convert_key_to_led[] = -{ - 0, 12, 24, 36, 48, 11, 23, 35, 47, 59, - 1, 13, 25, 37, 49, 10, 22, 34, 46, 58, - 2, 14, 26, 38, 50, 9, 21, 33, 45, 57, - 3, 15, 27, 39, 51, 8, 20, 32, 44, 56, - 4, 16, 28, 40, 52, 7, 19, 31, 43, 55, - 5, 17, 29, 41, 53, 6, 18, 30, 42, 54, - 119, 107, 95, 83, 71, 108, 96, 84, 72, 60, - 118, 106, 94, 82, 70, 109, 97, 85, 73, 61, - 117, 105, 93, 81, 69, 110, 98, 86, 74, 62, - 116, 104, 92, 80, 68, 111, 99, 87, 75, 63, - 115, 103, 91, 79, 67, 112, 100, 88, 76, 64, - 114, 102, 90, 78, 66, 113, 101, 89, 77, 65 -}; - -# else -const uint8_t PROGMEM convert_key_to_led[] = -{ -0, 12, 24, 36, 48, 11, 23, 35, 47, 59, -1, 13, 25, 37, 49, 10, 22, 34, 46, 58, -2, 14, 26, 38, 50, 9, 21, 33, 45, 57, -3, 15, 27, 39, 51, 8, 20, 32, 44, 56, -4, 16, 28, 40, 52, 7, 19, 31, 43, 55, -5, 17, 29, 41, 53, 6, 18, 30, 42, 54, - -85, 86, 87, 88, 89, 90, 91, NO_LED, NO_LED, NO_LED, -98, 99, 100, 101, 102, 103, 104, NO_LED, NO_LED, NO_LED, -NO_LED, 111, 112, 113, 114, 115, 116, NO_LED, NO_LED, NO_LED, -NO_LED, 97, 96, 95, 94, 93, 92, NO_LED, NO_LED, NO_LED, -NO_LED, 110, 109, 108, 107, 106, 105, NO_LED, NO_LED, NO_LED, -NO_LED, 122, 121, 120, 119, 118, 117, NO_LED, NO_LED, NO_LED -}; - -/* Top 2 rows on the right side (LED:60-84) are - duplicates of the bottom 2 rows (LED:85-122). - LED:97 = Encoder, - LED:110 don't have a duplicate on the top row, - LED:72 is used when r20 is pressed (not a duplicate) */ -const uint8_t PROGMEM convert_key_to_led2[] = -{ -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, - -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -60, 61, 62, 63, 64, 65, 66, NO_LED, NO_LED, NO_LED, -72, 73, 74, 75, 76, 77, 78, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, NO_LED, -NO_LED, NO_LED, 71, 70, 69, 68, 67, NO_LED, NO_LED, NO_LED, -NO_LED, 84, 83, 82, 81, 80, 79, NO_LED, NO_LED, NO_LED -}; -# endif -#endif // RGBLIGHT_ENABLE - -#ifdef RGB_MATRIX_ENABLE - -led_config_t g_led_config = { - { - { 74, 75, 98, 99, 122, 63, 86, 87, 110, 111 }, - { 73, 76, 97, 100, 121, 64, 85, 88, 109, 112 }, - { 72, 77, 96, 101, 120, 65, 84, 89, 108, 113 }, - { 71, 78, 95, 102, 119, 66, 83, 90, 107, 114 }, - { 70, 79, 94, 103, 118, 67, 82, 91, 106, 115 }, - { 69, 80, 93, 104, 117, 68, 81, 92, 105, 116 }, - { 26, 27, 28, 29, 30, 31, 32, NO_LED, NO_LED, NO_LED }, - { 50, 49, 48, 47, 46, 45, 44, NO_LED, NO_LED, NO_LED }, - { 25, 51, 52, 53, 54, 55, 56, NO_LED, NO_LED, NO_LED }, - { NO_LED, 12, 37, 36, 35, 34, 33, NO_LED, NO_LED, NO_LED }, - { NO_LED, 38, 39, 40, 41, 42, 43, NO_LED, NO_LED, NO_LED }, - { NO_LED, 62, 61, 60, 59, 58, 57, NO_LED, NO_LED, NO_LED } - }, { - { 120, 0 }, { 128, 0 }, { 136, 0 }, { 144, 0 }, { 152, 0 }, { 160, 0 }, { 168, 0 }, { 176, 0 }, { 184, 0 }, { 192, 0 }, { 200, 0 }, { 208, 0 }, - { 224, 32 }, - { 212, 16 }, { 204, 16 }, { 196, 16 }, { 188, 16 }, { 180, 16 }, { 172, 16 }, { 164, 16 }, { 156, 16 }, { 148, 16 }, { 140, 16 }, { 132, 16 }, { 124, 16 }, { 116, 16 }, - { 120, 32 }, { 128, 32 }, { 136, 32 }, { 144, 32 }, { 152, 32 }, { 160, 32 }, { 168, 32 }, { 176, 32 }, { 184, 32 }, { 192, 32 }, { 200, 32 }, { 208, 32 }, - { 212, 48 }, { 204, 48 }, { 196, 48 }, { 188, 48 }, { 180, 48 }, { 172, 48 }, { 164, 48 }, { 156, 48 }, { 148, 48 }, { 140, 48 }, { 132, 48 }, { 124, 48 }, { 116, 48 }, - { 120, 64 }, { 128, 64 }, { 136, 64 }, { 144, 64 }, { 152, 64 }, { 160, 64 }, { 168, 64 }, { 176, 64 }, { 184, 64 }, { 192, 64 }, { 200, 64 }, { 208, 64 }, - - { 88, 0 }, { 80, 0 }, { 72, 0 }, { 64, 0 }, { 56, 0 }, { 48, 0 }, { 40, 0 }, { 32, 0 }, { 24, 0 }, { 16, 0 }, { 8, 0 }, { 0, 0 }, - { 4, 16 }, { 12, 16 }, { 20, 16 }, { 28, 16 }, { 36, 16 }, { 44, 16 }, { 52, 16 }, { 60, 16 }, { 68, 16 }, { 76, 16 }, { 84, 16 }, { 92, 16 }, - { 96, 32 }, { 88, 32 }, { 80, 32 }, { 72, 32 }, { 64, 32 }, { 56, 32 }, { 48, 32 }, { 40, 32 }, { 32, 32 }, { 24, 32 }, { 16, 32 }, { 8, 32 }, - { 12, 48 }, { 20, 48 }, { 28, 48 }, { 36, 48 }, { 44, 48 }, { 52, 48 }, { 60, 48 }, { 68, 48 }, { 76, 48 }, { 84, 48 }, { 92, 48 }, { 100, 48 }, - { 104, 64 }, { 96, 64 }, { 88, 64 }, { 80, 64 }, { 72, 64 }, { 64, 64 }, { 56, 64 }, { 48, 64 }, { 40, 64 }, { 32, 64 }, { 24, 64 }, { 16, 64 } - }, { - 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, 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, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, - } -}; - -// const uint8_t PROGMEM convert_led_location2number[] = { -// 74, 73, 72, 71, 70, 69, 68, 67, 66, 65, 64, 63, -// 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, -// 98, 97, 96, 95, 94, 93, 92, 91, 90, 89, 88, 87, -// 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, -// 122, 121, 120, 119, 118, 117, 116, 115, 114, 113, 112, 111, -// -// 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -// 25, 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, -// 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 12, -// 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40, 39, 38, -// 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62 -// }; -#endif - -void my_process_midi4Bass(uint8_t channel, keyrecord_t *record, - uint8_t *chord_status, uint8_t chord, uint16_t root_note, bool is_single_bass) { - uint8_t velocity = midi_config.velocity; - if (record->event.pressed) { - if (chord_status[chord] == MIDI_INVALID_NOTE) { - uint8_t note = midi_compute_note(root_note); - if (is_single_bass) { - midi_send_noteon(&midi_device, channel, note, velocity); - } else { - midi_send_noteon(&midi_device, channel, note, velocity); - midi_send_noteon(&midi_device, channel, note + 12, velocity); // +1 Octave - } - dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity); - chord_status[chord] = note; // store root_note status. - } - } else { - uint8_t note = chord_status[chord]; - if (note != MIDI_INVALID_NOTE) { - if (is_single_bass) { - midi_send_noteoff(&midi_device, channel, note, velocity); - } else { - midi_send_noteoff(&midi_device, channel, note, velocity); - midi_send_noteoff(&midi_device, channel, note + 12, velocity); // +1 Octave - } - dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity); - } - chord_status[chord] = MIDI_INVALID_NOTE; - } -} - -void my_process_midi4TriadChords(uint8_t channel, keyrecord_t *record, - uint8_t *chord_status, uint8_t chord, uint16_t root_note, - int8_t offset1, int8_t offset2, int8_t offset3) { - uint8_t velocity = midi_config.velocity; - if (record->event.pressed) { - if (chord_status[chord] == MIDI_INVALID_NOTE) { - uint8_t note = midi_compute_note(root_note); - midi_send_noteon(&midi_device, channel, note + offset1, velocity); - midi_send_noteon(&midi_device, channel, note + offset2, velocity); - midi_send_noteon(&midi_device, channel, note + offset3, velocity); - dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity); - chord_status[chord] = note; // store root_note status. - } - } else { - uint8_t note = chord_status[chord]; - if (note != MIDI_INVALID_NOTE) { - midi_send_noteoff(&midi_device, channel, note + offset1, velocity); - midi_send_noteoff(&midi_device, channel, note + offset2, velocity); - midi_send_noteoff(&midi_device, channel, note + offset3, velocity); - dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity); - } - chord_status[chord] = MIDI_INVALID_NOTE; - } -} - -void my_process_midi(uint8_t channel, uint16_t keycode, keyrecord_t *record, uint8_t *my_tone_status, int8_t offset, bool melody_unison_suppress) { - - uint8_t tone = keycode - MIDI_TONE_MIN; - - uint8_t melody_unison_velocity; - if (melody_unison_suppress) { - if (midi_config.velocity > UNISON_VELOCITY_OFFSET){ - melody_unison_velocity = midi_config.velocity - UNISON_VELOCITY_OFFSET; - } else { - melody_unison_velocity = 0; - } - } else { - melody_unison_velocity = midi_config.velocity; - } - - if (record->event.pressed) { - if (my_tone_status[tone] == MIDI_INVALID_NOTE) { - uint8_t note = midi_compute_note(keycode); - midi_send_noteon(&midi_device, channel, note + offset, melody_unison_velocity); - dprintf("midi noteon channel:%d note:%d tone:%d velocity:%d\n", channel, note, tone, melody_unison_velocity); - my_tone_status[tone] = note; // store root_note status. - } - } else { - uint8_t note = my_tone_status[tone]; - if (note != MIDI_INVALID_NOTE) { - midi_send_noteoff(&midi_device, channel, note + offset, melody_unison_velocity); - dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, melody_unison_velocity); - } - my_tone_status[tone] = MIDI_INVALID_NOTE; - } -} - -#ifdef RGBLIGHT_ENABLE -void keylight_manager(keyrecord_t *record, uint8_t hue, uint8_t sat, uint8_t val, uint8_t keylocation) { - if (keylocation == NO_LED) { - return; // do nothing. -# ifdef CONSOLE_ENABLE - uprintf("keylight_manager, NO_LED\n"); -# endif - } - - if (record->event.pressed) { - rgblight_sethsv_at(hue, sat, val, keylocation); - } else { - rgblight_sethsv_at(HSV_BLACK, keylocation); - } -} - -#endif // RGBLIGHT_ENABLE - diff --git a/keyboards/giabalanai/giabalanai.h b/keyboards/giabalanai/giabalanai.h deleted file mode 100644 index 199dac37d9ed..000000000000 --- a/keyboards/giabalanai/giabalanai.h +++ /dev/null @@ -1,68 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -#define _________________QWERTY_L1_________________ KC_Q, KC_W, KC_E, KC_R, KC_T -#define _________________QWERTY_L2_________________ KC_A, KC_S, KC_D, KC_F, KC_G -#define _________________QWERTY_L3_________________ KC_Z, KC_X, KC_C, KC_V, KC_B - -#define _________________QWERTY_R1_________________ KC_Y, KC_U, KC_I, KC_O, KC_P -#define _________________QWERTY_R2_________________ KC_H, KC_J, KC_K, KC_L, KC_SCLN -#define _________________QWERTY_R3_________________ KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH - -#define _________________COLEMAK_L1________________ KC_Q, KC_W, KC_F, KC_P, KC_G -#define _________________COLEMAK_L2________________ KC_A, KC_R, KC_S, KC_T, KC_D -#define _________________COLEMAK_L3________________ KC_Z, KC_X, KC_C, KC_V, KC_B - -#define _________________COLEMAK_R1________________ KC_J, KC_L, KC_U, KC_Y, KC_SCLN -#define _________________COLEMAK_R2________________ KC_H, KC_N, KC_E, KC_I, KC_O -#define _________________COLEMAK_R3________________ KC_K, KC_M, KC_COMM, KC_DOT, KC_SLSH - -#define _________________NUMBER_L__________________ KC_1, KC_2, KC_3, KC_4, KC_5 -#define _________________NUMBER_R__________________ KC_6, KC_7, KC_8, KC_9, KC_0 - -#define _________________FUNC__L___________________ KC_F1, KC_F2, KC_F3, KC_F4, KC_F5 -#define _________________FUNC__R___________________ KC_F6, KC_F7, KC_F8, KC_F9, KC_F10 - -#ifdef RGBLIGHT_ENABLE - -extern const uint8_t PROGMEM convert_key_to_led[]; -# ifndef GIABARINAIX2 -extern const uint8_t PROGMEM convert_key_to_led2[]; -# endif -#endif // RGBLIGHT_ENABLE - -// #ifdef RGB_MATRIX_ENABLE -// extern const uint8_t PROGMEM convert_led_location2number[]; -// #endif - -extern MidiDevice midi_device; -void my_process_midi4Bass(uint8_t channel, keyrecord_t *record, - uint8_t *chord_status, uint8_t chord, uint16_t root_note, bool is_single_bass); - -void my_process_midi4TriadChords(uint8_t channel, keyrecord_t *record, - uint8_t *chord_status, uint8_t chord, uint16_t root_note, - int8_t offset1, int8_t offset2, int8_t offset3); - -void my_process_midi(uint8_t channel, uint16_t keycode, keyrecord_t *record, uint8_t *my_tone_status, int8_t offset, bool melody_unison_suppress); - - -#ifdef RGBLIGHT_ENABLE -void keylight_manager(keyrecord_t *record, uint8_t hue, uint8_t sat, uint8_t val, uint8_t keylocation); -#endif // RGBLIGHT_ENABLE diff --git a/keyboards/giabalanai/info.json b/keyboards/giabalanai/info.json deleted file mode 100644 index 7c2fa72047e7..000000000000 --- a/keyboards/giabalanai/info.json +++ /dev/null @@ -1,305 +0,0 @@ -{ - "keyboard_name": "giabalanai", - "manufacturer": "3araht", - "url": "https://github.com/3araht", - "maintainer": "3araht", - "usb": { - "vid": "0xFEED", - "pid": "0xF4B0", - "device_version": "0.0.1" - }, - "rgb_matrix": { - "driver": "WS2812" - }, - "rgblight": { - "max_brightness": 80 - }, - "matrix_pins": { - "cols": ["B1", "F7", "F6", "F5", "F4", "B3", "B2", "B6", "D0", "D1"], - "rows": ["B5", "B4", "E6", "D7", "C6", "D4"] - }, - "diode_direction": "COL2ROW", - "features": { - "midi": true, - "extrakey": true, - "encoder": true, - "bootmagic": false, - "console": false, - "mousekey": false, - "nkro": false, - "rgblight": false, - "audio": false - }, - "encoder": { - "rotary": [] - }, - "ws2812": { - "pin": "D3" - }, - "split": { - "enabled": true, - "soft_serial_pin": "D2", - "encoder": { - "right": { - "rotary": [ - {"pin_a": "B4", "pin_b": "B6"} - ] - } - }, - "matrix_pins": { - "right": { - "cols": ["F4", "F5", "F6", "F7", "B1", "B3", "B2", "C7", "B7", "F1"], - "rows": ["D1", "D0", "D4", "C6", "D7", "E6"] - } - } - }, - "processor": "atmega32u4", - "bootloader": "caterina", - "layouts": { - "LAYOUT": { - "layout": [ - {"matrix": [0, 0], "x": 0, "y": 0}, - {"matrix": [1, 0], "x": 1, "y": 0}, - {"matrix": [2, 0], "x": 2, "y": 0}, - {"matrix": [3, 0], "x": 3, "y": 0}, - {"matrix": [4, 0], "x": 4, "y": 0}, - {"matrix": [5, 0], "x": 5, "y": 0}, - {"matrix": [5, 5], "x": 6, "y": 0}, - {"matrix": [4, 5], "x": 7, "y": 0}, - {"matrix": [3, 5], "x": 8, "y": 0}, - {"matrix": [2, 5], "x": 9, "y": 0}, - {"matrix": [1, 5], "x": 10, "y": 0}, - {"matrix": [0, 5], "x": 11, "y": 0}, - - {"matrix": [0, 1], "x": 0.5, "y": 1}, - {"matrix": [1, 1], "x": 1.5, "y": 1}, - {"matrix": [2, 1], "x": 2.5, "y": 1}, - {"matrix": [3, 1], "x": 3.5, "y": 1}, - {"matrix": [4, 1], "x": 4.5, "y": 1}, - {"matrix": [5, 1], "x": 5.5, "y": 1}, - {"matrix": [5, 6], "x": 6.5, "y": 1}, - {"matrix": [4, 6], "x": 7.5, "y": 1}, - {"matrix": [3, 6], "x": 8.5, "y": 1}, - {"matrix": [2, 6], "x": 9.5, "y": 1}, - {"matrix": [1, 6], "x": 10.5, "y": 1}, - {"matrix": [0, 6], "x": 11.5, "y": 1}, - - {"matrix": [0, 2], "x": 14.5, "y": 1}, - - {"matrix": [1, 2], "x": 1, "y": 2}, - {"matrix": [2, 2], "x": 2, "y": 2}, - {"matrix": [3, 2], "x": 3, "y": 2}, - {"matrix": [4, 2], "x": 4, "y": 2}, - {"matrix": [5, 2], "x": 5, "y": 2}, - {"matrix": [5, 7], "x": 6, "y": 2}, - {"matrix": [4, 7], "x": 7, "y": 2}, - {"matrix": [3, 7], "x": 8, "y": 2}, - {"matrix": [2, 7], "x": 9, "y": 2}, - {"matrix": [1, 7], "x": 10, "y": 2}, - {"matrix": [0, 7], "x": 11, "y": 2}, - {"matrix": [0, 3], "x": 12, "y": 2}, - - {"matrix": [1, 3], "x": 15, "y": 2}, - {"matrix": [2, 3], "x": 16, "y": 2}, - {"matrix": [3, 3], "x": 17, "y": 2}, - {"matrix": [4, 3], "x": 18, "y": 2}, - {"matrix": [5, 3], "x": 19, "y": 2}, - {"matrix": [5, 8], "x": 20, "y": 2}, - {"matrix": [4, 8], "x": 21, "y": 2}, - {"matrix": [3, 8], "x": 22, "y": 2}, - {"matrix": [2, 8], "x": 23, "y": 2}, - {"matrix": [1, 8], "x": 24, "y": 2}, - {"matrix": [0, 8], "x": 25, "y": 2}, - {"matrix": [0, 4], "x": 26, "y": 2}, - - {"matrix": [1, 4], "x": 27.5, "y": 2}, - - {"matrix": [2, 4], "x": 1.5, "y": 3}, - {"matrix": [3, 4], "x": 2.5, "y": 3}, - {"matrix": [4, 4], "x": 3.5, "y": 3}, - {"matrix": [5, 4], "x": 4.5, "y": 3}, - {"matrix": [5, 9], "x": 5.5, "y": 3}, - {"matrix": [4, 9], "x": 6.5, "y": 3}, - {"matrix": [3, 9], "x": 7.5, "y": 3}, - {"matrix": [2, 9], "x": 8.5, "y": 3}, - {"matrix": [1, 9], "x": 9.5, "y": 3}, - {"matrix": [0, 9], "x": 10.5, "y": 3}, - {"matrix": [8, 0], "x": 11.5, "y": 3}, - {"matrix": [6, 0], "x": 12.5, "y": 3}, - - {"matrix": [6, 1], "x": 14.5, "y": 3}, - {"matrix": [6, 2], "x": 15.5, "y": 3}, - {"matrix": [6, 3], "x": 16.5, "y": 3}, - {"matrix": [6, 4], "x": 17.5, "y": 3}, - {"matrix": [6, 5], "x": 18.5, "y": 3}, - {"matrix": [6, 6], "x": 19.5, "y": 3}, - {"matrix": [9, 6], "x": 20.5, "y": 3}, - {"matrix": [9, 5], "x": 21.5, "y": 3}, - {"matrix": [9, 4], "x": 22.5, "y": 3}, - {"matrix": [9, 3], "x": 23.5, "y": 3}, - {"matrix": [9, 2], "x": 24.5, "y": 3}, - {"matrix": [9, 1], "x": 25.5, "y": 3}, - {"matrix": [7, 0], "x": 26.5, "y": 3}, - - {"matrix": [7, 1], "x": 2, "y": 4}, - {"matrix": [7, 2], "x": 3, "y": 4}, - {"matrix": [7, 3], "x": 4, "y": 4}, - {"matrix": [7, 4], "x": 5, "y": 4}, - {"matrix": [7, 5], "x": 6, "y": 4}, - {"matrix": [7, 6], "x": 7, "y": 4}, - {"matrix": [10, 6], "x": 8, "y": 4}, - {"matrix": [10, 5], "x": 9, "y": 4}, - {"matrix": [10, 4], "x": 10, "y": 4}, - {"matrix": [10, 3], "x": 11, "y": 4}, - {"matrix": [10, 2], "x": 12, "y": 4}, - {"matrix": [10, 1], "x": 13, "y": 4}, - - {"matrix": [8, 1], "x": 15, "y": 4}, - {"matrix": [8, 2], "x": 16, "y": 4}, - {"matrix": [8, 3], "x": 17, "y": 4}, - {"matrix": [8, 4], "x": 18, "y": 4}, - {"matrix": [8, 5], "x": 19, "y": 4}, - {"matrix": [8, 6], "x": 20, "y": 4}, - {"matrix": [11, 6], "x": 21, "y": 4}, - {"matrix": [11, 5], "x": 22, "y": 4}, - {"matrix": [11, 4], "x": 23, "y": 4}, - {"matrix": [11, 3], "x": 24, "y": 4}, - {"matrix": [11, 2], "x": 25, "y": 4}, - {"matrix": [11, 1], "x": 26, "y": 4} - ] - }, - "LAYOUT_giabarinaix2": { - "layout": [ - {"matrix": [0, 0], "x": 0, "y": 0}, - {"matrix": [1, 0], "x": 1, "y": 0}, - {"matrix": [2, 0], "x": 2, "y": 0}, - {"matrix": [3, 0], "x": 3, "y": 0}, - {"matrix": [4, 0], "x": 4, "y": 0}, - {"matrix": [5, 0], "x": 5, "y": 0}, - {"matrix": [5, 5], "x": 6, "y": 0}, - {"matrix": [4, 5], "x": 7, "y": 0}, - {"matrix": [3, 5], "x": 8, "y": 0}, - {"matrix": [2, 5], "x": 9, "y": 0}, - {"matrix": [1, 5], "x": 10, "y": 0}, - {"matrix": [0, 5], "x": 11, "y": 0}, - - {"matrix": [0, 1], "x": 0.5, "y": 1}, - {"matrix": [1, 1], "x": 1.5, "y": 1}, - {"matrix": [2, 1], "x": 2.5, "y": 1}, - {"matrix": [3, 1], "x": 3.5, "y": 1}, - {"matrix": [4, 1], "x": 4.5, "y": 1}, - {"matrix": [5, 1], "x": 5.5, "y": 1}, - {"matrix": [5, 6], "x": 6.5, "y": 1}, - {"matrix": [4, 6], "x": 7.5, "y": 1}, - {"matrix": [3, 6], "x": 8.5, "y": 1}, - {"matrix": [2, 6], "x": 9.5, "y": 1}, - {"matrix": [1, 6], "x": 10.5, "y": 1}, - {"matrix": [0, 6], "x": 11.5, "y": 1}, - - {"matrix": [0, 2], "x": 1, "y": 2}, - {"matrix": [1, 2], "x": 2, "y": 2}, - {"matrix": [2, 2], "x": 3, "y": 2}, - {"matrix": [3, 2], "x": 4, "y": 2}, - {"matrix": [4, 2], "x": 5, "y": 2}, - {"matrix": [5, 2], "x": 6, "y": 2}, - {"matrix": [5, 7], "x": 7, "y": 2}, - {"matrix": [4, 7], "x": 8, "y": 2}, - {"matrix": [3, 7], "x": 9, "y": 2}, - {"matrix": [2, 7], "x": 10, "y": 2}, - {"matrix": [1, 7], "x": 11, "y": 2}, - {"matrix": [0, 7], "x": 12, "y": 2}, - - {"matrix": [0, 3], "x": 1.5, "y": 3}, - {"matrix": [1, 3], "x": 2.5, "y": 3}, - {"matrix": [2, 3], "x": 3.5, "y": 3}, - {"matrix": [3, 3], "x": 4.5, "y": 3}, - {"matrix": [4, 3], "x": 5.5, "y": 3}, - {"matrix": [5, 3], "x": 6.5, "y": 3}, - {"matrix": [5, 8], "x": 7.5, "y": 3}, - {"matrix": [4, 8], "x": 8.5, "y": 3}, - {"matrix": [3, 8], "x": 9.5, "y": 3}, - {"matrix": [2, 8], "x": 10.5, "y": 3}, - {"matrix": [1, 8], "x": 11.5, "y": 3}, - {"matrix": [0, 8], "x": 12.5, "y": 3}, - - {"matrix": [0, 4], "x": 2, "y": 4}, - {"matrix": [1, 4], "x": 3, "y": 4}, - {"matrix": [2, 4], "x": 4, "y": 4}, - {"matrix": [3, 4], "x": 5, "y": 4}, - {"matrix": [4, 4], "x": 6, "y": 4}, - {"matrix": [5, 4], "x": 7, "y": 4}, - {"matrix": [5, 9], "x": 8, "y": 4}, - {"matrix": [4, 9], "x": 9, "y": 4}, - {"matrix": [3, 9], "x": 10, "y": 4}, - {"matrix": [2, 9], "x": 11, "y": 4}, - {"matrix": [1, 9], "x": 12, "y": 4}, - {"matrix": [0, 9], "x": 13, "y": 4}, - - {"matrix": [6, 9], "x": 0, "y": 6}, - {"matrix": [7, 9], "x": 1, "y": 6}, - {"matrix": [8, 9], "x": 2, "y": 6}, - {"matrix": [9, 9], "x": 3, "y": 6}, - {"matrix": [10, 9], "x": 4, "y": 6}, - {"matrix": [11, 9], "x": 5, "y": 6}, - {"matrix": [11, 4], "x": 6, "y": 6}, - {"matrix": [10, 4], "x": 7, "y": 6}, - {"matrix": [9, 4], "x": 8, "y": 6}, - {"matrix": [8, 4], "x": 9, "y": 6}, - {"matrix": [7, 4], "x": 10, "y": 6}, - {"matrix": [6, 4], "x": 11, "y": 6}, - - {"matrix": [6, 8], "x": 0.5, "y": 7}, - {"matrix": [7, 8], "x": 1.5, "y": 7}, - {"matrix": [8, 8], "x": 2.5, "y": 7}, - {"matrix": [9, 8], "x": 3.5, "y": 7}, - {"matrix": [10, 8], "x": 4.5, "y": 7}, - {"matrix": [11, 8], "x": 5.5, "y": 7}, - {"matrix": [11, 3], "x": 6.5, "y": 7}, - {"matrix": [10, 3], "x": 7.5, "y": 7}, - {"matrix": [9, 3], "x": 8.5, "y": 7}, - {"matrix": [8, 3], "x": 9.5, "y": 7}, - {"matrix": [7, 3], "x": 10.5, "y": 7}, - {"matrix": [6, 3], "x": 11.5, "y": 7}, - - {"matrix": [6, 7], "x": 1, "y": 8}, - {"matrix": [7, 7], "x": 2, "y": 8}, - {"matrix": [8, 7], "x": 3, "y": 8}, - {"matrix": [9, 7], "x": 4, "y": 8}, - {"matrix": [10, 7], "x": 5, "y": 8}, - {"matrix": [11, 7], "x": 6, "y": 8}, - {"matrix": [11, 2], "x": 7, "y": 8}, - {"matrix": [10, 2], "x": 8, "y": 8}, - {"matrix": [9, 2], "x": 9, "y": 8}, - {"matrix": [8, 2], "x": 10, "y": 8}, - {"matrix": [7, 2], "x": 11, "y": 8}, - {"matrix": [6, 2], "x": 12, "y": 8}, - - {"matrix": [6, 6], "x": 1.5, "y": 9}, - {"matrix": [7, 6], "x": 2.5, "y": 9}, - {"matrix": [8, 6], "x": 3.5, "y": 9}, - {"matrix": [9, 6], "x": 4.5, "y": 9}, - {"matrix": [10, 6], "x": 5.5, "y": 9}, - {"matrix": [11, 6], "x": 6.5, "y": 9}, - {"matrix": [11, 1], "x": 7.5, "y": 9}, - {"matrix": [10, 1], "x": 8.5, "y": 9}, - {"matrix": [9, 1], "x": 9.5, "y": 9}, - {"matrix": [8, 1], "x": 10.5, "y": 9}, - {"matrix": [7, 1], "x": 11.5, "y": 9}, - {"matrix": [6, 1], "x": 12.5, "y": 9}, - - {"matrix": [6, 5], "x": 2, "y": 10}, - {"matrix": [7, 5], "x": 3, "y": 10}, - {"matrix": [8, 5], "x": 4, "y": 10}, - {"matrix": [9, 5], "x": 5, "y": 10}, - {"matrix": [10, 5], "x": 6, "y": 10}, - {"matrix": [11, 5], "x": 7, "y": 10}, - {"matrix": [11, 0], "x": 8, "y": 10}, - {"matrix": [10, 0], "x": 9, "y": 10}, - {"matrix": [9, 0], "x": 10, "y": 10}, - {"matrix": [8, 0], "x": 11, "y": 10}, - {"matrix": [7, 0], "x": 12, "y": 10}, - {"matrix": [6, 0], "x": 13, "y": 10} - ] - } - } -} diff --git a/keyboards/giabalanai/keymaps/2firmware/keymap.c b/keyboards/giabalanai/keymaps/2firmware/keymap.c deleted file mode 100644 index 338d5d8e0ff2..000000000000 --- a/keyboards/giabalanai/keymaps/2firmware/keymap.c +++ /dev/null @@ -1,739 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "split_util.h" -#include "print.h" -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) - -#define DF_QWER DF(_QWERTY) -#define DF_COLE DF(_COLEMAK) -#define MO_ADJ MO(_ADJUST) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) -#define SHIF_UP RSFT_T(KC_UP) -#define ADJ_EIS LT(_ADJUST,KC_LNG2) -#define MIS_KAN LT(_MISC,KC_LNG1) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// UNISON flags -static bool melody_dyad_high = false; // true when +1 octave unison dyad is enabled. -static bool melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - -static bool melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - -// To record the status of Bass Chord (single or dyad, default: dyad.) -typedef union { - uint32_t raw; - struct { - bool isSingleBass:1; - }; -} user_config_t; -user_config_t user_config; - -#define IS_SINGLE_BASS() (user_config.isSingleBass) - -#ifdef RGBLIGHT_ENABLE -/* used to specify there is no LED on the keylocation. */ -# define NO_LED 255 -#endif // RGBLIGHT_ENABLE - - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _FAKE_B_SYSTEM, // MIDI fake B-system doesn't have correct assignments on top two rows. The bottom 3 rows are B-system. - _C_SYSTEM_BASS2ROW, // counter bass system - _C_SYSTEM_ENTIRELY, // single notes for both left and right keybaords. - _CHROMATONE, - _CFLIP_BASS2ROW, // 180 degree flipped layout on right side keyboard - _QWERTY, - _COLEMAK, - _ADJUST, // for Fn keys, etc. - _FN // for changing layers, octaves, etc. -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION, - CSYSTEM, // C-SYSTEM layout - BSYSTEM, // B-SYSTEM layout - CNTBASC, // CouNTer BASs C-system layout - CSYSALL, // C-SYStem ALL layout - CHRTONE, // CHRomaTONE layout - CFLIP2B, // C-system FLIPped 2(to) Backwards - TGLBASS, // ToGgLe BASS unison - TGLMICH, // ToGgLe MIdi CHannel separation - MELDYAL, // MELody DYad Low - MELODYS, // MELODY Single - MELDYAH, // MELody DYad High - TGLUVEL // ToGgLe Unison VELocity -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; -static uint8_t my_tone_status[MIDI_TONE_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* fake B-system */ - [_FAKE_B_SYSTEM] = LAYOUT( - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - - MI_Ab2, - MI_A2, MI_C3, MI_Eb3, MI_Gb3, MI_A3, MI_C4, MI_Eb4, MI_Gb4, MI_A4, MI_C5, MI_Eb5, MI_Gb5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5 - ), - - /* BASS2row */ - [_C_SYSTEM_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* C-system entirely */ - [_C_SYSTEM_ENTIRELY] = LAYOUT( - MI_BNDU, XXXXXXX, XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, - MI_BNDD, XXXXXXX, MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, - XXXXXXX, XXXXXXX, MI_D, MI_F, MI_Ab, MI_B, MI_D1, MI_F1, MI_Ab1, MI_B1, MI_D2, MI_F2, - XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, MI_E2, MI_G2, - MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, MI_Fs2, MI_A2, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* Chromatone */ - [_CHROMATONE] = LAYOUT( - MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, - MI_D, MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, - MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, - MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, MI_D2, - MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, MI_Eb2, - - MI_C2, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3, FN_MUTE, - MI_C2, MI_D2, MI_E2, MI_Gb2, MI_Ab2, MI_Bb2, MI_C3, MI_D3, MI_E3, MI_Gb3, MI_Ab3, MI_Bb3, MI_C4, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3 - ), - - [_CFLIP_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_G5, - MI_F5, MI_D5, MI_B4, MI_Ab4, MI_F4, MI_D4, MI_B3, MI_Ab3, MI_F3, MI_D3, MI_B2, MI_Ab2, FN_MUTE, - MI_Fs5, MI_Eb5, MI_C5, MI_A4, MI_Fs4, MI_Eb4, MI_C4, MI_A3, MI_Fs3, MI_Eb3, MI_C3, MI_A2, MI_Fs2, - MI_E5, MI_Db5, MI_Bb4, MI_G4, MI_E4, MI_Db4, MI_Bb3, MI_G3, MI_E3, MI_Db3, MI_Bb2, MI_G2 - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* COLEMAK */ - [_COLEMAK] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, KC_DEL, - KC_LCTL, _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, KC_ENT, - KC_LSFT, _________________COLEMAK_L3________________, _________________COLEMAK_R3________________, SHIF_UP, - KC_CAPS, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* ADJUST */ - [_ADJUST] = LAYOUT_wrapper( - _______, _________________FUNC__L___________________, _________________FUNC__R___________________, _______, - _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MINS, KC_EQL, _______, - _______, KC_VOLD, KC_VOLU, KC_MUTE, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_GRV, _______, - _______, KC_BRID, KC_BRIU, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LBRC, KC_RBRC, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_QUOT, KC_BSLS, _______, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - - /* Fn */ - [_FN] = LAYOUT( - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, - DF_QWER, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_COLE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TGLMICH, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - XXXXXXX, - MI_OCN2, MI_OCN1, MI_OC0, MI_OC1, MI_OC2, XXXXXXX, XXXXXXX, MI_OCTD, MI_OCTU, XXXXXXX, VERSION, EE_CLR, _______, - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, XXXXXXX, XXXXXXX, XXXXXXX, MI_VELD, MI_VELU, XXXXXXX, RGB_TOG, - XXXXXXX, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MI_TRSD, MI_TRSU, TGLUVEL, MELDYAL, MELODYS, MELDYAH - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_FAKE_B_SYSTEM] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_ENTIRELY] = { ENCODER_CCW_CW(_______, _______) }, - [_CHROMATONE] = { ENCODER_CCW_CW(_______, _______) }, - [_CFLIP_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_COLEMAK] = { ENCODER_CCW_CW(_______, _______) }, - [_ADJUST] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -#ifdef RGBLIGHT_ENABLE - -// Light up adjust layer keys (left keyboard) -const rgblight_segment_t PROGMEM my_adjust_layer[] = RGBLIGHT_LAYER_SEGMENTS({1, 10, HSV_ORANGE}, - {21, 2, HSV_ORANGE}, - {25, 3, HSV_ORANGE}, - {30, 5, HSV_ORANGE}, - {37, 2, HSV_ORANGE}, - {45, 2, HSV_ORANGE}, - {57, 2, HSV_ORANGE} -); - -// Light up fn layer keys -const rgblight_segment_t PROGMEM my_fn_layer[] = RGBLIGHT_LAYER_SEGMENTS( // left keyboard - {0, 6, HSV_ORANGE}, // MIDI layouts - {11, 1, HSV_RED}, // RGB_TOG - {12, 1, HSV_WHITE}, // DF_QWER - {13, 1, HSV_CORAL}, // TGLBASS - {24, 1, HSV_WHITE}, // DF_COLE - {35, 1, HSV_TEAL}, // TGLMICH -#if 0 // Color Test - {36, 1, HSV_WHITE}, - {37, 1, HSV_RED}, - {38, 1, HSV_CORAL}, - {39, 1, HSV_ORANGE}, - {40, 1, HSV_GOLDENROD}, - {41, 1, HSV_GOLD}, - {42, 1, HSV_YELLOW}, - {43, 1, HSV_CHARTREUSE}, - {44, 1, HSV_GREEN}, - {45, 1, HSV_SPRINGGREEN}, - {46, 1, HSV_TURQUOISE}, - {47, 1, HSV_TEAL}, - {48, 1, HSV_CYAN}, - {49, 1, HSV_AZURE}, - {50, 1, HSV_BLUE}, - {51, 1, HSV_PURPLE}, - {52, 1, HSV_MAGENTA}, - {53, 1, HSV_PINK}, -#endif - // right keyboard - {60, 6, HSV_ORANGE}, // MIDI layouts - {74, 1, HSV_CORAL}, // TGLBASS - {85, 1, HSV_BLUE}, // MIDI Oct - {86, 1, HSV_CYAN}, // MIDI Oct - {87, 1, HSV_SPRINGGREEN}, // MIDI Oct - {88, 1, HSV_GREEN}, // MIDI Oct - {89, 1, HSV_CHARTREUSE}, // MIDI Oct - {96, 1, HSV_PINK}, // EE_CLR - {98, 6, HSV_ORANGE}, // MIDI layouts - {107, 1, HSV_YELLOW}, // MI_VELD - {108, 1, HSV_GREEN}, // MI_VELU - {110, 1, HSV_RED}, // RGB_TOG - {112, 1, HSV_CORAL}, // TGLBASS - {119, 1, HSV_CORAL}, // TGLUVEL - {120, 1, HSV_CYAN}, // MELDYAL - {121, 1, HSV_GOLD}, // MELODYS - {122, 1, HSV_SPRINGGREEN} // MELDYAH -); - - - -// Now define the array of layers. Later layers take precedence -const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(my_fn_layer, my_adjust_layer); - -layer_state_t layer_state_set_user(layer_state_t state) { - // Both layers will light up if both kb layers are active - rgblight_set_layer_state(0, layer_state_cmp(state, _FN)); - rgblight_set_layer_state(1, layer_state_cmp(state, _ADJUST)); - return state; -}; - -#endif // RGBLIGHT_ENABLE - -void my_init(void){ - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; -} - -void eeconfig_init_user(void) { - midi_init(); - my_init(); - - // Used to set octave to 0 - midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - - // UNISON flags - melody_dyad_high = false; // true when +1 octave unison dyad is enabled. - melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - - // Reset Bass setting - user_config.raw = 0; // default: dyad - eeconfig_update_user(user_config.raw); - - // Reset the midi keyboard layout - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); -} - -void keyboard_post_init_user(void) { - my_init(); - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++) { - my_tone_status[i] = MIDI_INVALID_NOTE; - } - // load EEPROM data for isSingleBass - user_config.raw = eeconfig_read_user(); - - // When USB cable is connected to the left side keyboard, use QWERTY layout by default. - if (is_keyboard_master() && isLeftHand) { - default_layer_set(1UL << _QWERTY); - } - -#ifdef RGBLIGHT_ENABLE - - rgblight_layers = my_rgb_layers; - - // Reset LED off - rgblight_sethsv(HSV_BLACK); -# if defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_sethsv(30, 50, 40); -# ifdef RGBLIGHT_EFFECT_KNIGHT - rgblight_mode(RGBLIGHT_MODE_KNIGHT); -# elif defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_mode(RGBLIGHT_MODE_TWINKLE+3); -# endif -# endif -#endif // RGBLIGHT_ENABLE -}; - -void toggle_isSingleBass(void) { -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(before) %u\n", user_config.isSingleBass); -#endif - user_config.isSingleBass = !user_config.isSingleBass; -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(after) %u\n", user_config.isSingleBass); -#endif - - eeconfig_update_user(user_config.raw); -} - -void toggle_MIDI_channel_separation(void) { - if (midi_chord_ch > 0) { - midi_chord_ch = 0; - midi_bass_ch = 0; - } else { - midi_chord_ch = 1; - midi_bass_ch = 2; - } -} - -#ifdef RGBLIGHT_ENABLE -void switch_keylight_color4bass(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_GREEN, keylocation); - break; - case _FAKE_B_SYSTEM: - keylight_manager(record, HSV_ORANGE, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_YELLOW, keylocation); - break; - case _CFLIP_BASS2ROW: - keylight_manager(record, HSV_PURPLE, keylocation); - break; - } -} -void switch_keylight_color4chords(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_SPRINGGREEN, keylocation); - break; - case _FAKE_B_SYSTEM: - keylight_manager(record, HSV_YELLOW, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; - case _CFLIP_BASS2ROW: - keylight_manager(record, HSV_MAGENTA, keylocation); - break; - } -} -#endif // RGBLIGHT_ENABLE - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - -#ifdef RGBLIGHT_ENABLE - /* prepare for turning on LEDs when keys are pressed. */ - uint8_t r = record->event.key.row; - uint8_t c = record->event.key.col; - // uint8_t keylocation = convert_key_to_led[MATRIX_COLS * r + c]; - // uint8_t keylocation2 = convert_key_to_led2[MATRIX_COLS * r + c]; - uint8_t keylocation = pgm_read_byte(&convert_key_to_led[MATRIX_COLS * r + c]); - uint8_t keylocation2 = pgm_read_byte(&convert_key_to_led2[MATRIX_COLS * r + c]); -#endif // RGBLIGHT_ENABLE - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // set default layer and save it to EEPROM when MIDI key layers are selected. - case CSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASE); - } - break; - - case BSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_FAKE_B_SYSTEM); - } - break; - - case CNTBASC: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); - } - break; - - case CSYSALL: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_ENTIRELY); - } - break; - - case CHRTONE: - if (record->event.pressed) { - set_single_persistent_default_layer(_CHROMATONE); - } - break; - - case CFLIP2B: - if (record->event.pressed) { - set_single_persistent_default_layer(_CFLIP_BASS2ROW); - } - break; - - case TGLBASS: - if (record->event.pressed) { - toggle_isSingleBass(); - }; - break; - - case TGLMICH: - if (record->event.pressed) { - toggle_MIDI_channel_separation(); - }; - break; - - case MELDYAL: - if (record->event.pressed) { - melody_dyad_low = true; - melody_dyad_high = false; - }; - break; - - case MELODYS: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = false; - }; - break; - - case MELDYAH: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = true; - }; - break; - - case TGLUVEL: - if (record->event.pressed) { - melody_unison_suppress = !melody_unison_suppress; - }; - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, IS_SINGLE_BASS()); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4bass(record, keylocation); -#endif - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - -#ifdef RGBLIGHT_ENABLE - case KC_A ... KC_RGUI: // for QWERTY - case QK_GRAVE_ESCAPE: - case ADJ_EIS: - case MO_ADJ: - case SHIF_UP: - keylight_manager(record, HSV_RED, keylocation); - break; -#endif - - // Keycodes on the right side. - case MIDI_TONE_MIN ... MIDI_TONE_MAX: // notes on the right side keyboard. - // root_note is played by process_midi(). - if ( melody_dyad_high == true ) { // play 1 octave higher as well. - my_process_midi(0, keycode, record, my_tone_status, 12, melody_unison_suppress); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_RED, keylocation); - keylight_manager(record, HSV_RED, keylocation2); -#endif - } else if ( melody_dyad_low == true ) { // play 1 octave lower as well. - my_process_midi(0, keycode, record, my_tone_status, -12, melody_unison_suppress); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_CYAN, keylocation); - keylight_manager(record, HSV_CYAN, keylocation2); -#endif - } else { - uprintf("layer=%u, default_layer_state = %u\n", biton32(default_layer_state), default_layer_state); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); - keylight_manager(record, HSV_GOLDENROD, keylocation2); -#endif - } - break; - -#ifdef RGBLIGHT_ENABLE - // case KC_MUTE: - case FN_MUTE: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - } - // If console is enabled, it will print the matrix position and status of each key pressed -#if defined(CONSOLE_ENABLE) && defined(RGBLIGHT_ENABLE) - uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); - uprintf("r=%d, c=%d, keyloc=%d, keyloc2=%d, matrix_col x r + c = %d\n", r, c, keylocation, keylocation2, MATRIX_COLS * r + c); -#endif - return true; -} diff --git a/keyboards/giabalanai/keymaps/2firmware/readme.md b/keyboards/giabalanai/keymaps/2firmware/readme.md deleted file mode 100644 index e851c97af8cf..000000000000 --- a/keyboards/giabalanai/keymaps/2firmware/readme.md +++ /dev/null @@ -1,12 +0,0 @@ -# A personal keymap for giabalanai with RGBLIGHT_ENABLE = yes in rules.mk, which 3araht is using. -"2firmware" requires writing the firmware separately to left and right keyboards in order to have different functionality when USB cable is connected to the left side keyboard. It can be used without the right side. -(EE_HANDS is defined in 2firmware/config.h). - -When USB cable is connected to the left side keyboard, QWERTY layout is used by default. - - -Use below for writing the firmware to the left side keyboard. -> make giabalanai:2firmware:avrdude-split-left - -Use below for writing the firmware to the right side keyboard. -> make giabalanai:2firmware:avrdude-split-right diff --git a/keyboards/giabalanai/keymaps/2firmware/rules.mk b/keyboards/giabalanai/keymaps/2firmware/rules.mk deleted file mode 100644 index 2ecc5f55c193..000000000000 --- a/keyboards/giabalanai/keymaps/2firmware/rules.mk +++ /dev/null @@ -1,4 +0,0 @@ -RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow -CONSOLE_ENABLE = no # Console for debug - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/3araht/keymap.c b/keyboards/giabalanai/keymaps/3araht/keymap.c deleted file mode 100644 index fb68c02c7087..000000000000 --- a/keyboards/giabalanai/keymaps/3araht/keymap.c +++ /dev/null @@ -1,780 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "print.h" -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) - -#define DF_QWER DF(_QWERTY) -#define DF_COLE DF(_COLEMAK) -#define MO_ADJ MO(_ADJUST) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) -#define SHIF_UP RSFT_T(KC_UP) -#define ADJ_EIS LT(_ADJUST,KC_LNG2) -#define MIS_KAN LT(_MISC,KC_LNG1) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// UNISON flags -static bool melody_dyad_high = false; // true when +1 octave unison dyad is enabled. -static bool melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - -static bool melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - -// To record the status of Bass Chord (single or dyad, default: dyad.) -typedef union { - uint32_t raw; - struct { - bool isSingleBass:1; - }; -} user_config_t; -user_config_t user_config; - -#define IS_SINGLE_BASS() (user_config.isSingleBass) - -#ifdef RGBLIGHT_ENABLE -/* used to specify there is no LED on the keylocation. */ -# define NO_LED 255 -#endif // RGBLIGHT_ENABLE - - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _FAKE_B_SYSTEM, // MIDI fake B-system doesn't have correct assignments on top two rows. The bottom 3 rows are B-system. - _C_SYSTEM_BASS2ROW, // counter bass system - _FAKE_B_SYSTEM_BASS2ROW, // MIDI fake B-system doesn't have correct assignments on top two rows. The bottom 3 rows are B-system. Counter bass version. - _C_SYSTEM_ENTIRELY, // single notes for both left and right keybaords. - _C_SYSTEM_FREEBASS, // C-system Free Bass - _CHROMATONE, - _CFLIP_BASS2ROW, // 180 degree flipped layout on right side keyboard - _QWERTY, - _COLEMAK, - _ADJUST, // for Fn keys, etc. - _FN // for changing layers, octaves, etc. -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION, - CSYSTEM, // C-SYSTEM layout - BSYSTEM, // B-SYSTEM layout - CNTBASC, // CouNTer BASs C-system layout - CNTBASB, // CouNTer BASs B-system layout - CSYSALL, // C-SYStem ALL layout - CSYSFBS, // C-SYStem Free BaSs - CHRTONE, // CHRomaTONE layout - CFLIP2B, // C-system FLIPped 2(to) Backwards - TGLBASS, // ToGgLe BASS unison - TGLMICH, // ToGgLe MIdi CHannel separation - MELDYAL, // MELody DYad Low - MELODYS, // MELODY Single - MELDYAH, // MELody DYad High - TGLUVEL // ToGgLe Unison VELocity -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; -static uint8_t my_tone_status[MIDI_TONE_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* fake B-system */ - [_FAKE_B_SYSTEM] = LAYOUT( - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - - MI_Ab2, - MI_A2, MI_C3, MI_Eb3, MI_Gb3, MI_A3, MI_C4, MI_Eb4, MI_Gb4, MI_A4, MI_C5, MI_Eb5, MI_Gb5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5 - ), - - /* BASS2row */ - [_C_SYSTEM_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* fake B-system */ - [_FAKE_B_SYSTEM_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_Ab2, - MI_A2, MI_C3, MI_Eb3, MI_Gb3, MI_A3, MI_C4, MI_Eb4, MI_Gb4, MI_A4, MI_C5, MI_Eb5, MI_Gb5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5 - ), - - /* C-system entirely */ - [_C_SYSTEM_ENTIRELY] = LAYOUT( - MI_BNDU, XXXXXXX, XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, - MI_BNDD, XXXXXXX, MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, - XXXXXXX, XXXXXXX, MI_D, MI_F, MI_Ab, MI_B, MI_D1, MI_F1, MI_Ab1, MI_B1, MI_D2, MI_F2, - XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, MI_E2, MI_G2, - MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, MI_Fs2, MI_A2, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* C-system free bass */ - [_C_SYSTEM_FREEBASS] = LAYOUT( - MI_Db3, MI_Bb2, MI_G2, MI_E2, MI_Db2, MI_Bb1, MI_G1, MI_E1, MI_Db1, MI_Bb, MI_G, MI_E, - MI_C3, MI_A2, MI_Fs2, MI_Eb2, MI_C2, MI_A1, MI_Fs1, MI_Eb1, MI_C1, MI_A, MI_Fs, MI_Eb, - MI_B2, MI_Ab2, MI_F2, MI_D2, MI_B1, MI_Ab1, MI_F1, MI_D1, MI_B, MI_Ab, MI_F, MI_D, - MI_Bb2, MI_G2, MI_E2, MI_Db2, MI_Bb1, MI_G1, MI_E1, MI_Db1, MI_Bb, MI_G, MI_E, MI_Db, - MI_A2, MI_Fs2, MI_Eb2, MI_C2, MI_A1, MI_Fs1, MI_Eb1, MI_C1, MI_A, MI_Fs, MI_Eb, MI_C, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* Chromatone */ - [_CHROMATONE] = LAYOUT( - MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, - MI_D, MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, - MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, - MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, MI_D2, - MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, MI_Eb2, - - MI_C2, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3, FN_MUTE, - MI_C2, MI_D2, MI_E2, MI_Gb2, MI_Ab2, MI_Bb2, MI_C3, MI_D3, MI_E3, MI_Gb3, MI_Ab3, MI_Bb3, MI_C4, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3 - ), - - [_CFLIP_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_G5, - MI_F5, MI_D5, MI_B4, MI_Ab4, MI_F4, MI_D4, MI_B3, MI_Ab3, MI_F3, MI_D3, MI_B2, MI_Ab2, FN_MUTE, - MI_Fs5, MI_Eb5, MI_C5, MI_A4, MI_Fs4, MI_Eb4, MI_C4, MI_A3, MI_Fs3, MI_Eb3, MI_C3, MI_A2, MI_Fs2, - MI_E5, MI_Db5, MI_Bb4, MI_G4, MI_E4, MI_Db4, MI_Bb3, MI_G3, MI_E3, MI_Db3, MI_Bb2, MI_G2 - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* COLEMAK */ - [_COLEMAK] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, KC_DEL, - KC_LCTL, _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, KC_ENT, - KC_LSFT, _________________COLEMAK_L3________________, _________________COLEMAK_R3________________, SHIF_UP, - KC_CAPS, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* ADJUST */ - [_ADJUST] = LAYOUT_wrapper( - _______, _________________FUNC__L___________________, _________________FUNC__R___________________, _______, - _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MINS, KC_EQL, _______, - _______, KC_VOLD, KC_VOLU, KC_MUTE, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_GRV, _______, - _______, KC_BRID, KC_BRIU, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LBRC, KC_RBRC, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_QUOT, KC_BSLS, _______, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - - /* Fn */ - [_FN] = LAYOUT( - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, CSYSFBS, CNTBASB, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, - DF_QWER, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_COLE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TGLMICH, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - XXXXXXX, - MI_OCN2, MI_OCN1, MI_OC0, MI_OC1, MI_OC2, XXXXXXX, XXXXXXX, MI_OCTD, MI_OCTU, XXXXXXX, VERSION, EE_CLR, _______, - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, CSYSFBS, CNTBASB, XXXXXXX, MI_VELD, MI_VELU, XXXXXXX, RGB_TOG, - XXXXXXX, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MI_TRSD, MI_TRSU, TGLUVEL, MELDYAL, MELODYS, MELDYAH - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_FAKE_B_SYSTEM] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_FAKE_B_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_ENTIRELY] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_FREEBASS] = { ENCODER_CCW_CW(_______, _______) }, - [_CHROMATONE] = { ENCODER_CCW_CW(_______, _______) }, - [_CFLIP_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_COLEMAK] = { ENCODER_CCW_CW(_______, _______) }, - [_ADJUST] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -#ifdef RGBLIGHT_ENABLE - -// Light up adjust layer keys (left keyboard) -const rgblight_segment_t PROGMEM my_adjust_layer[] = RGBLIGHT_LAYER_SEGMENTS({1, 10, HSV_ORANGE}, - {21, 2, HSV_ORANGE}, - {25, 3, HSV_ORANGE}, - {30, 5, HSV_ORANGE}, - {37, 2, HSV_ORANGE}, - {45, 2, HSV_ORANGE}, - {57, 2, HSV_ORANGE} -); - -// Light up fn layer keys -const rgblight_segment_t PROGMEM my_fn_layer[] = RGBLIGHT_LAYER_SEGMENTS( // left keyboard - {0, 8, HSV_ORANGE}, // MIDI layouts - {11, 1, HSV_RED}, // RGB_TOG - {12, 1, HSV_WHITE}, // DF_QWER - {13, 1, HSV_CORAL}, // TGLBASS - {24, 1, HSV_WHITE}, // DF_COLE - {35, 1, HSV_TEAL}, // TGLMICH -#if 0 // Color Test - {36, 1, HSV_WHITE}, - {37, 1, HSV_RED}, - {38, 1, HSV_CORAL}, - {39, 1, HSV_ORANGE}, - {40, 1, HSV_GOLDENROD}, - {41, 1, HSV_GOLD}, - {42, 1, HSV_YELLOW}, - {43, 1, HSV_CHARTREUSE}, - {44, 1, HSV_GREEN}, - {45, 1, HSV_SPRINGGREEN}, - {46, 1, HSV_TURQUOISE}, - {47, 1, HSV_TEAL}, - {48, 1, HSV_CYAN}, - {49, 1, HSV_AZURE}, - {50, 1, HSV_BLUE}, - {51, 1, HSV_PURPLE}, - {52, 1, HSV_MAGENTA}, - {53, 1, HSV_PINK}, -#endif - // right keyboard - {60, 8, HSV_ORANGE}, // MIDI layouts - {74, 1, HSV_CORAL}, // TGLBASS - {85, 1, HSV_BLUE}, // MIDI Oct - {86, 1, HSV_CYAN}, // MIDI Oct - {87, 1, HSV_SPRINGGREEN}, // MIDI Oct - {88, 1, HSV_GREEN}, // MIDI Oct - {89, 1, HSV_CHARTREUSE}, // MIDI Oct - {95, 1, HSV_GOLD}, // VERSION - {96, 1, HSV_PINK}, // EE_CLR - {98, 8, HSV_ORANGE}, // MIDI layouts - {107, 1, HSV_YELLOW}, // MI_VELD - {108, 1, HSV_GREEN}, // MI_VELU - {110, 1, HSV_RED}, // RGB_TOG - {112, 1, HSV_CORAL}, // TGLBASS - {119, 1, HSV_CORAL}, // TGLUVEL - {120, 1, HSV_CYAN}, // MELDYAL - {121, 1, HSV_GOLD}, // MELODYS - {122, 1, HSV_SPRINGGREEN} // MELDYAH -); - -// Now define the array of layers. Later layers take precedence -const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(my_fn_layer, my_adjust_layer); - -layer_state_t layer_state_set_user(layer_state_t state) { - // Both layers will light up if both kb layers are active - rgblight_set_layer_state(0, layer_state_cmp(state, _FN)); - rgblight_set_layer_state(1, layer_state_cmp(state, _ADJUST)); - return state; -}; - -#endif // RGBLIGHT_ENABLE - -void my_init(void){ - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; -} - -void eeconfig_init_user(void) { - midi_init(); - my_init(); - - // Used to set octave to 0 - midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - - // UNISON flags - melody_dyad_high = false; // true when +1 octave unison dyad is enabled. - melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - - // Reset Bass setting - user_config.raw = 0; // default: dyad - eeconfig_update_user(user_config.raw); - - // Reset the midi keyboard layout - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); -} - -void keyboard_post_init_user(void) { - my_init(); - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++) { - my_tone_status[i] = MIDI_INVALID_NOTE; - } - // load EEPROM data for isSingleBass - user_config.raw = eeconfig_read_user(); - -#ifdef RGBLIGHT_ENABLE - - rgblight_layers = my_rgb_layers; - - // Reset LED off - rgblight_sethsv(HSV_BLACK); -# if defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_sethsv(30, 50, 40); -# ifdef RGBLIGHT_EFFECT_KNIGHT - rgblight_mode(RGBLIGHT_MODE_KNIGHT); -# elif defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_mode(RGBLIGHT_MODE_TWINKLE+3); -# endif -# endif -#endif // RGBLIGHT_ENABLE -}; - -void toggle_isSingleBass(void) { -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(before) %u\n", user_config.isSingleBass); -#endif - user_config.isSingleBass = !user_config.isSingleBass; -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(after) %u\n", user_config.isSingleBass); -#endif - - eeconfig_update_user(user_config.raw); -} - -void toggle_MIDI_channel_separation(void) { - if (midi_chord_ch > 0) { - midi_chord_ch = 0; - midi_bass_ch = 0; - } else { - midi_chord_ch = 1; - midi_bass_ch = 2; - } -} - -#ifdef RGBLIGHT_ENABLE -void switch_keylight_color4bass(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_GREEN, keylocation); - break; - case _FAKE_B_SYSTEM: - keylight_manager(record, HSV_ORANGE, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - case _FAKE_B_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_YELLOW, keylocation); - break; - case _CFLIP_BASS2ROW: - keylight_manager(record, HSV_PURPLE, keylocation); - break; - } -} -void switch_keylight_color4chords(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_SPRINGGREEN, keylocation); - break; - case _FAKE_B_SYSTEM: - keylight_manager(record, HSV_YELLOW, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - case _FAKE_B_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; - case _CFLIP_BASS2ROW: - keylight_manager(record, HSV_MAGENTA, keylocation); - break; - } -} -#endif // RGBLIGHT_ENABLE - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - -#ifdef RGBLIGHT_ENABLE - /* prepare for turning on LEDs when keys are pressed. */ - uint8_t r = record->event.key.row; - uint8_t c = record->event.key.col; - // uint8_t keylocation = convert_key_to_led[MATRIX_COLS * r + c]; - // uint8_t keylocation2 = convert_key_to_led2[MATRIX_COLS * r + c]; - uint8_t keylocation = pgm_read_byte(&convert_key_to_led[MATRIX_COLS * r + c]); - uint8_t keylocation2 = pgm_read_byte(&convert_key_to_led2[MATRIX_COLS * r + c]); -#endif // RGBLIGHT_ENABLE - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // set default layer and save it to EEPROM when MIDI key layers are selected. - case CSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASE); - } - break; - - case BSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_FAKE_B_SYSTEM); - } - break; - - case CNTBASC: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); - } - break; - - case CNTBASB: - if (record->event.pressed) { - set_single_persistent_default_layer(_FAKE_B_SYSTEM_BASS2ROW); - } - break; - - case CSYSALL: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_ENTIRELY); - } - break; - - case CHRTONE: - if (record->event.pressed) { - set_single_persistent_default_layer(_CHROMATONE); - } - break; - - case CFLIP2B: - if (record->event.pressed) { - set_single_persistent_default_layer(_CFLIP_BASS2ROW); - } - break; - - case CSYSFBS: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_FREEBASS); - } - break; - - case TGLBASS: - if (record->event.pressed) { - toggle_isSingleBass(); - }; - break; - - case TGLMICH: - if (record->event.pressed) { - toggle_MIDI_channel_separation(); - }; - break; - - case MELDYAL: - if (record->event.pressed) { - melody_dyad_low = true; - melody_dyad_high = false; - }; - break; - - case MELODYS: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = false; - }; - break; - - case MELDYAH: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = true; - }; - break; - - case TGLUVEL: - if (record->event.pressed) { - melody_unison_suppress = !melody_unison_suppress; - }; - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, IS_SINGLE_BASS()); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4bass(record, keylocation); -#endif - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - -#ifdef RGBLIGHT_ENABLE - case KC_A ... KC_RGUI: // for QWERTY - case QK_GRAVE_ESCAPE: - case ADJ_EIS: - case MO_ADJ: - case SHIF_UP: - keylight_manager(record, HSV_RED, keylocation); - break; -#endif - - // Keycodes on the right side. - case MIDI_TONE_MIN ... MIDI_TONE_MAX: // notes on the right side keyboard. - // root_note is played by process_midi(). - if ( melody_dyad_high == true ) { // play 1 octave higher as well. - my_process_midi(0, keycode, record, my_tone_status, 12, melody_unison_suppress); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_RED, keylocation); - keylight_manager(record, HSV_RED, keylocation2); -#endif - } else if ( melody_dyad_low == true ) { // play 1 octave lower as well. - my_process_midi(0, keycode, record, my_tone_status, -12, melody_unison_suppress); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_CYAN, keylocation); - keylight_manager(record, HSV_CYAN, keylocation2); -#endif - } else { - uprintf("layer=%u, default_layer_state = %u\n", biton32(default_layer_state), default_layer_state); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); - keylight_manager(record, HSV_GOLDENROD, keylocation2); -#endif - } - break; - -#ifdef RGBLIGHT_ENABLE - // case KC_MUTE: - case FN_MUTE: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - } - // If console is enabled, it will print the matrix position and status of each key pressed -#if defined(CONSOLE_ENABLE) && defined(RGBLIGHT_ENABLE) - uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); - uprintf("r=%d, c=%d, keyloc=%d, keyloc2=%d, matrix_col x r + c = %d\n", r, c, keylocation, keylocation2, MATRIX_COLS * r + c); -#endif - return true; -} diff --git a/keyboards/giabalanai/keymaps/3araht/readme.md b/keyboards/giabalanai/keymaps/3araht/readme.md deleted file mode 100644 index a731456db61c..000000000000 --- a/keyboards/giabalanai/keymaps/3araht/readme.md +++ /dev/null @@ -1 +0,0 @@ -# A personal keymap for giabalanai with RGBLIGHT_ENABLE = yes in rules.mk, which 3araht is using. diff --git a/keyboards/giabalanai/keymaps/3araht/rules.mk b/keyboards/giabalanai/keymaps/3araht/rules.mk deleted file mode 100644 index 2ecc5f55c193..000000000000 --- a/keyboards/giabalanai/keymaps/3araht/rules.mk +++ /dev/null @@ -1,4 +0,0 @@ -RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow -CONSOLE_ENABLE = no # Console for debug - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/default/keymap.c b/keyboards/giabalanai/keymaps/default/keymap.c deleted file mode 100644 index 42874025f382..000000000000 --- a/keyboards/giabalanai/keymaps/default/keymap.c +++ /dev/null @@ -1,259 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) - -#define DFCBASE DF(_C_SYSTEM_BASE) -#define DF_QWER DF(_QWERTY) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _QWERTY, // just in case - _FN -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, KC_RCTL, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* Fn */ - [_FN] = LAYOUT( - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, VERSION, XXXXXXX, _______, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -void keyboard_post_init_user(void) { - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - default_layer_set(1UL << _C_SYSTEM_BASE); -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, false); - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); - break; - } - return true; -} diff --git a/keyboards/giabalanai/keymaps/default/readme.md b/keyboards/giabalanai/keymaps/default/readme.md deleted file mode 100644 index d929aa1f5e54..000000000000 --- a/keyboards/giabalanai/keymaps/default/readme.md +++ /dev/null @@ -1 +0,0 @@ -# The default keymap for giabalanai diff --git a/keyboards/giabalanai/keymaps/default/rules.mk b/keyboards/giabalanai/keymaps/default/rules.mk deleted file mode 100644 index 8006608ea922..000000000000 --- a/keyboards/giabalanai/keymaps/default/rules.mk +++ /dev/null @@ -1 +0,0 @@ -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/default_giabarinaix2/config.h b/keyboards/giabalanai/keymaps/default_giabarinaix2/config.h deleted file mode 100644 index dd10d213a0b6..000000000000 --- a/keyboards/giabalanai/keymaps/default_giabarinaix2/config.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2023 3araht - -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 . -*/ -#pragma once - -#define GIABARINAIX2 -#ifdef GIABARINAIX2 -# undef MATRIX_ROW_PINS_RIGHT -# undef MATRIX_COL_PINS_RIGHT - -# ifdef RGBLIGHT_ENABLE -# undef RGBLED_NUM -# define RGBLED_NUM 120 -# undef RGBLIGHT_LED_MAP -# define RGBLIGHT_LED_MAP { \ - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \ - 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \ - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \ - 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, \ - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, \ - \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, \ - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \ - 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, \ - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ - 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48 \ - } -# endif -#endif diff --git a/keyboards/giabalanai/keymaps/default_giabarinaix2/info.json b/keyboards/giabalanai/keymaps/default_giabarinaix2/info.json deleted file mode 100644 index 6581733dd1c5..000000000000 --- a/keyboards/giabalanai/keymaps/default_giabarinaix2/info.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "keyboard_name": "giabarinaix2", - "manufacturer": "3araht", - "url": "https://github.com/3araht", - "maintainer": "3araht", - "usb": { - "vid": "0xFEED", - "pid": "0xF4B2", - "device_version": "0.0.1" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label": "l00", "x": 0, "y": 0}, - {"label": "l01", "x": 1, "y": 0}, - {"label": "l02", "x": 2, "y": 0}, - {"label": "l03", "x": 3, "y": 0}, - {"label": "l04", "x": 4, "y": 0}, - {"label": "l05", "x": 5, "y": 0}, - {"label": "l06", "x": 6, "y": 0}, - {"label": "l07", "x": 7, "y": 0}, - {"label": "l08", "x": 8, "y": 0}, - {"label": "l09", "x": 9, "y": 0}, - {"label": "l0a", "x": 10, "y": 0}, - {"label": "l0b", "x": 11, "y": 0}, - - {"label": "r00", "x": 14.5, "y": 0}, - {"label": "r01", "x": 15.5, "y": 0}, - {"label": "r02", "x": 16.5, "y": 0}, - {"label": "r03", "x": 17.5, "y": 0}, - {"label": "r04", "x": 18.5, "y": 0}, - {"label": "r05", "x": 19.5, "y": 0}, - {"label": "r06", "x": 20.5, "y": 0}, - {"label": "r07", "x": 21.5, "y": 0}, - {"label": "r08", "x": 22.5, "y": 0}, - {"label": "r09", "x": 23.5, "y": 0}, - {"label": "r0a", "x": 24.5, "y": 0}, - {"label": "r0b", "x": 25.5, "y": 0}, - - {"label": "l10", "x": 0.5, "y": 1}, - {"label": "l11", "x": 1.5, "y": 1}, - {"label": "l12", "x": 2.5, "y": 1}, - {"label": "l13", "x": 3.5, "y": 1}, - {"label": "l14", "x": 4.5, "y": 1}, - {"label": "l15", "x": 5.5, "y": 1}, - {"label": "l16", "x": 6.5, "y": 1}, - {"label": "l17", "x": 7.5, "y": 1}, - {"label": "l18", "x": 8.5, "y": 1}, - {"label": "l19", "x": 9.5, "y": 1}, - {"label": "l1a", "x": 10.5, "y": 1}, - {"label": "l1b", "x": 11.5, "y": 1}, - - {"label": "r10", "x": 15, "y": 1}, - {"label": "r11", "x": 16, "y": 1}, - {"label": "r12", "x": 17, "y": 1}, - {"label": "r13", "x": 18, "y": 1}, - {"label": "r14", "x": 19, "y": 1}, - {"label": "r15", "x": 20, "y": 1}, - {"label": "r16", "x": 21, "y": 1}, - {"label": "r17", "x": 22, "y": 1}, - {"label": "r18", "x": 23, "y": 1}, - {"label": "r19", "x": 24, "y": 1}, - {"label": "r1a", "x": 25, "y": 1}, - {"label": "r1b", "x": 26, "y": 1}, - - {"label": "l20", "x": 1, "y": 2}, - {"label": "l21", "x": 2, "y": 2}, - {"label": "l22", "x": 3, "y": 2}, - {"label": "l23", "x": 4, "y": 2}, - {"label": "l24", "x": 5, "y": 2}, - {"label": "l25", "x": 6, "y": 2}, - {"label": "l26", "x": 7, "y": 2}, - {"label": "l27", "x": 8, "y": 2}, - {"label": "l28", "x": 9, "y": 2}, - {"label": "l29", "x": 10, "y": 2}, - {"label": "l2a", "x": 11, "y": 2}, - {"label": "l2b", "x": 12, "y": 2}, - - {"label": "r20", "x": 15.5, "y": 2}, - {"label": "r21", "x": 16.5, "y": 2}, - {"label": "r22", "x": 17.5, "y": 2}, - {"label": "r23", "x": 18.5, "y": 2}, - {"label": "r24", "x": 19.5, "y": 2}, - {"label": "r25", "x": 20.5, "y": 2}, - {"label": "r26", "x": 21.5, "y": 2}, - {"label": "r27", "x": 22.5, "y": 2}, - {"label": "r28", "x": 23.5, "y": 2}, - {"label": "r29", "x": 24.5, "y": 2}, - {"label": "r2a", "x": 25.5, "y": 2}, - {"label": "r2b", "x": 26.5, "y": 2}, - - {"label": "l30", "x": 1.5, "y": 3}, - {"label": "l31", "x": 2.5, "y": 3}, - {"label": "l32", "x": 3.5, "y": 3}, - {"label": "l33", "x": 4.5, "y": 3}, - {"label": "l34", "x": 5.5, "y": 3}, - {"label": "l35", "x": 6.5, "y": 3}, - {"label": "l36", "x": 7.5, "y": 3}, - {"label": "l37", "x": 8.5, "y": 3}, - {"label": "l38", "x": 9.5, "y": 3}, - {"label": "l39", "x": 10.5, "y": 3}, - {"label": "l3a", "x": 11.5, "y": 3}, - {"label": "l3b", "x": 12.5, "y": 3}, - - {"label": "r30", "x": 16, "y": 3}, - {"label": "r31", "x": 17, "y": 3}, - {"label": "r32", "x": 18, "y": 3}, - {"label": "r33", "x": 19, "y": 3}, - {"label": "r34", "x": 20, "y": 3}, - {"label": "r35", "x": 21, "y": 3}, - {"label": "r36", "x": 22, "y": 3}, - {"label": "r37", "x": 23, "y": 3}, - {"label": "r38", "x": 24, "y": 3}, - {"label": "r39", "x": 25, "y": 3}, - {"label": "r3a", "x": 26, "y": 3}, - {"label": "r3b", "x": 27, "y": 3}, - - {"label": "l40", "x": 2, "y": 4}, - {"label": "l41", "x": 3, "y": 4}, - {"label": "l42", "x": 4, "y": 4}, - {"label": "l43", "x": 5, "y": 4}, - {"label": "l44", "x": 6, "y": 4}, - {"label": "l45", "x": 7, "y": 4}, - {"label": "l46", "x": 8, "y": 4}, - {"label": "l47", "x": 9, "y": 4}, - {"label": "l48", "x": 10, "y": 4}, - {"label": "l49", "x": 11, "y": 4}, - {"label": "l4a", "x": 12, "y": 4}, - {"label": "l4b", "x": 13, "y": 4}, - - {"label": "r40", "x": 16.5, "y": 4}, - {"label": "r41", "x": 17.5, "y": 4}, - {"label": "r42", "x": 18.5, "y": 4}, - {"label": "r43", "x": 19.5, "y": 4}, - {"label": "r44", "x": 20.5, "y": 4}, - {"label": "r45", "x": 21.5, "y": 4}, - {"label": "r46", "x": 22.5, "y": 4}, - {"label": "r47", "x": 23.5, "y": 4}, - {"label": "r48", "x": 24.5, "y": 4}, - {"label": "r49", "x": 25.5, "y": 4}, - {"label": "r4a", "x": 26.5, "y": 4}, - {"label": "r4b", "x": 27.5, "y": 4} - ] - } - } -} diff --git a/keyboards/giabalanai/keymaps/default_giabarinaix2/keymap.c b/keyboards/giabalanai/keymaps/default_giabarinaix2/keymap.c deleted file mode 100644 index ca9ac3855597..000000000000 --- a/keyboards/giabalanai/keymaps/default_giabarinaix2/keymap.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper_giabarinaix2(...) LAYOUT_giabarinaix2(__VA_ARGS__) - -#define DFCBASE DF(_C_SYSTEM_BASE) -#define DF_QWER DF(_QWERTY) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _QWERTY, // just in case - _FN -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT_giabarinaix2( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Db2, MI_E2, MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, - MI_Eb2, MI_Fs2, MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, - MI_F2, MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, FN_MUTE - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper_giabarinaix2( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, KC_RCTL, - - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, _______ - ), - - /* Fn */ - [_FN] = LAYOUT_giabarinaix2( - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, VERSION, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______ - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -void keyboard_post_init_user(void) { - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - default_layer_set(1UL << _C_SYSTEM_BASE); -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, false); - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); - break; - } - return true; -} diff --git a/keyboards/giabalanai/keymaps/default_giabarinaix2/readme.md b/keyboards/giabalanai/keymaps/default_giabarinaix2/readme.md deleted file mode 100644 index ecdae4723d9c..000000000000 --- a/keyboards/giabalanai/keymaps/default_giabarinaix2/readme.md +++ /dev/null @@ -1 +0,0 @@ -# The default keymap for giabarinaix2 diff --git a/keyboards/giabalanai/keymaps/default_giabarinaix2/rules.mk b/keyboards/giabalanai/keymaps/default_giabarinaix2/rules.mk deleted file mode 100644 index 354223388411..000000000000 --- a/keyboards/giabalanai/keymaps/default_giabarinaix2/rules.mk +++ /dev/null @@ -1,3 +0,0 @@ -ENCODER_ENABLE = no # encoder on mute button - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/giabarinaix2led/config.h b/keyboards/giabalanai/keymaps/giabarinaix2led/config.h deleted file mode 100644 index dd10d213a0b6..000000000000 --- a/keyboards/giabalanai/keymaps/giabarinaix2led/config.h +++ /dev/null @@ -1,42 +0,0 @@ -/* -Copyright 2023 3araht - -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 . -*/ -#pragma once - -#define GIABARINAIX2 -#ifdef GIABARINAIX2 -# undef MATRIX_ROW_PINS_RIGHT -# undef MATRIX_COL_PINS_RIGHT - -# ifdef RGBLIGHT_ENABLE -# undef RGBLED_NUM -# define RGBLED_NUM 120 -# undef RGBLIGHT_LED_MAP -# define RGBLIGHT_LED_MAP { \ - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \ - 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \ - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \ - 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, \ - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, \ - \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, \ - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \ - 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, \ - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ - 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48 \ - } -# endif -#endif diff --git a/keyboards/giabalanai/keymaps/giabarinaix2led/info.json b/keyboards/giabalanai/keymaps/giabarinaix2led/info.json deleted file mode 100644 index 6581733dd1c5..000000000000 --- a/keyboards/giabalanai/keymaps/giabarinaix2led/info.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "keyboard_name": "giabarinaix2", - "manufacturer": "3araht", - "url": "https://github.com/3araht", - "maintainer": "3araht", - "usb": { - "vid": "0xFEED", - "pid": "0xF4B2", - "device_version": "0.0.1" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label": "l00", "x": 0, "y": 0}, - {"label": "l01", "x": 1, "y": 0}, - {"label": "l02", "x": 2, "y": 0}, - {"label": "l03", "x": 3, "y": 0}, - {"label": "l04", "x": 4, "y": 0}, - {"label": "l05", "x": 5, "y": 0}, - {"label": "l06", "x": 6, "y": 0}, - {"label": "l07", "x": 7, "y": 0}, - {"label": "l08", "x": 8, "y": 0}, - {"label": "l09", "x": 9, "y": 0}, - {"label": "l0a", "x": 10, "y": 0}, - {"label": "l0b", "x": 11, "y": 0}, - - {"label": "r00", "x": 14.5, "y": 0}, - {"label": "r01", "x": 15.5, "y": 0}, - {"label": "r02", "x": 16.5, "y": 0}, - {"label": "r03", "x": 17.5, "y": 0}, - {"label": "r04", "x": 18.5, "y": 0}, - {"label": "r05", "x": 19.5, "y": 0}, - {"label": "r06", "x": 20.5, "y": 0}, - {"label": "r07", "x": 21.5, "y": 0}, - {"label": "r08", "x": 22.5, "y": 0}, - {"label": "r09", "x": 23.5, "y": 0}, - {"label": "r0a", "x": 24.5, "y": 0}, - {"label": "r0b", "x": 25.5, "y": 0}, - - {"label": "l10", "x": 0.5, "y": 1}, - {"label": "l11", "x": 1.5, "y": 1}, - {"label": "l12", "x": 2.5, "y": 1}, - {"label": "l13", "x": 3.5, "y": 1}, - {"label": "l14", "x": 4.5, "y": 1}, - {"label": "l15", "x": 5.5, "y": 1}, - {"label": "l16", "x": 6.5, "y": 1}, - {"label": "l17", "x": 7.5, "y": 1}, - {"label": "l18", "x": 8.5, "y": 1}, - {"label": "l19", "x": 9.5, "y": 1}, - {"label": "l1a", "x": 10.5, "y": 1}, - {"label": "l1b", "x": 11.5, "y": 1}, - - {"label": "r10", "x": 15, "y": 1}, - {"label": "r11", "x": 16, "y": 1}, - {"label": "r12", "x": 17, "y": 1}, - {"label": "r13", "x": 18, "y": 1}, - {"label": "r14", "x": 19, "y": 1}, - {"label": "r15", "x": 20, "y": 1}, - {"label": "r16", "x": 21, "y": 1}, - {"label": "r17", "x": 22, "y": 1}, - {"label": "r18", "x": 23, "y": 1}, - {"label": "r19", "x": 24, "y": 1}, - {"label": "r1a", "x": 25, "y": 1}, - {"label": "r1b", "x": 26, "y": 1}, - - {"label": "l20", "x": 1, "y": 2}, - {"label": "l21", "x": 2, "y": 2}, - {"label": "l22", "x": 3, "y": 2}, - {"label": "l23", "x": 4, "y": 2}, - {"label": "l24", "x": 5, "y": 2}, - {"label": "l25", "x": 6, "y": 2}, - {"label": "l26", "x": 7, "y": 2}, - {"label": "l27", "x": 8, "y": 2}, - {"label": "l28", "x": 9, "y": 2}, - {"label": "l29", "x": 10, "y": 2}, - {"label": "l2a", "x": 11, "y": 2}, - {"label": "l2b", "x": 12, "y": 2}, - - {"label": "r20", "x": 15.5, "y": 2}, - {"label": "r21", "x": 16.5, "y": 2}, - {"label": "r22", "x": 17.5, "y": 2}, - {"label": "r23", "x": 18.5, "y": 2}, - {"label": "r24", "x": 19.5, "y": 2}, - {"label": "r25", "x": 20.5, "y": 2}, - {"label": "r26", "x": 21.5, "y": 2}, - {"label": "r27", "x": 22.5, "y": 2}, - {"label": "r28", "x": 23.5, "y": 2}, - {"label": "r29", "x": 24.5, "y": 2}, - {"label": "r2a", "x": 25.5, "y": 2}, - {"label": "r2b", "x": 26.5, "y": 2}, - - {"label": "l30", "x": 1.5, "y": 3}, - {"label": "l31", "x": 2.5, "y": 3}, - {"label": "l32", "x": 3.5, "y": 3}, - {"label": "l33", "x": 4.5, "y": 3}, - {"label": "l34", "x": 5.5, "y": 3}, - {"label": "l35", "x": 6.5, "y": 3}, - {"label": "l36", "x": 7.5, "y": 3}, - {"label": "l37", "x": 8.5, "y": 3}, - {"label": "l38", "x": 9.5, "y": 3}, - {"label": "l39", "x": 10.5, "y": 3}, - {"label": "l3a", "x": 11.5, "y": 3}, - {"label": "l3b", "x": 12.5, "y": 3}, - - {"label": "r30", "x": 16, "y": 3}, - {"label": "r31", "x": 17, "y": 3}, - {"label": "r32", "x": 18, "y": 3}, - {"label": "r33", "x": 19, "y": 3}, - {"label": "r34", "x": 20, "y": 3}, - {"label": "r35", "x": 21, "y": 3}, - {"label": "r36", "x": 22, "y": 3}, - {"label": "r37", "x": 23, "y": 3}, - {"label": "r38", "x": 24, "y": 3}, - {"label": "r39", "x": 25, "y": 3}, - {"label": "r3a", "x": 26, "y": 3}, - {"label": "r3b", "x": 27, "y": 3}, - - {"label": "l40", "x": 2, "y": 4}, - {"label": "l41", "x": 3, "y": 4}, - {"label": "l42", "x": 4, "y": 4}, - {"label": "l43", "x": 5, "y": 4}, - {"label": "l44", "x": 6, "y": 4}, - {"label": "l45", "x": 7, "y": 4}, - {"label": "l46", "x": 8, "y": 4}, - {"label": "l47", "x": 9, "y": 4}, - {"label": "l48", "x": 10, "y": 4}, - {"label": "l49", "x": 11, "y": 4}, - {"label": "l4a", "x": 12, "y": 4}, - {"label": "l4b", "x": 13, "y": 4}, - - {"label": "r40", "x": 16.5, "y": 4}, - {"label": "r41", "x": 17.5, "y": 4}, - {"label": "r42", "x": 18.5, "y": 4}, - {"label": "r43", "x": 19.5, "y": 4}, - {"label": "r44", "x": 20.5, "y": 4}, - {"label": "r45", "x": 21.5, "y": 4}, - {"label": "r46", "x": 22.5, "y": 4}, - {"label": "r47", "x": 23.5, "y": 4}, - {"label": "r48", "x": 24.5, "y": 4}, - {"label": "r49", "x": 25.5, "y": 4}, - {"label": "r4a", "x": 26.5, "y": 4}, - {"label": "r4b", "x": 27.5, "y": 4} - ] - } - } -} diff --git a/keyboards/giabalanai/keymaps/giabarinaix2led/keymap.c b/keyboards/giabalanai/keymaps/giabarinaix2led/keymap.c deleted file mode 100644 index c134c9eeebdc..000000000000 --- a/keyboards/giabalanai/keymaps/giabarinaix2led/keymap.c +++ /dev/null @@ -1,464 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper_giabarinaix2(...) LAYOUT_giabarinaix2(__VA_ARGS__) - -#define DFCBASE DF(_C_SYSTEM_BASE) -#define DF_QWER DF(_QWERTY) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -#ifdef RGBLIGHT_ENABLE -/* used to specify there is no LED on the keylocation. */ -# define NO_LED 255 -#endif // RGBLIGHT_ENABLE -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _C_SYSTEM_BASS2ROW, // counter bass system - _C_SYSTEM_ENTIRELY, // single notes for both left and right keybaords. - _CHROMATONE, - _QWERTY, // just in case - _FN -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION, - CSYSTEM, // C-SYSTEM layout - CNTBASC, // CouNTer BASs C-system layout - CSYSALL, // C-SYStem ALL layout - CHRTONE, // CHRomaTONE layout - TGLMICH // ToGgLe MIdi CHannel separation -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT_giabarinaix2( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Db2, MI_E2, MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, - MI_Eb2, MI_Fs2, MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, - MI_F2, MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, FN_MUTE - ), - - /* BASS2row */ - [_C_SYSTEM_BASS2ROW] = LAYOUT_giabarinaix2( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - - MI_Db2, MI_E2, MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, - MI_Eb2, MI_Fs2, MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, - MI_F2, MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, FN_MUTE - ), - - /* C-system entirely */ - [_C_SYSTEM_ENTIRELY] = LAYOUT_giabarinaix2( - XXXXXXX, XXXXXXX, XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, - XXXXXXX, XXXXXXX, MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, - XXXXXXX, XXXXXXX, MI_D, MI_F, MI_Ab, MI_B, MI_D1, MI_F1, MI_Ab1, MI_B1, MI_D2, MI_F2, - XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, MI_E2, MI_G2, - MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, MI_Fs2, MI_A2, - - MI_E2, MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, - MI_Fs2, MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, - MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5, FN_MUTE - ), - - /* Chromatone */ - [_CHROMATONE] = LAYOUT_giabarinaix2( - XXXXXXX, XXXXXXX, MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, - XXXXXXX, MI_C, MI_D, MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, - XXXXXXX, MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, - MI_C, MI_D, MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, - MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, - - MI_A1, MI_B1, MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, - MI_Bb1, MI_C2, MI_D2, MI_E2, MI_Gb2, MI_Ab2, MI_Bb2, MI_C3, MI_D3, MI_E3, MI_Gb3, MI_Ab3, - MI_B1, MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, - MI_C2, MI_D2, MI_E2, MI_Gb2, MI_Ab2, MI_Bb2, MI_C3, MI_D3, MI_E3, MI_Gb3, MI_Ab3, MI_Bb3, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, FN_MUTE - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper_giabarinaix2( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, KC_RCTL, - - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, _______ - ), - - /* Fn */ - [_FN] = LAYOUT_giabarinaix2( - CSYSTEM, CNTBASC, CSYSALL, CHRTONE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TGLMICH, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - CSYSTEM, CNTBASC, CSYSALL, CHRTONE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, RGB_TOG, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, VERSION, TGLMICH, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______ - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_C_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_ENTIRELY] = { ENCODER_CCW_CW(_______, _______) }, - [_CHROMATONE] = { ENCODER_CCW_CW(_______, _______) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -#ifdef RGBLIGHT_ENABLE - -// Light up fn layer keys -const rgblight_segment_t PROGMEM my_fn_layer[] = RGBLIGHT_LAYER_SEGMENTS( // left keyboard - {0, 4, HSV_ORANGE}, // MIDI layouts - {11, 1, HSV_RED}, // RGB_TOG - {12, 1, HSV_WHITE}, // DF_QWER - {35, 1, HSV_TEAL}, // TGLMICH - - // right keyboard - {60, 4, HSV_ORANGE}, // MIDI layouts - {71 , 1, HSV_RED}, // RGB_TOG - {72, 1, HSV_WHITE}, // DF_QWER - {83, 1, HSV_TEAL} // TGLMICH -); - - -// Now define the array of layers. Later layers take precedence -const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(my_fn_layer); - -layer_state_t layer_state_set_user(layer_state_t state) { - // Both layers will light up if both kb layers are active - rgblight_set_layer_state(0, layer_state_cmp(state, _FN)); - return state; -}; - -#endif // RGBLIGHT_ENABLE -void keyboard_post_init_user(void) { - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - -#ifdef RGBLIGHT_ENABLE - - rgblight_layers = my_rgb_layers; - - // Reset LED off - rgblight_sethsv(HSV_BLACK); -# if defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_sethsv(30, 50, 40); -# ifdef RGBLIGHT_EFFECT_KNIGHT - rgblight_mode(RGBLIGHT_MODE_KNIGHT); -# elif defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_mode(RGBLIGHT_MODE_TWINKLE+3); -# endif -# endif -#endif // RGBLIGHT_ENABLE -}; - -void toggle_MIDI_channel_separation(void) { - if (midi_chord_ch > 0) { - midi_chord_ch = 0; - midi_bass_ch = 0; - } else { - midi_chord_ch = 1; - midi_bass_ch = 2; - } -} - -#ifdef RGBLIGHT_ENABLE -void switch_keylight_color4bass(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_GREEN, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_YELLOW, keylocation); - break; - } -} -void switch_keylight_color4chords(keyrecord_t *record, uint8_t keylocation){ - switch (biton32(default_layer_state)) { - case _C_SYSTEM_BASE: - keylight_manager(record, HSV_SPRINGGREEN, keylocation); - break; - case _C_SYSTEM_BASS2ROW: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; - } -} -#endif // RGBLIGHT_ENABLE - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - - #ifdef RGBLIGHT_ENABLE - /* prepare for turning on LEDs when keys are pressed. */ - uint8_t r = record->event.key.row; - uint8_t c = record->event.key.col; - uint8_t keylocation = pgm_read_byte(&convert_key_to_led[MATRIX_COLS * r + c]); - #endif // RGBLIGHT_ENABLE - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // set default layer and save it to EEPROM when MIDI key layers are selected. - case CSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASE); - } - break; - - case CNTBASC: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); - } - break; - - case CSYSALL: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_ENTIRELY); - } - break; - - case CHRTONE: - if (record->event.pressed) { - set_single_persistent_default_layer(_CHROMATONE); - } - break; - - case TGLMICH: - if (record->event.pressed) { - toggle_MIDI_channel_separation(); - }; - break; - - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, false); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4bass(record, keylocation); -#endif - break; - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); -#ifdef RGBLIGHT_ENABLE - switch_keylight_color4chords(record, keylocation); -#endif - break; - -#ifdef RGBLIGHT_ENABLE - case KC_A ... KC_RGUI: // for QWERTY - case QK_GRAVE_ESCAPE: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - // Keycodes on the right side. -#ifdef RGBLIGHT_ENABLE - case MIDI_TONE_MIN ... MIDI_TONE_MAX: // notes on the right side. - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; - // case KC_MUTE: - case FN_MUTE: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - } - return true; -} diff --git a/keyboards/giabalanai/keymaps/giabarinaix2led/readme.md b/keyboards/giabalanai/keymaps/giabarinaix2led/readme.md deleted file mode 100644 index 89139ec1b3b6..000000000000 --- a/keyboards/giabalanai/keymaps/giabarinaix2led/readme.md +++ /dev/null @@ -1 +0,0 @@ -# A keymap for giabarinaix2 with LEDs. diff --git a/keyboards/giabalanai/keymaps/giabarinaix2led/rules.mk b/keyboards/giabalanai/keymaps/giabarinaix2led/rules.mk deleted file mode 100644 index d8dc6a10e76a..000000000000 --- a/keyboards/giabalanai/keymaps/giabarinaix2led/rules.mk +++ /dev/null @@ -1,3 +0,0 @@ -RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/party/keymap.c b/keyboards/giabalanai/keymaps/party/keymap.c deleted file mode 100644 index e4ff33693059..000000000000 --- a/keyboards/giabalanai/keymaps/party/keymap.c +++ /dev/null @@ -1,818 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "print.h" -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) - -#define DF_QWER DF(_QWERTY) -#define DF_COLE DF(_COLEMAK) -#define MO_ADJ MO(_ADJUST) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) -#define SHIF_UP RSFT_T(KC_UP) -#define ADJ_EIS LT(_ADJUST,KC_LNG2) -#define MIS_KAN LT(_MISC,KC_LNG1) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// UNISON flags -static bool melody_dyad_high = false; // true when +1 octave unison dyad is enabled. -static bool melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - -static bool melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - -// To record the status of Bass Chord (single or dyad, default: dyad.) -typedef union { - uint32_t raw; - struct { - bool isSingleBass:1; - }; -} user_config_t; -user_config_t user_config; - -#define IS_SINGLE_BASS() (user_config.isSingleBass) - -#ifdef RGBLIGHT_ENABLE -/* used to specify there is no LED on the keylocation. */ -# define NO_LED 255 -#endif // RGBLIGHT_ENABLE - - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _FAKE_B_SYSTEM, // MIDI fake B-system doesn't have correct assignments on top two rows. The bottom 3 rows are B-system. - _C_SYSTEM_BASS2ROW, // counter bass system - _FAKE_B_SYSTEM_BASS2ROW, // MIDI fake B-system doesn't have correct assignments on top two rows. The bottom 3 rows are B-system. Counter bass version. - _C_SYSTEM_ENTIRELY, // single notes for both left and right keybaords. - _C_SYSTEM_FREEBASS, // C-system Free Bass - _CHROMATONE, - _CFLIP_BASS2ROW, // 180 degree flipped layout on right side keyboard - _QWERTY, - _COLEMAK, - _ADJUST, // for Fn keys, etc. - _FN // for changing layers, octaves, etc. -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION, - CSYSTEM, // C-SYSTEM layout - BSYSTEM, // B-SYSTEM layout - CNTBASC, // CouNTer BASs C-system layout - CNTBASB, // CouNTer BASs B-system layout - CSYSALL, // C-SYStem ALL layout - CSYSFBS, // C-SYStem Free BaSs - CHRTONE, // CHRomaTONE layout - CFLIP2B, // C-system FLIPped 2(to) Backwards - TGLBASS, // ToGgLe BASS unison - TGLMICH, // ToGgLe MIdi CHannel separation - MELDYAL, // MELody DYad Low - MELODYS, // MELODY Single - MELDYAH, // MELody DYad High - TGLUVEL // ToGgLe Unison VELocity -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; -static uint8_t my_tone_status[MIDI_TONE_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* fake B-system */ - [_FAKE_B_SYSTEM] = LAYOUT( - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - - MI_Ab2, - MI_A2, MI_C3, MI_Eb3, MI_Gb3, MI_A3, MI_C4, MI_Eb4, MI_Gb4, MI_A4, MI_C5, MI_Eb5, MI_Gb5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5 - ), - - /* BASS2row */ - [_C_SYSTEM_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* fake B-system */ - [_FAKE_B_SYSTEM_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_Ab2, - MI_A2, MI_C3, MI_Eb3, MI_Gb3, MI_A3, MI_C4, MI_Eb4, MI_Gb4, MI_A4, MI_C5, MI_Eb5, MI_Gb5, _______, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5 - ), - - /* C-system entirely */ - [_C_SYSTEM_ENTIRELY] = LAYOUT( - MI_BNDU, XXXXXXX, XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, - MI_BNDD, XXXXXXX, MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, - XXXXXXX, XXXXXXX, MI_D, MI_F, MI_Ab, MI_B, MI_D1, MI_F1, MI_Ab1, MI_B1, MI_D2, MI_F2, - XXXXXXX, MI_Db, MI_E, MI_G, MI_Bb, MI_Db1, MI_E1, MI_G1, MI_Bb1, MI_Db2, MI_E2, MI_G2, - MI_C, MI_Eb, MI_Fs, MI_A, MI_C1, MI_Eb1, MI_Fs1, MI_A1, MI_C2, MI_Eb2, MI_Fs2, MI_A2, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* C-system free bass */ - [_C_SYSTEM_FREEBASS] = LAYOUT( - MI_Db3, MI_Bb2, MI_G2, MI_E2, MI_Db2, MI_Bb1, MI_G1, MI_E1, MI_Db1, MI_Bb, MI_G, MI_E, - MI_C3, MI_A2, MI_Fs2, MI_Eb2, MI_C2, MI_A1, MI_Fs1, MI_Eb1, MI_C1, MI_A, MI_Fs, MI_Eb, - MI_B2, MI_Ab2, MI_F2, MI_D2, MI_B1, MI_Ab1, MI_F1, MI_D1, MI_B, MI_Ab, MI_F, MI_D, - MI_Bb2, MI_G2, MI_E2, MI_Db2, MI_Bb1, MI_G1, MI_E1, MI_Db1, MI_Bb, MI_G, MI_E, MI_Db, - MI_A2, MI_Fs2, MI_Eb2, MI_C2, MI_A1, MI_Fs1, MI_Eb1, MI_C1, MI_A, MI_Fs, MI_Eb, MI_C, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* Chromatone */ - [_CHROMATONE] = LAYOUT( - MI_Db, MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, - MI_D, MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, - MI_Eb, MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, - MI_E, MI_Fs, MI_Ab, MI_Bb, MI_C1, MI_D1, MI_E1, MI_Fs1, MI_Ab1, MI_Bb1, MI_C2, MI_D2, - MI_F, MI_G, MI_A, MI_B, MI_Db1, MI_Eb1, MI_F1, MI_G1, MI_A1, MI_B1, MI_Db2, MI_Eb2, - - MI_C2, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3, FN_MUTE, - MI_C2, MI_D2, MI_E2, MI_Gb2, MI_Ab2, MI_Bb2, MI_C3, MI_D3, MI_E3, MI_Gb3, MI_Ab3, MI_Bb3, MI_C4, - MI_Db2, MI_Eb2, MI_F2, MI_G2, MI_A2, MI_B2, MI_Db3, MI_Eb3, MI_F3, MI_G3, MI_A3, MI_B3 - ), - - [_CFLIP_BASS2ROW] = LAYOUT( - MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, MI_CH_Csr, MI_CH_Gsr, MI_CH_Dsr, MI_CH_Asr, - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - - MI_G5, - MI_F5, MI_D5, MI_B4, MI_Ab4, MI_F4, MI_D4, MI_B3, MI_Ab3, MI_F3, MI_D3, MI_B2, MI_Ab2, FN_MUTE, - MI_Fs5, MI_Eb5, MI_C5, MI_A4, MI_Fs4, MI_Eb4, MI_C4, MI_A3, MI_Fs3, MI_Eb3, MI_C3, MI_A2, MI_Fs2, - MI_E5, MI_Db5, MI_Bb4, MI_G4, MI_E4, MI_Db4, MI_Bb3, MI_G3, MI_E3, MI_Db3, MI_Bb2, MI_G2 - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* COLEMAK */ - [_COLEMAK] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________COLEMAK_L1________________, _________________COLEMAK_R1________________, KC_DEL, - KC_LCTL, _________________COLEMAK_L2________________, _________________COLEMAK_R2________________, KC_ENT, - KC_LSFT, _________________COLEMAK_L3________________, _________________COLEMAK_R3________________, SHIF_UP, - KC_CAPS, KC_LGUI, KC_LALT, ADJ_EIS, KC_SPC, KC_SPC, KC_LNG1, KC_APP, MO_ADJ, KC_LEFT, KC_DOWN, KC_RGHT, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - /* ADJUST */ - [_ADJUST] = LAYOUT_wrapper( - _______, _________________FUNC__L___________________, _________________FUNC__R___________________, _______, - _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_MINS, KC_EQL, _______, - _______, KC_VOLD, KC_VOLU, KC_MUTE, XXXXXXX, XXXXXXX, KC_LEFT, KC_DOWN, KC_UP, KC_RGHT, KC_GRV, _______, - _______, KC_BRID, KC_BRIU, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, KC_LBRC, KC_RBRC, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_QUOT, KC_BSLS, _______, - - _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ - ), - - - /* Fn */ - [_FN] = LAYOUT( - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, CSYSFBS, CNTBASB, XXXXXXX, XXXXXXX, RGB_MOD, RGB_TOG, - DF_QWER, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_COLE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, TGLMICH, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - XXXXXXX, - MI_OCN2, MI_OCN1, MI_OC0, MI_OC1, MI_OC2, XXXXXXX, XXXXXXX, MI_OCTD, MI_OCTU, XXXXXXX, VERSION, EE_CLR, _______, - CSYSTEM, BSYSTEM, CNTBASC, CSYSALL, CHRTONE, CFLIP2B, CSYSFBS, CNTBASB, XXXXXXX, MI_VELD, MI_VELU, RGB_MOD, RGB_TOG, - XXXXXXX, TGLBASS, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, MI_TRSD, MI_TRSU, TGLUVEL, MELDYAL, MELODYS, MELDYAH - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_FAKE_B_SYSTEM] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_FAKE_B_SYSTEM_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_ENTIRELY] = { ENCODER_CCW_CW(_______, _______) }, - [_C_SYSTEM_FREEBASS] = { ENCODER_CCW_CW(_______, _______) }, - [_CHROMATONE] = { ENCODER_CCW_CW(_______, _______) }, - [_CFLIP_BASS2ROW] = { ENCODER_CCW_CW(_______, _______) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_COLEMAK] = { ENCODER_CCW_CW(_______, _______) }, - [_ADJUST] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(RGB_RMOD, RGB_MOD) }, -}; -#endif - -#ifdef RGBLIGHT_ENABLE - -// Light up adjust layer keys (left keyboard) -const rgblight_segment_t PROGMEM my_adjust_layer[] = RGBLIGHT_LAYER_SEGMENTS({1, 10, HSV_ORANGE}, - {21, 2, HSV_ORANGE}, - {25, 3, HSV_ORANGE}, - {30, 5, HSV_ORANGE}, - {37, 2, HSV_ORANGE}, - {45, 2, HSV_ORANGE}, - {57, 2, HSV_ORANGE} -); - -// Light up fn layer keys -const rgblight_segment_t PROGMEM my_fn_layer[] = RGBLIGHT_LAYER_SEGMENTS( // left keyboard - {0, 8, HSV_ORANGE}, // MIDI layouts - {11, 1, HSV_RED}, // RGB_TOG - {12, 1, HSV_WHITE}, // DF_QWER - {13, 1, HSV_CORAL}, // TGLBASS - {24, 1, HSV_WHITE}, // DF_COLE - {35, 1, HSV_TEAL}, // TGLMICH -#if 0 // Color Test - {36, 1, HSV_WHITE}, - {37, 1, HSV_RED}, - {38, 1, HSV_CORAL}, - {39, 1, HSV_ORANGE}, - {40, 1, HSV_GOLDENROD}, - {41, 1, HSV_GOLD}, - {42, 1, HSV_YELLOW}, - {43, 1, HSV_CHARTREUSE}, - {44, 1, HSV_GREEN}, - {45, 1, HSV_SPRINGGREEN}, - {46, 1, HSV_TURQUOISE}, - {47, 1, HSV_TEAL}, - {48, 1, HSV_CYAN}, - {49, 1, HSV_AZURE}, - {50, 1, HSV_BLUE}, - {51, 1, HSV_PURPLE}, - {52, 1, HSV_MAGENTA}, - {53, 1, HSV_PINK}, -#endif - // right keyboard - {60, 8, HSV_ORANGE}, // MIDI layouts - {74, 1, HSV_CORAL}, // TGLBASS - {85, 1, HSV_BLUE}, // MIDI Oct - {86, 1, HSV_CYAN}, // MIDI Oct - {87, 1, HSV_SPRINGGREEN}, // MIDI Oct - {88, 1, HSV_GREEN}, // MIDI Oct - {89, 1, HSV_CHARTREUSE}, // MIDI Oct - {95, 1, HSV_GOLD}, // VERSION - {96, 1, HSV_PINK}, // EE_CLR - {98, 8, HSV_ORANGE}, // MIDI layouts - {107, 1, HSV_YELLOW}, // MI_VELD - {108, 1, HSV_GREEN}, // MI_VELU - {110, 1, HSV_RED}, // RGB_TOG - {112, 1, HSV_CORAL}, // TGLBASS - {119, 1, HSV_CORAL}, // TGLUVEL - {120, 1, HSV_CYAN}, // MELDYAL - {121, 1, HSV_GOLD}, // MELODYS - {122, 1, HSV_SPRINGGREEN} // MELDYAH -); - -// Now define the array of layers. Later layers take precedence -const rgblight_segment_t* const PROGMEM my_rgb_layers[] = RGBLIGHT_LAYERS_LIST(my_fn_layer, my_adjust_layer); - -layer_state_t layer_state_set_user(layer_state_t state) { - // Both layers will light up if both kb layers are active - rgblight_set_layer_state(0, layer_state_cmp(state, _FN)); - rgblight_set_layer_state(1, layer_state_cmp(state, _ADJUST)); - return state; -}; - -#endif // RGBLIGHT_ENABLE - -void my_init(void){ - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; -} - -void eeconfig_init_user(void) { - midi_init(); - my_init(); - - // Used to set octave to 0 - midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - - // UNISON flags - melody_dyad_high = false; // true when +1 octave unison dyad is enabled. - melody_dyad_low = false; // true when -1 octave unison dyad is enabled. - melody_unison_suppress = true; // true: velocity of octave unison note is suppressd to UNISON_VELOCITY_RATIO - - // Reset Bass setting - user_config.raw = 0; // default: dyad - eeconfig_update_user(user_config.raw); - - // Reset the midi keyboard layout - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); - -#ifdef RGB_MATRIX_ENABLE - rgb_matrix_sethsv(HSV_BLUE); - // party mode (for LED soldering test.) - rgb_matrix_mode(RGB_MATRIX_RAINBOW_MOVING_CHEVRON); -#endif -} - -#ifdef RGB_MATRIX_ENABLE -bool rgb_matrix_indicators_user(void) { - uint8_t i; - // uint32_t mode = rgblight_get_mode(); - - if (rgb_matrix_is_enabled()) { // turn the lights on when it is enabled. - - uint8_t layer = biton32(layer_state); - - switch (layer) { - case _ADJUST: - rgb_matrix_set_color(30, RGB_DARKORANGE); - rgb_matrix_set_color(34, RGB_DARKORANGE); - // rgb_matrix_set_color(72, RGB_DARKORANGE); - break; - case _FN: - for (i = 0;i < 8;i++) { - rgb_matrix_set_color(74 - i, RGB_DARKORANGE); // MIDI layouts - // right keyboard - rgb_matrix_set_color(i, RGB_DARKORANGE); // MIDI layouts - rgb_matrix_set_color(50 - i, RGB_DARKORANGE); // MIDI layouts - } - - // rgb_matrix_set_color(pgm_read_byte(&convert_led_location2number[11]), RGB_RED); // RGB_TOG <- too heavy. - rgb_matrix_set_color(64, RGB_DARKBLUE); // RGB_MOD - rgb_matrix_set_color(63, RGB_DARKRED); // RGB_TOG - rgb_matrix_set_color(76, RGB_DARKCORAL); // TGLBASS - - rgb_matrix_set_color(75, RGB_DARKWHITE); // DF_QWER - rgb_matrix_set_color(98, RGB_DARKWHITE); // DF_COLE - rgb_matrix_set_color(87, RGB_DARKTEAL); // TGLMICH - - rgb_matrix_set_color(23, RGB_DARKCORAL); // TGLBASS - rgb_matrix_set_color(26, RGB_DARKBLUE); // MIDI Oct - rgb_matrix_set_color(27, RGB_DARKCYAN); // MIDI Oct - rgb_matrix_set_color(28, RGB_DARKSPRINGGREEN); // MIDI Oct - rgb_matrix_set_color(29, RGB_DARKGREEN); // MIDI Oct - rgb_matrix_set_color(30, RGB_DARKCHARTREUSE); // MIDI Oct - rgb_matrix_set_color(36, RGB_DARKGOLD); // VERSION - rgb_matrix_set_color(37, RGB_DARKPINK); // EE_CLR - rgb_matrix_set_color(41, RGB_DARKYELLOW); // MI_VELD - rgb_matrix_set_color(40, RGB_DARKGREEN); // MI_VELU - rgb_matrix_set_color(39, RGB_DARKBLUE); // RGB_MOD - rgb_matrix_set_color(38, RGB_DARKRED); // RGB_TOG - rgb_matrix_set_color(52, RGB_DARKCORAL); // TGLBASS - rgb_matrix_set_color(59, RGB_DARKCORAL); // TGLUVEL - rgb_matrix_set_color(60, RGB_DARKCYAN); // MELDYAL - rgb_matrix_set_color(61, RGB_DARKGOLD); // MELODYS - rgb_matrix_set_color(62, RGB_DARKSPRINGGREEN); // MELDYAH - break; - } - } - return false; -} -#endif - -void keyboard_post_init_user(void) { - my_init(); - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++) { - my_tone_status[i] = MIDI_INVALID_NOTE; - } - // load EEPROM data for isSingleBass - user_config.raw = eeconfig_read_user(); - -#ifdef RGBLIGHT_ENABLE - - rgblight_layers = my_rgb_layers; - - // Reset LED off - rgblight_sethsv(HSV_BLACK); -# if defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_sethsv(30, 50, 40); -# ifdef RGBLIGHT_EFFECT_KNIGHT - rgblight_mode(RGBLIGHT_MODE_KNIGHT); -# elif defined(RGBLIGHT_EFFECT_TWINKLE) - rgblight_mode(RGBLIGHT_MODE_TWINKLE+3); -# endif -# endif -#endif // RGBLIGHT_ENABLE - -#ifdef RGB_MATRIX_ENABLE - rgb_matrix_sethsv(HSV_BLUE); - // party mode (for LED soldering test.) - rgb_matrix_mode(RGB_MATRIX_RAINBOW_MOVING_CHEVRON); -#endif -}; - -void toggle_isSingleBass(void) { -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(before) %u\n", user_config.isSingleBass); -#endif - user_config.isSingleBass = !user_config.isSingleBass; -#ifdef CONSOLE_ENABLE - uprintf("isSingleBass(after) %u\n", user_config.isSingleBass); -#endif - - eeconfig_update_user(user_config.raw); -} - -void toggle_MIDI_channel_separation(void) { - if (midi_chord_ch > 0) { - midi_chord_ch = 0; - midi_bass_ch = 0; - } else { - midi_chord_ch = 1; - midi_bass_ch = 2; - } -} - -#ifdef RGBLIGHT_ENABLE -void keylight_manager(keyrecord_t *record, uint8_t hue, uint8_t sat, uint8_t val, uint8_t keylocation) { - if (keylocation == NO_LED) { - return; // do nothing. -# ifdef CONSOLE_ENABLE - uprintf("keylight_manager, NO_LED\n"); -# endif - } - - if (record->event.pressed) { - rgblight_sethsv_at(hue, sat, val, keylocation); - } else { - rgblight_sethsv_at(HSV_BLACK, keylocation); - } -} -#endif // RGBLIGHT_ENABLE - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - -#ifdef RGBLIGHT_ENABLE - /* prepare for turning on LEDs when keys are pressed. */ - uint8_t r = record->event.key.row; - uint8_t c = record->event.key.col; - // uint8_t keylocation = convert_key_to_led[MATRIX_COLS * r + c]; - // uint8_t keylocation2 = convert_key_to_led2[MATRIX_COLS * r + c]; - uint8_t keylocation = pgm_read_byte(&convert_key_to_led[MATRIX_COLS * r + c]); - uint8_t keylocation2 = pgm_read_byte(&convert_key_to_led2[MATRIX_COLS * r + c]); -#endif // RGBLIGHT_ENABLE - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // set default layer and save it to EEPROM when MIDI key layers are selected. - case CSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASE); - } - break; - - case BSYSTEM: - if (record->event.pressed) { - set_single_persistent_default_layer(_FAKE_B_SYSTEM); - } - break; - - case CNTBASC: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_BASS2ROW); - } - break; - - case CNTBASB: - if (record->event.pressed) { - set_single_persistent_default_layer(_FAKE_B_SYSTEM_BASS2ROW); - } - break; - - case CSYSALL: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_ENTIRELY); - } - break; - - case CHRTONE: - if (record->event.pressed) { - set_single_persistent_default_layer(_CHROMATONE); - } - break; - - case CFLIP2B: - if (record->event.pressed) { - set_single_persistent_default_layer(_CFLIP_BASS2ROW); - } - break; - - case CSYSFBS: - if (record->event.pressed) { - set_single_persistent_default_layer(_C_SYSTEM_FREEBASS); - } - break; - - case TGLBASS: - if (record->event.pressed) { - toggle_isSingleBass(); - }; - break; - - case TGLMICH: - if (record->event.pressed) { - toggle_MIDI_channel_separation(); - }; - break; - - case MELDYAL: - if (record->event.pressed) { - melody_dyad_low = true; - melody_dyad_high = false; - }; - break; - - case MELODYS: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = false; - }; - break; - - case MELDYAH: - if (record->event.pressed) { - melody_dyad_low = false; - melody_dyad_high = true; - }; - break; - - case TGLUVEL: - if (record->event.pressed) { - melody_unison_suppress = !melody_unison_suppress; - }; - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, IS_SINGLE_BASS()); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); -#endif - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); -#endif - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); -#endif - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); -#endif - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); -#endif - break; - -#ifdef RGBLIGHT_ENABLE - case KC_A ... KC_RGUI: // for QWERTY - case QK_GRAVE_ESCAPE: - case ADJ_EIS: - case MO_ADJ: - case SHIF_UP: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - - // Keycodes on the right side. - case MIDI_TONE_MIN ... MIDI_TONE_MAX: // notes on the right side keyboard. - // root_note is played by process_midi(). - if ( melody_dyad_high == true ) { // play 1 octave higher as well. - my_process_midi(0, keycode, record, my_tone_status, 12, melody_unison_suppress); - } else if ( melody_dyad_low == true ) { // play 1 octave lower as well. - my_process_midi(0, keycode, record, my_tone_status, -12, melody_unison_suppress); - } -#ifdef RGBLIGHT_ENABLE - keylight_manager(record, HSV_GOLDENROD, keylocation); - keylight_manager(record, HSV_GOLDENROD, keylocation2); -#endif - break; - -#ifdef RGBLIGHT_ENABLE - // case KC_MUTE: - case FN_MUTE: - keylight_manager(record, HSV_GOLDENROD, keylocation); - break; -#endif - } - // If console is enabled, it will print the matrix position and status of each key pressed -#if defined(CONSOLE_ENABLE) && defined(RGBLIGHT_ENABLE) - uprintf("KL: kc: %u, col: %u, row: %u, pressed: %u\n", keycode, record->event.key.col, record->event.key.row, record->event.pressed); - uprintf("r=%d, c=%d, keyloc=%d, keyloc2=%d, matrix_col x r + c = %d\n", r, c, keylocation, keylocation2, MATRIX_COLS * r + c); -#endif - return true; -} diff --git a/keyboards/giabalanai/keymaps/party/readme.md b/keyboards/giabalanai/keymaps/party/readme.md deleted file mode 100644 index 797fed76f83e..000000000000 --- a/keyboards/giabalanai/keymaps/party/readme.md +++ /dev/null @@ -1,3 +0,0 @@ -# The fancy LED ver. for giabalanai -# warning: There is little space left for the firmware. You can't do anything further with this firmware. -# Power consumption might exceed 5 V * 500 mA = 2.5 W or so. diff --git a/keyboards/giabalanai/keymaps/party/rgb_matrix_user.inc b/keyboards/giabalanai/keymaps/party/rgb_matrix_user.inc deleted file mode 100644 index 6159968a69bc..000000000000 --- a/keyboards/giabalanai/keymaps/party/rgb_matrix_user.inc +++ /dev/null @@ -1,57 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -RGB_MATRIX_EFFECT(my_solid_reactive_with_CnoteIndicator) -RGB_MATRIX_EFFECT(my_party_rocks) - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -bool my_solid_reactive_with_CnoteIndicator(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint16_t max_tick = 65535 / rgb_matrix_config.speed; - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - HSV hsv = rgb_matrix_config.hsv; - switch (i) { - // C note indicator - case 15: - case 19: - case 23: - case 52: - case 56: - case 60: - case 80: // left hand side, bass C note when counter bass is chosen. - // HSV_GOLDENROD - hsv.h = 30; - hsv.s = 218; - hsv.v = 218; - break; - } - uint16_t tick = max_tick; - // Reverse search to find most recent key hit - for (int8_t j = g_last_hit_tracker.count - 1; j >= 0; j--) { - if (g_last_hit_tracker.x[j] == g_led_config.point[i].x && g_last_hit_tracker.y[j] == g_led_config.point[i].y && g_last_hit_tracker.tick[j] < tick) { - tick = g_last_hit_tracker.tick[j]; - break; - } - } - - uint16_t offset = scale16by8(tick, rgb_matrix_config.speed); - hsv.h += qsub8(130, offset); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return led_max < RGB_MATRIX_LED_COUNT; -} - -bool my_party_rocks(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - HSV hsv = {rand() & 0xFF, rand() & 0xFF, rgb_matrix_config.hsv.v}; - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - // rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - rgb_matrix_set_color_all(rgb.r, rgb.g, rgb.b); - return led_max < RGB_MATRIX_LED_COUNT; -} - - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/keyboards/giabalanai/keymaps/party/rules.mk b/keyboards/giabalanai/keymaps/party/rules.mk deleted file mode 100644 index c05207feebe5..000000000000 --- a/keyboards/giabalanai/keymaps/party/rules.mk +++ /dev/null @@ -1,6 +0,0 @@ -# RGBLIGHT_ENABLE = yes # Enable keyboard RGB underglow -CONSOLE_ENABLE = no # Console for debug -RGB_MATRIX_ENABLE = yes # Use RGB matrix (Don't enable this when RGBLIGHT_ENABLE is used.) -RGB_MATRIX_CUSTOM_USER = yes # - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/via/keymap.c b/keyboards/giabalanai/keymaps/via/keymap.c deleted file mode 100644 index 332ad45e3c7f..000000000000 --- a/keyboards/giabalanai/keymaps/via/keymap.c +++ /dev/null @@ -1,260 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper(...) LAYOUT(__VA_ARGS__) - -#define DFCBASE DF(_C_SYSTEM_BASE) -#define DF_QWER DF(_QWERTY) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _QWERTY, // just in case - _FN -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION = QK_KB_0 -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Fs2, - MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, MI_F5, FN_MUTE, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, MI_G5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, MI_Fs5 - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, KC_RCTL, - - QK_GESC, - _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_MINS, KC_BSPC, _______, - KC_LCTL, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_QUOT, KC_ENT, - KC_LALT, _________________QWERTY_L3_________________, KC_N, KC_M, KC_COMM, KC_DOT, KC_SPC, KC_RSFT - ), - - /* Fn */ - [_FN] = LAYOUT( - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - _______, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, VERSION, XXXXXXX, _______, - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -void keyboard_post_init_user(void) { - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; - - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - default_layer_set(1UL << _C_SYSTEM_BASE); -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, false); - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); - break; - } - return true; -} diff --git a/keyboards/giabalanai/keymaps/via/readme.md b/keyboards/giabalanai/keymaps/via/readme.md deleted file mode 100644 index 3c599bfe0e37..000000000000 --- a/keyboards/giabalanai/keymaps/via/readme.md +++ /dev/null @@ -1 +0,0 @@ -# The default VIA keymap for giabalanai diff --git a/keyboards/giabalanai/keymaps/via/rules.mk b/keyboards/giabalanai/keymaps/via/rules.mk deleted file mode 100644 index da4a83087f41..000000000000 --- a/keyboards/giabalanai/keymaps/via/rules.mk +++ /dev/null @@ -1,3 +0,0 @@ -VIA_ENABLE = yes - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/keymaps/via_giabarinaix2/config.h b/keyboards/giabalanai/keymaps/via_giabarinaix2/config.h deleted file mode 100644 index 01905b8dfec3..000000000000 --- a/keyboards/giabalanai/keymaps/via_giabarinaix2/config.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -#define DYNAMIC_KEYMAP_LAYER_COUNT 3 -#define GIABARINAIX2 -#ifdef GIABARINAIX2 -# undef MATRIX_ROW_PINS_RIGHT -# undef MATRIX_COL_PINS_RIGHT - -# ifdef RGBLIGHT_ENABLE -# undef RGBLED_NUM -# define RGBLED_NUM 120 -# undef RGBLIGHT_LED_MAP -# define RGBLIGHT_LED_MAP { \ - 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, \ - 107, 106, 105, 104, 103, 102, 101, 100, 99, 98, 97, 96, \ - 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, \ - 83, 82, 81, 80, 79, 78, 77, 76, 75, 74, 73, 72, \ - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, \ - \ - 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, \ - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, \ - 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, \ - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, \ - 59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48 \ - } -# endif -#endif diff --git a/keyboards/giabalanai/keymaps/via_giabarinaix2/info.json b/keyboards/giabalanai/keymaps/via_giabarinaix2/info.json deleted file mode 100644 index 6581733dd1c5..000000000000 --- a/keyboards/giabalanai/keymaps/via_giabarinaix2/info.json +++ /dev/null @@ -1,146 +0,0 @@ -{ - "keyboard_name": "giabarinaix2", - "manufacturer": "3araht", - "url": "https://github.com/3araht", - "maintainer": "3araht", - "usb": { - "vid": "0xFEED", - "pid": "0xF4B2", - "device_version": "0.0.1" - }, - "layouts": { - "LAYOUT": { - "layout": [ - {"label": "l00", "x": 0, "y": 0}, - {"label": "l01", "x": 1, "y": 0}, - {"label": "l02", "x": 2, "y": 0}, - {"label": "l03", "x": 3, "y": 0}, - {"label": "l04", "x": 4, "y": 0}, - {"label": "l05", "x": 5, "y": 0}, - {"label": "l06", "x": 6, "y": 0}, - {"label": "l07", "x": 7, "y": 0}, - {"label": "l08", "x": 8, "y": 0}, - {"label": "l09", "x": 9, "y": 0}, - {"label": "l0a", "x": 10, "y": 0}, - {"label": "l0b", "x": 11, "y": 0}, - - {"label": "r00", "x": 14.5, "y": 0}, - {"label": "r01", "x": 15.5, "y": 0}, - {"label": "r02", "x": 16.5, "y": 0}, - {"label": "r03", "x": 17.5, "y": 0}, - {"label": "r04", "x": 18.5, "y": 0}, - {"label": "r05", "x": 19.5, "y": 0}, - {"label": "r06", "x": 20.5, "y": 0}, - {"label": "r07", "x": 21.5, "y": 0}, - {"label": "r08", "x": 22.5, "y": 0}, - {"label": "r09", "x": 23.5, "y": 0}, - {"label": "r0a", "x": 24.5, "y": 0}, - {"label": "r0b", "x": 25.5, "y": 0}, - - {"label": "l10", "x": 0.5, "y": 1}, - {"label": "l11", "x": 1.5, "y": 1}, - {"label": "l12", "x": 2.5, "y": 1}, - {"label": "l13", "x": 3.5, "y": 1}, - {"label": "l14", "x": 4.5, "y": 1}, - {"label": "l15", "x": 5.5, "y": 1}, - {"label": "l16", "x": 6.5, "y": 1}, - {"label": "l17", "x": 7.5, "y": 1}, - {"label": "l18", "x": 8.5, "y": 1}, - {"label": "l19", "x": 9.5, "y": 1}, - {"label": "l1a", "x": 10.5, "y": 1}, - {"label": "l1b", "x": 11.5, "y": 1}, - - {"label": "r10", "x": 15, "y": 1}, - {"label": "r11", "x": 16, "y": 1}, - {"label": "r12", "x": 17, "y": 1}, - {"label": "r13", "x": 18, "y": 1}, - {"label": "r14", "x": 19, "y": 1}, - {"label": "r15", "x": 20, "y": 1}, - {"label": "r16", "x": 21, "y": 1}, - {"label": "r17", "x": 22, "y": 1}, - {"label": "r18", "x": 23, "y": 1}, - {"label": "r19", "x": 24, "y": 1}, - {"label": "r1a", "x": 25, "y": 1}, - {"label": "r1b", "x": 26, "y": 1}, - - {"label": "l20", "x": 1, "y": 2}, - {"label": "l21", "x": 2, "y": 2}, - {"label": "l22", "x": 3, "y": 2}, - {"label": "l23", "x": 4, "y": 2}, - {"label": "l24", "x": 5, "y": 2}, - {"label": "l25", "x": 6, "y": 2}, - {"label": "l26", "x": 7, "y": 2}, - {"label": "l27", "x": 8, "y": 2}, - {"label": "l28", "x": 9, "y": 2}, - {"label": "l29", "x": 10, "y": 2}, - {"label": "l2a", "x": 11, "y": 2}, - {"label": "l2b", "x": 12, "y": 2}, - - {"label": "r20", "x": 15.5, "y": 2}, - {"label": "r21", "x": 16.5, "y": 2}, - {"label": "r22", "x": 17.5, "y": 2}, - {"label": "r23", "x": 18.5, "y": 2}, - {"label": "r24", "x": 19.5, "y": 2}, - {"label": "r25", "x": 20.5, "y": 2}, - {"label": "r26", "x": 21.5, "y": 2}, - {"label": "r27", "x": 22.5, "y": 2}, - {"label": "r28", "x": 23.5, "y": 2}, - {"label": "r29", "x": 24.5, "y": 2}, - {"label": "r2a", "x": 25.5, "y": 2}, - {"label": "r2b", "x": 26.5, "y": 2}, - - {"label": "l30", "x": 1.5, "y": 3}, - {"label": "l31", "x": 2.5, "y": 3}, - {"label": "l32", "x": 3.5, "y": 3}, - {"label": "l33", "x": 4.5, "y": 3}, - {"label": "l34", "x": 5.5, "y": 3}, - {"label": "l35", "x": 6.5, "y": 3}, - {"label": "l36", "x": 7.5, "y": 3}, - {"label": "l37", "x": 8.5, "y": 3}, - {"label": "l38", "x": 9.5, "y": 3}, - {"label": "l39", "x": 10.5, "y": 3}, - {"label": "l3a", "x": 11.5, "y": 3}, - {"label": "l3b", "x": 12.5, "y": 3}, - - {"label": "r30", "x": 16, "y": 3}, - {"label": "r31", "x": 17, "y": 3}, - {"label": "r32", "x": 18, "y": 3}, - {"label": "r33", "x": 19, "y": 3}, - {"label": "r34", "x": 20, "y": 3}, - {"label": "r35", "x": 21, "y": 3}, - {"label": "r36", "x": 22, "y": 3}, - {"label": "r37", "x": 23, "y": 3}, - {"label": "r38", "x": 24, "y": 3}, - {"label": "r39", "x": 25, "y": 3}, - {"label": "r3a", "x": 26, "y": 3}, - {"label": "r3b", "x": 27, "y": 3}, - - {"label": "l40", "x": 2, "y": 4}, - {"label": "l41", "x": 3, "y": 4}, - {"label": "l42", "x": 4, "y": 4}, - {"label": "l43", "x": 5, "y": 4}, - {"label": "l44", "x": 6, "y": 4}, - {"label": "l45", "x": 7, "y": 4}, - {"label": "l46", "x": 8, "y": 4}, - {"label": "l47", "x": 9, "y": 4}, - {"label": "l48", "x": 10, "y": 4}, - {"label": "l49", "x": 11, "y": 4}, - {"label": "l4a", "x": 12, "y": 4}, - {"label": "l4b", "x": 13, "y": 4}, - - {"label": "r40", "x": 16.5, "y": 4}, - {"label": "r41", "x": 17.5, "y": 4}, - {"label": "r42", "x": 18.5, "y": 4}, - {"label": "r43", "x": 19.5, "y": 4}, - {"label": "r44", "x": 20.5, "y": 4}, - {"label": "r45", "x": 21.5, "y": 4}, - {"label": "r46", "x": 22.5, "y": 4}, - {"label": "r47", "x": 23.5, "y": 4}, - {"label": "r48", "x": 24.5, "y": 4}, - {"label": "r49", "x": 25.5, "y": 4}, - {"label": "r4a", "x": 26.5, "y": 4}, - {"label": "r4b", "x": 27.5, "y": 4} - ] - } - } -} diff --git a/keyboards/giabalanai/keymaps/via_giabarinaix2/keymap.c b/keyboards/giabalanai/keymaps/via_giabarinaix2/keymap.c deleted file mode 100644 index fcf6a35ff2a4..000000000000 --- a/keyboards/giabalanai/keymaps/via_giabarinaix2/keymap.c +++ /dev/null @@ -1,262 +0,0 @@ -/* Copyright 2020 3araht - * - * 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 . - */ -#include QMK_KEYBOARD_H -#include "version.h" - -// Alias layout macros that expand groups of keys. -#define LAYOUT_wrapper_giabarinaix2(...) LAYOUT_giabarinaix2(__VA_ARGS__) - -#define DFCBASE DF(_C_SYSTEM_BASE) -#define DF_QWER DF(_QWERTY) -// Long press: go to _FN layer, tap: MUTE -#define FN_MUTE LT(_FN, KC_MUTE) - -// Used to set octave to 0 -extern midi_config_t midi_config; -uint8_t midi_bass_ch = 0, midi_chord_ch = 0; // By default, all use the same channel. - -// Defines names for use in layer keycodes and the keymap -enum layer_names { - _C_SYSTEM_BASE, // MIDI C-system - _QWERTY, // just in case - _FN -}; - -// Defines the keycodes used by our macros in process_record_user -enum custom_keycodes { - - // MIDI Chord Keycodes - Root notes - MY_CHORD_MIN = SAFE_RANGE, - - MI_CH_Cr = MY_CHORD_MIN, - MI_CH_Csr, - MI_CH_Dbr = MI_CH_Csr, - MI_CH_Dr, - MI_CH_Dsr, - MI_CH_Ebr = MI_CH_Dsr, - MI_CH_Er, - MI_CH_Fr, - MI_CH_Fsr, - MI_CH_Gbr = MI_CH_Fsr, - MI_CH_Gr, - MI_CH_Gsr, - MI_CH_Abr = MI_CH_Gsr, - MI_CH_Ar, - MI_CH_Asr, - MI_CH_Bbr = MI_CH_Asr, - MI_CH_Br, - - // MIDI Chord Keycodes - Major - - MI_CH_C, - MI_CH_Cs, - MI_CH_Db = MI_CH_Cs, - MI_CH_D, - MI_CH_Ds, - MI_CH_Eb = MI_CH_Ds, - MI_CH_E, - MI_CH_F, - MI_CH_Fs, - MI_CH_Gb = MI_CH_Fs, - MI_CH_G, - MI_CH_Gs, - MI_CH_Ab = MI_CH_Gs, - MI_CH_A, - MI_CH_As, - MI_CH_Bb = MI_CH_As, - MI_CH_B, - - // MIDI Chord Keycodes Minor - - MI_CH_Cm, - MI_CH_Csm, - MI_CH_Dbm = MI_CH_Csm, - MI_CH_Dm, - MI_CH_Dsm, - MI_CH_Ebm = MI_CH_Dsm, - MI_CH_Em, - MI_CH_Fm, - MI_CH_Fsm, - MI_CH_Gbm = MI_CH_Fsm, - MI_CH_Gm, - MI_CH_Gsm, - MI_CH_Abm = MI_CH_Gsm, - MI_CH_Am, - MI_CH_Asm, - MI_CH_Bbm = MI_CH_Asm, - MI_CH_Bm, - - //MIDI Chord Keycodes Dominant Seventh - - MI_CH_CDom7, - MI_CH_CsDom7, - MI_CH_DbDom7 = MI_CH_CsDom7, - MI_CH_DDom7, - MI_CH_DsDom7, - MI_CH_EbDom7 = MI_CH_DsDom7, - MI_CH_EDom7, - MI_CH_FDom7, - MI_CH_FsDom7, - MI_CH_GbDom7 = MI_CH_FsDom7, - MI_CH_GDom7, - MI_CH_GsDom7, - MI_CH_AbDom7 = MI_CH_GsDom7, - MI_CH_ADom7, - MI_CH_AsDom7, - MI_CH_BbDom7 = MI_CH_AsDom7, - MI_CH_BDom7, - - // MIDI Chord Keycodes Diminished Seventh - - MI_CH_CDim7, - MI_CH_CsDim7, - MI_CH_DbDim7 = MI_CH_CsDim7, - MI_CH_DDim7, - MI_CH_DsDim7, - MI_CH_EbDim7 = MI_CH_DsDim7, - MI_CH_EDim7, - MI_CH_FDim7, - MI_CH_FsDim7, - MI_CH_GbDim7 = MI_CH_FsDim7, - MI_CH_GDim7, - MI_CH_GsDim7, - MI_CH_AbDim7 = MI_CH_GsDim7, - MI_CH_ADim7, - MI_CH_AsDim7, - MI_CH_BbDim7 = MI_CH_AsDim7, - MI_CH_BDim7, - - MY_CHORD_MAX = MI_CH_BDim7, - - VERSION = QK_KB_0 -}; - -#define MY_CHORD_COUNT (MY_CHORD_MAX - MY_CHORD_MIN + 1) -static uint8_t chord_status[MY_CHORD_COUNT]; - -const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { - /* C-system Base */ - [_C_SYSTEM_BASE] = LAYOUT_giabarinaix2( - MI_CH_Dbr, MI_CH_Abr, MI_CH_Ebr, MI_CH_Bbr, MI_CH_Fr, MI_CH_Cr, MI_CH_Gr, MI_CH_Dr, MI_CH_Ar, MI_CH_Er, MI_CH_Br, MI_CH_Fsr, - MI_CH_Db, MI_CH_Ab, MI_CH_Eb, MI_CH_Bb, MI_CH_F, MI_CH_C, MI_CH_G, MI_CH_D, MI_CH_A, MI_CH_E, MI_CH_B, MI_CH_Fs, - MI_CH_Dbm, MI_CH_Abm, MI_CH_Ebm, MI_CH_Bbm, MI_CH_Fm, MI_CH_Cm, MI_CH_Gm, MI_CH_Dm, MI_CH_Am, MI_CH_Em, MI_CH_Bm, MI_CH_Fsm, - MI_CH_DbDom7, MI_CH_AbDom7, MI_CH_EbDom7, MI_CH_BbDom7, MI_CH_FDom7, MI_CH_CDom7, MI_CH_GDom7, MI_CH_DDom7, MI_CH_ADom7, MI_CH_EDom7, MI_CH_BDom7, MI_CH_FsDom7, - MI_CH_DbDim7, MI_CH_AbDim7, MI_CH_EbDim7, MI_CH_BbDim7, MI_CH_FDim7, MI_CH_CDim7, MI_CH_GDim7, MI_CH_DDim7, MI_CH_ADim7, MI_CH_EDim7, MI_CH_BDim7, MI_CH_FsDim7, - - MI_Db2, MI_E2, MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, - MI_Eb2, MI_Fs2, MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, - MI_F2, MI_Ab2, MI_B2, MI_D3, MI_F3, MI_Ab3, MI_B3, MI_D4, MI_F4, MI_Ab4, MI_B4, MI_D5, - MI_G2, MI_Bb2, MI_Db3, MI_E3, MI_G3, MI_Bb3, MI_Db4, MI_E4, MI_G4, MI_Bb4, MI_Db5, MI_E5, - MI_A2, MI_C3, MI_Eb3, MI_Fs3, MI_A3, MI_C4, MI_Eb4, MI_Fs4, MI_A4, MI_C5, MI_Eb5, FN_MUTE - ), - - /* QWERTY */ - [_QWERTY] = LAYOUT_wrapper_giabarinaix2( - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, KC_RCTL, - - QK_GESC, _________________NUMBER_L__________________, _________________NUMBER_R__________________, KC_BSPC, - KC_TAB, _________________QWERTY_L1_________________, _________________QWERTY_R1_________________, KC_DEL, - KC_CAPS, _________________QWERTY_L2_________________, _________________QWERTY_R2_________________, KC_ENT, - KC_LSFT, _________________QWERTY_L3_________________, _________________QWERTY_R3_________________, KC_RSFT, - KC_LCTL, KC_LGUI, KC_LALT, KC_LNG2, KC_SPC, KC_SPC, KC_SPC, KC_SPC, KC_LNG1, KC_RALT, KC_RGUI, _______ - ), - - /* Fn */ - [_FN] = LAYOUT_giabarinaix2( - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - DFCBASE, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - DF_QWER, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, VERSION, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______ - ) -}; - -#if defined(ENCODER_MAP_ENABLE) -const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = { - [_C_SYSTEM_BASE] = { ENCODER_CCW_CW(KC_VOLD, KC_VOLU) }, - [_QWERTY] = { ENCODER_CCW_CW(_______, _______) }, - [_FN] = { ENCODER_CCW_CW(_______, _______) }, -}; -#endif - -void keyboard_post_init_user(void) { - // Set octave to 0 - midi_config.octave = QK_MIDI_OCTAVE_0 - MIDI_OCTAVE_MIN; - - // avoid using 127 since it is used as a special number in some sound sources. - midi_config.velocity = MIDI_INITIAL_VELOCITY; - - for (uint8_t i = 0; i < MY_CHORD_COUNT; i++) { - chord_status[i] = MIDI_INVALID_NOTE; - } - - default_layer_set(1UL << _C_SYSTEM_BASE); -}; - -bool process_record_user(uint16_t keycode, keyrecord_t *record) { - uint16_t root_note = MIDI_INVALID_NOTE; // Starting value for the root note of each chord - - uint8_t chord = keycode - MY_CHORD_MIN; - - switch (keycode) { - case VERSION: // Output firmware info. - if (record->event.pressed) { - SEND_STRING(QMK_KEYBOARD ":" QMK_KEYMAP " @ " QMK_VERSION " | " QMK_BUILDDATE); - } - break; - - // MIDI Chord Keycodes, on the left side. - case MI_CH_Cr ... MI_CH_Br: // Root Notes - root_note = keycode - MI_CH_Cr + MI_C1; - my_process_midi4Bass(midi_bass_ch, record, chord_status, chord, root_note, false); - break; - - case MI_CH_C ... MI_CH_B: // Major Chords - root_note = keycode - MI_CH_C + MI_C2; - // Root, Major Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 4, 7); - break; - - case MI_CH_Cm ... MI_CH_Bm: // Minor Chord - root_note = keycode - MI_CH_Cm + MI_C2; - // Root, Minor Third, and Fifth Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 7); - break; - - case MI_CH_CDom7 ... MI_CH_BDom7: // Dominant 7th Chord - root_note = keycode - MI_CH_CDom7 + MI_C2; - // Major Third, Major Fifth, and Minor Seventh Notes - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 4, 7, 10); - break; - - case MI_CH_CDim7 ... MI_CH_BDim7: // Diminished 7th Chord - root_note = keycode - MI_CH_CDim7 + MI_C2; - // Root, Minor Third, and Diminished 5th Note - my_process_midi4TriadChords(midi_chord_ch, record, chord_status, chord, root_note, 0, 3, 6); - break; - } - return true; -} diff --git a/keyboards/giabalanai/keymaps/via_giabarinaix2/readme.md b/keyboards/giabalanai/keymaps/via_giabarinaix2/readme.md deleted file mode 100644 index 04c1613d530a..000000000000 --- a/keyboards/giabalanai/keymaps/via_giabarinaix2/readme.md +++ /dev/null @@ -1 +0,0 @@ -# The default keymap for giabarinaix2, VIA version. diff --git a/keyboards/giabalanai/keymaps/via_giabarinaix2/rules.mk b/keyboards/giabalanai/keymaps/via_giabarinaix2/rules.mk deleted file mode 100644 index f4836fd4f203..000000000000 --- a/keyboards/giabalanai/keymaps/via_giabarinaix2/rules.mk +++ /dev/null @@ -1,4 +0,0 @@ -VIA_ENABLE = yes -ENCODER_ENABLE = no # encoder on mute button - -ENCODER_MAP_ENABLE = yes # replacing ENCODERS_CW_KEY method to this on 2022/08/31. diff --git a/keyboards/giabalanai/readme.md b/keyboards/giabalanai/readme.md deleted file mode 100644 index 30b1b60cd1b0..000000000000 --- a/keyboards/giabalanai/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -# giabalanai - -

-giabalanai_logo -

- -![giabalanai overview](https://github.com/3araht/giabalanai/blob/main/pictures/giabalanai_overview.jpg) - -giabalanai keyboard is a simple-design Chromatic Button Accordion-ish MIDI keyboard (60 bass + C-system 62 keys = 38 notes) that doesn't have bellows nor register switches. - -* Keyboard Maintainer: [3araht](https://github.com/3araht) -* Hardware Supported: giabalanai keyboard, a split keyboard mainly work as MIDI keyboard. -* Hardware Availability: [Yushakobo](https://yushakobo.jp/shop/consign_giabalanai/) or [BOOTH](https://3araht.booth.pm/). Click [here](https://www.tenso.com/en/static/lp_shop_booth) for BOOTH overseas shipping! - - -Make example for this keyboard (after setting up your build environment): - - make giabalanai:default - -Flashing example for this keyboard: - - make giabalanai: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). diff --git a/keyboards/giabalanai/rules.mk b/keyboards/giabalanai/rules.mk deleted file mode 100644 index 90ba252d2643..000000000000 --- a/keyboards/giabalanai/rules.mk +++ /dev/null @@ -1,9 +0,0 @@ -# Build Options -# change yes to no to disable -# -COMMAND_ENABLE = no # Commands for debug and configuration -BACKLIGHT_ENABLE = no # Enable keyboard backlight functionality -# RGB_MATRIX_ENABLE is not suitable for giabalanai keyboard on the right side (there are dulpicate keys). -RGB_MATRIX_ENABLE = no # Use RGB matrix (Don't enable this when RGBLIGHT_ENABLE is used.) - -LTO_ENABLE = yes diff --git a/keyboards/halfcliff/config.h b/keyboards/halfcliff/config.h index 6f5dd093d657..192267af9269 100644 --- a/keyboards/halfcliff/config.h +++ b/keyboards/halfcliff/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #define RGBLED_NUM 10 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 5, 5 } #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/halfcliff/info.json b/keyboards/halfcliff/info.json index fb0666fbf434..a0b79ba34197 100644 --- a/keyboards/halfcliff/info.json +++ b/keyboards/halfcliff/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [5, 5] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/handwired/dactyl_manuform/dmote/62key/config.h b/keyboards/handwired/dactyl_manuform/dmote/62key/config.h index 41af664c2588..0c3bee7dcb40 100644 --- a/keyboards/handwired/dactyl_manuform/dmote/62key/config.h +++ b/keyboards/handwired/dactyl_manuform/dmote/62key/config.h @@ -6,4 +6,3 @@ #define RGBLIGHT_EFFECT_CHRISTMAS #define RGBLIGHT_EFFECT_CHRISTMAS_STEP 1 #define RGBLED_NUM 6 // Used when chaining strips -#define RGBLED_SPLIT { 3, 3 } // Used when not chaining strips diff --git a/keyboards/handwired/dactyl_manuform/dmote/62key/info.json b/keyboards/handwired/dactyl_manuform/dmote/62key/info.json index c2a818bde299..379ca33af6b9 100644 --- a/keyboards/handwired/dactyl_manuform/dmote/62key/info.json +++ b/keyboards/handwired/dactyl_manuform/dmote/62key/info.json @@ -10,6 +10,9 @@ "pid": "0x3632", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [3, 3] + }, "ws2812": { "pin": "D1" }, diff --git a/keyboards/handwired/freoduo/config.h b/keyboards/handwired/freoduo/config.h index 232d5638eb04..e4045a37905a 100644 --- a/keyboards/handwired/freoduo/config.h +++ b/keyboards/handwired/freoduo/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . #if !defined(RGBLED_NUM) # define RGBLED_NUM 30 # define RGBLIGHT_SPLIT -# define RGBLED_SPLIT { 16, 14 } // Switch RGB sides with LED MAP. # define RGBLIGHT_LED_MAP { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30} # define RGBLIGHT_LAYERS diff --git a/keyboards/handwired/freoduo/info.json b/keyboards/handwired/freoduo/info.json index 5ddf21ee7956..a4d6144cf95d 100644 --- a/keyboards/handwired/freoduo/info.json +++ b/keyboards/handwired/freoduo/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, +"rgblight": { + "split_count": [16, 14] +}, "ws2812": { "pin": "D4" }, diff --git a/keyboards/handwired/minorca/keymaps/ridingqwerty/keymap.c b/keyboards/handwired/minorca/keymaps/ridingqwerty/keymap.c index 7d541270fba6..26e6fc630ceb 100644 --- a/keyboards/handwired/minorca/keymaps/ridingqwerty/keymap.c +++ b/keyboards/handwired/minorca/keymaps/ridingqwerty/keymap.c @@ -59,9 +59,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { }, #ifdef UNICODE_H [_RUNE] = { - {KC_ESC, X(INGWZ), X(WUNJO), X(EHWAZ), X(RAIDO), X(TIWAZ), X(IWAZ), X(UR), X(ISAZ), X(ETHEL), X(PERTH), SC(BSPC) }, - {ED(TAB), X(ANSUZ), X(SOWIL), X(DAGAZ), X(FE), X(GEBO), X(HAGLZ), X(JERAN), X(KAUNA), X(LAUKZ), XXXXXXX, NM(SCLN) }, - {MT_QUOT, XXXXXXX, X(ALGIZ), X(THURS), X(KAUNA), X(WUNJO), X(BEORC), X(NAUDZ), X(MANNZ), KC_COMM, FK(DOT), RS(SLSH) }, + {KC_ESC, UM(INGWZ), UM(WUNJO), UM(EHWAZ), UM(RAIDO), UM(TIWAZ), UM(IWAZ), UM(UR), UM(ISAZ), UM(ETHEL), UM(PERTH), SC(BSPC) }, + {ED(TAB), UM(ANSUZ), UM(SOWIL), UM(DAGAZ), UM(FE), UM(GEBO), UM(HAGLZ), UM(JERAN), UM(KAUNA), UM(LAUKZ), XXXXXXX, NM(SCLN) }, + {MT_QUOT, XXXXXXX, UM(ALGIZ), UM(THURS), UM(KAUNA), UM(WUNJO), UM(BEORC), UM(NAUDZ), UM(MANNZ), KC_COMM, FK(DOT), RS(SLSH) }, {LC(ESC), XXXXXXX, LG(LBRC), LA(RBRC), NM(BSPC), XXXXXXX, XXXXXXX, SM(SPC), XXXXXXX, RA(MINS), RG(EQL), RC(ENT) } }, #endif diff --git a/keyboards/handwired/promethium/keymaps/default/keymap.c b/keyboards/handwired/promethium/keymaps/default/keymap.c index 100db976781e..42819245c7af 100644 --- a/keyboards/handwired/promethium/keymaps/default/keymap.c +++ b/keyboards/handwired/promethium/keymaps/default/keymap.c @@ -779,9 +779,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_PUNC] = LAYOUT( - KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, X(LTEQ), X(GTEQ), _______, - KC_GRV, KC_ASTR, KC_BSLS, KC_MINS, KC_EQL, KC_SLSH, X(NOTEQ),KC_LPRN, KC_RPRN, KC_LABK, KC_RABK, _______, - KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, X(PLMIN),KC_LBRC, KC_RBRC, KC_LCBR, KC_RCBR, _______, + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, UM(LTEQ), UM(GTEQ), _______, + KC_GRV, KC_ASTR, KC_BSLS, KC_MINS, KC_EQL, KC_SLSH, UM(NOTEQ),KC_LPRN, KC_RPRN, KC_LABK, KC_RABK, _______, + KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, UM(PLMIN),KC_LBRC, KC_RBRC, KC_LCBR, KC_RCBR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_COLN, _______, _______, _______, _______ ), @@ -836,9 +836,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_GREEKU] = LAYOUT( - _______, XXXXXXX, XXXXXXX,X(UEPSI), X(URHO), X(UTAU),X(UUPSI),X(UTHET),X(UIOTA),X(UOMIC), X(UPI), _______, - _______,X(UALPH),X(USIGM),X(UDELT), X(UPHI),X(UGAMM), X(UETA), X(UXI),X(UKAPP),X(ULAMB), KC_QUOT, _______, - _______,X(UZETA), X(UCHI), X(UPSI),X(UOMEG),X(UBETA), X(UNU), X(UMU), KC_COMM, KC_DOT, KC_SLSH, _______, + _______, XXXXXXX, XXXXXXX,UM(UEPSI), UM(URHO), UM(UTAU),UM(UUPSI),UM(UTHET),UM(UIOTA),UM(UOMIC), UM(UPI), _______, + _______,UM(UALPH),UM(USIGM),UM(UDELT), UM(UPHI),UM(UGAMM), UM(UETA), UM(UXI),UM(UKAPP),UM(ULAMB), KC_QUOT, _______, + _______,UM(UZETA), UM(UCHI), UM(UPSI),UM(UOMEG),UM(UBETA), UM(UNU), UM(UMU), KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), @@ -855,9 +855,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_GREEKL] = LAYOUT( - _______, XXXXXXX,X(FSIGM),X(LEPSI), X(LRHO), X(LTAU),X(LUPSI),X(LTHET),X(LIOTA),X(LOMIC), X(LPI), _______, - _______,X(LALPH),X(LSIGM),X(LDELT), X(LPHI),X(LGAMM), X(LETA), X(LXI),X(LKAPP),X(LLAMB), KC_QUOT, _______, - _______,X(LZETA), X(LCHI), X(LPSI),X(LOMEG),X(LBETA), X(LNU), X(LMU), KC_COMM, KC_DOT, KC_SLSH, _______, + _______, XXXXXXX,UM(FSIGM),UM(LEPSI), UM(LRHO), UM(LTAU),UM(LUPSI),UM(LTHET),UM(LIOTA),UM(LOMIC), UM(LPI), _______, + _______,UM(LALPH),UM(LSIGM),UM(LDELT), UM(LPHI),UM(LGAMM), UM(LETA), UM(LXI),UM(LKAPP),UM(LLAMB), KC_QUOT, _______, + _______,UM(LZETA), UM(LCHI), UM(LPSI),UM(LOMEG),UM(LBETA), UM(LNU), UM(LMU), KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), @@ -893,10 +893,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_EMOJI] = LAYOUT( - X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW), - X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS), - X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH), - X(POO), X(EYES), X(HUNRD),_______, X(SKULL),X(HORNS), X(HALO), X(FEAR),_______,X(YUMMY),X(DISAP),X(NOEVK), + UM(HART2), UM(CRY2),UM(WEARY),UM(EYERT),UM(SMIRK), UM(TJOY),UM(RECYC),UM(UNAMU),UM(MUSIC),UM(OKHND),UM(PENSV), UM(PHEW), + UM(THMUP), UM(PRAY),UM(SMILE),UM(SMIL2),UM(FLUSH), UM(GRIN),UM(HEART), UM(BYE), UM(KISS),UM(CELEB), UM(COOL),UM(NOEVS), + UM(THMDN),UM(SLEEP), UM(CLAP), UM(CRY), UM(VIC),UM(BHART), UM(SUN),UM(SMEYE), UM(WINK), UM(MOON),UM(CONFU),UM(NOEVH), + UM(POO), UM(EYES), UM(HUNRD),_______, UM(SKULL),UM(HORNS), UM(HALO), UM(FEAR),_______,UM(YUMMY),UM(DISAP),UM(NOEVK), _______, _______, _______ ), diff --git a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c index 1d299c229932..203a0eda22a1 100644 --- a/keyboards/handwired/promethium/keymaps/priyadi/keymap.c +++ b/keyboards/handwired/promethium/keymaps/priyadi/keymap.c @@ -782,9 +782,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_PUNC] = LAYOUT( - KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, X(LTEQ), X(GTEQ), _______, - KC_GRV, KC_ASTR, KC_BSLS, KC_MINS, KC_EQL, KC_SLSH, X(NOTEQ),KC_LPRN, KC_RPRN, KC_LABK, KC_RABK, _______, - KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, X(PLMIN),KC_LBRC, KC_RBRC, KC_LCBR, KC_RCBR, _______, + KC_TILD, KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, UM(LTEQ), UM(GTEQ), _______, + KC_GRV, KC_ASTR, KC_BSLS, KC_MINS, KC_EQL, KC_SLSH, UM(NOTEQ),KC_LPRN, KC_RPRN, KC_LABK, KC_RABK, _______, + KC_AMPR, KC_CIRC, KC_PIPE, KC_UNDS, KC_PLUS, KC_QUES, UM(PLMIN),KC_LBRC, KC_RBRC, KC_LCBR, KC_RCBR, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_COLN, _______, _______, _______, _______ ), @@ -839,9 +839,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_GREEKU] = LAYOUT( - _______, XXXXXXX, XXXXXXX,X(UEPSI), X(URHO), X(UTAU),X(UUPSI),X(UTHET),X(UIOTA),X(UOMIC), X(UPI), _______, - _______,X(UALPH),X(USIGM),X(UDELT), X(UPHI),X(UGAMM), X(UETA), X(UXI),X(UKAPP),X(ULAMB), KC_QUOT, _______, - _______,X(UZETA), X(UCHI), X(UPSI),X(UOMEG),X(UBETA), X(UNU), X(UMU), KC_COMM, KC_DOT, KC_SLSH, _______, + _______, XXXXXXX, XXXXXXX,UM(UEPSI), UM(URHO), UM(UTAU),UM(UUPSI),UM(UTHET),UM(UIOTA),UM(UOMIC), UM(UPI), _______, + _______,UM(UALPH),UM(USIGM),UM(UDELT), UM(UPHI),UM(UGAMM), UM(UETA), UM(UXI),UM(UKAPP),UM(ULAMB), KC_QUOT, _______, + _______,UM(UZETA), UM(UCHI), UM(UPSI),UM(UOMEG),UM(UBETA), UM(UNU), UM(UMU), KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), @@ -858,9 +858,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_GREEKL] = LAYOUT( - _______, XXXXXXX,X(FSIGM),X(LEPSI), X(LRHO), X(LTAU),X(LUPSI),X(LTHET),X(LIOTA),X(LOMIC), X(LPI), _______, - _______,X(LALPH),X(LSIGM),X(LDELT), X(LPHI),X(LGAMM), X(LETA), X(LXI),X(LKAPP),X(LLAMB), KC_QUOT, _______, - _______,X(LZETA), X(LCHI), X(LPSI),X(LOMEG),X(LBETA), X(LNU), X(LMU), KC_COMM, KC_DOT, KC_SLSH, _______, + _______, XXXXXXX,UM(FSIGM),UM(LEPSI), UM(LRHO), UM(LTAU),UM(LUPSI),UM(LTHET),UM(LIOTA),UM(LOMIC), UM(LPI), _______, + _______,UM(LALPH),UM(LSIGM),UM(LDELT), UM(LPHI),UM(LGAMM), UM(LETA), UM(LXI),UM(LKAPP),UM(LLAMB), KC_QUOT, _______, + _______,UM(LZETA), UM(LCHI), UM(LPSI),UM(LOMEG),UM(LBETA), UM(LNU), UM(LMU), KC_COMM, KC_DOT, KC_SLSH, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), @@ -896,10 +896,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_EMOJI] = LAYOUT( - X(HART2), X(CRY2),X(WEARY),X(EYERT),X(SMIRK), X(TJOY),X(RECYC),X(UNAMU),X(MUSIC),X(OKHND),X(PENSV), X(PHEW), - X(THMUP), X(PRAY),X(SMILE),X(SMIL2),X(FLUSH), X(GRIN),X(HEART), X(BYE), X(KISS),X(CELEB), X(COOL),X(NOEVS), - X(THMDN),X(SLEEP), X(CLAP), X(CRY), X(VIC),X(BHART), X(SUN),X(SMEYE), X(WINK), X(MOON),X(CONFU),X(NOEVH), - X(POO), X(EYES), X(HUNRD),_______, X(SKULL),X(HORNS), X(HALO), X(FEAR),_______,X(YUMMY),X(DISAP),X(NOEVK), + UM(HART2), UM(CRY2),UM(WEARY),UM(EYERT),UM(SMIRK), UM(TJOY),UM(RECYC),UM(UNAMU),UM(MUSIC),UM(OKHND),UM(PENSV), UM(PHEW), + UM(THMUP), UM(PRAY),UM(SMILE),UM(SMIL2),UM(FLUSH), UM(GRIN),UM(HEART), UM(BYE), UM(KISS),UM(CELEB), UM(COOL),UM(NOEVS), + UM(THMDN),UM(SLEEP), UM(CLAP), UM(CRY), UM(VIC),UM(BHART), UM(SUN),UM(SMEYE), UM(WINK), UM(MOON),UM(CONFU),UM(NOEVH), + UM(POO), UM(EYES), UM(HUNRD),_______, UM(SKULL),UM(HORNS), UM(HALO), UM(FEAR),_______,UM(YUMMY),UM(DISAP),UM(NOEVK), _______, _______, _______ ), diff --git a/keyboards/handwired/scottokeebs/scotto36/info.json b/keyboards/handwired/scottokeebs/scotto36/info.json new file mode 100644 index 000000000000..fe8ecb6629ff --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/info.json @@ -0,0 +1,76 @@ +{ + "manufacturer": "ScottoKeebs", + "keyboard_name": "Scotto36", + "maintainer": "joe-scotto", + "diode_direction": "COL2ROW", + "development_board": "promicro", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + // 4, 5, 6, 7, 8, 9, A3, A2, A1, A0 + "cols": ["D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5", "F6", "F7"], + // 15, 14, 16, 10 + "rows": ["B1", "B3", "B2", "B6"] + }, + "url": "https://scottokeebs.com", + "usb": { + "device_version": "1.0.0", + "pid": "0x0002", + "vid": "0x534B" + }, + "community_layouts": ["split_3x5_3"], + "layouts": { + "LAYOUT_split_3x5_3": { + "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}, + + // Row 2 + {"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}, + + // Row 3 + {"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}, + + // Row 4 + {"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} + ] + } + } +} diff --git a/quantum/keymap.h b/keyboards/handwired/scottokeebs/scotto36/keymaps/default/config.h similarity index 75% rename from quantum/keymap.h rename to keyboards/handwired/scottokeebs/scotto36/keymaps/default/config.h index a067e1aa368f..1a6512052c1d 100644 --- a/quantum/keymap.h +++ b/keyboards/handwired/scottokeebs/scotto36/keymaps/default/config.h @@ -1,5 +1,5 @@ /* -Copyright 2012-2016 Jun Wako +Copyright 2022 Joe Scotto 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 @@ -8,7 +8,7 @@ the Free Software Foundation, either version 2 of the License, or 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 +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 @@ -17,4 +17,7 @@ along with this program. If not, see . #pragma once -#pragma message("'keymap.h' should no longer be included!") +// Define options +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/scottokeebs/scotto36/keymaps/default/keymap.c b/keyboards/handwired/scottokeebs/scotto36/keymaps/default/keymap.c new file mode 100644 index 000000000000..590f59aa07de --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/keymaps/default/keymap.c @@ -0,0 +1,45 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_split_3x5_3( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_BSPC, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), KC_ESC + ), + [1] = LAYOUT_split_3x5_3( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [2] = LAYOUT_split_3x5_3( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [3] = LAYOUT_split_3x5_3( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/keyboards/giabalanai/keymaps/via/config.h b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/config.h similarity index 75% rename from keyboards/giabalanai/keymaps/via/config.h rename to keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/config.h index f225b6534047..1a6512052c1d 100644 --- a/keyboards/giabalanai/keymaps/via/config.h +++ b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/config.h @@ -1,5 +1,5 @@ /* -Copyright 2023 3araht +Copyright 2022 Joe Scotto 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 @@ -8,12 +8,16 @@ the Free Software Foundation, either version 2 of the License, or 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 +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 . */ + #pragma once -#define DYNAMIC_KEYMAP_LAYER_COUNT 3 +// Define options +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/keymap.c b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/keymap.c new file mode 100644 index 000000000000..293082af6630 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/keymap.c @@ -0,0 +1,281 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +#include +char wpm_str[10]; + +// Tap Dance declarations +enum { + TD_ESC_SPOTLIGHT_EMOJI, + TD_ESC_WINDOWS_EMOJI +}; + +void td_esc_spotlight_emoji (tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code16(G(KC_SPC)); + } else if (state->count == 3) { + tap_code16(C(G(KC_SPC))); + } +} + +void td_esc_windows_emoji (tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code(KC_LGUI); + } else if (state->count == 3) { + tap_code16(G(KC_DOT)); + } +}; + + // Tap Dance definitions +tap_dance_action_t tap_dance_actions[] = { + [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), + [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) +}; + +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case TD(TD_ESC_SPOTLIGHT_EMOJI) : + case TD(TD_ESC_WINDOWS_EMOJI) : + case LGUI_T(KC_SPC) : + case LT(1, KC_TAB) : + case LT(2, KC_ENT) : + return 200; + default: + return TAPPING_TERM; + } +}; + +// Layer Names +enum layer_names { + _MAC_DEFAULT, + _MAC_CODE, + _MAC_NUM, + _MAC_FUNC, + _WIN_DEFAULT, + _WIN_CODE, + _WIN_NUM, + _WIN_FUNC +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_split_3x5_3( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [1] = LAYOUT_split_3x5_3( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [2] = LAYOUT_split_3x5_3( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [3] = LAYOUT_split_3x5_3( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [4] = LAYOUT_split_3x5_3( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [5] = LAYOUT_split_3x5_3( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE,KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) + ), + [6] = LAYOUT_split_3x5_3( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) + ), + [7] = LAYOUT_split_3x5_3( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_LALT, KC_LCTL, KC_SPC, KC_TRNS, KC_TRNS, TD(TD_ESC_WINDOWS_EMOJI) + ) +}; + +// OLED +#ifdef OLED_ENABLE +// WPM responsiveness +#define IDLE_FRAMES 5 +#define IDLE_SPEED 20 // Speed at which animation goes into idle +#define TAP_FRAMES 2 +#define TAP_SPEED 40 // WPM to trigger Bongo +#define ANIM_FRAME_DURATION 200 // Frame MS +#define ANIM_SIZE 636 // Number of bytes in array, max 1024 + +uint32_t anim_timer = 0; +uint32_t anim_sleep = 0; +uint8_t current_idle_frame = 0; +uint8_t current_tap_frame = 0; + +static void render_animation(void) { + static const char PROGMEM idle[IDLE_FRAMES][ANIM_SIZE] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x82, 0x02, 0x02, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x80, 0x00, 0x00, 0x60, 0x60, 0x00, 0x01, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x30, 0x0c, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x86, 0x86, 0x40, 0x40, 0x40, 0x40, 0x21, 0x22, 0x22, 0x20, 0x11, 0x11, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x34, 0xc4, 0x04, 0x04, 0x04, 0x08, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x20, 0x18, 0x04, 0x02, 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0d, 0x31, 0xc1, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x04, 0x04, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + static const char PROGMEM prep[][ANIM_SIZE] = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; + static const char PROGMEM tap[TAP_FRAMES][ANIM_SIZE] = { + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x64, 0x18, 0x04, 0x12, 0xc2, 0xca, 0x24, 0x88, 0xf0, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x41, 0x42, 0x24, 0x98, 0xc0, 0x88, 0x88, 0x8c, 0x9c, 0x1c, 0x1e, 0x0e, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x40, 0x40, 0x20, 0x20, 0x10, 0x08, 0x04, 0x02, 0x04, 0x08, 0x10, 0x10, 0x20, 0x20, 0x40, 0x40, 0x80, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xc1, 0x01, 0x01, 0x02, 0x02, 0x04, 0x84, 0x44, 0x44, 0x42, 0x82, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x40, 0x80, 0x80, 0x40, 0x00, 0x00, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x04, 0x04, 0x08, 0x08, 0x10, 0x20, 0x40, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x18, 0x06, 0x01, 0x00, 0x00, 0x0c, 0x03, 0x00, 0x02, 0x18, 0x19, 0x00, 0x05, 0xfe, 0x80, 0x83, 0x83, 0x40, 0x40, 0x40, 0x40, 0x20, 0x21, 0x21, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x08, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x04, 0x08, 0x30, 0x40, 0x80, 0x80, 0x00, 0x00, 0x01, 0x86, 0x98, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x40, 0x40, 0x40, 0x40, 0x20, 0x20, 0x20, 0x20, 0x10, 0x10, 0x10, 0x10, 0x08, 0x0f, 0x08, 0x08, 0x04, 0x04, 0x04, 0x04, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x0f, 0x0f, 0x07, 0x03, 0x03, 0x61, 0xf0, 0xf8, 0xfc, 0x60, 0x01, 0x01, 0x01, 0x3c, 0x78, 0xf8, 0xf0, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, + }; + + void animation_phase(void) { + if (get_current_wpm() <= IDLE_SPEED) { + current_idle_frame = (current_idle_frame + 1) % IDLE_FRAMES; + oled_write_raw_P(idle[abs((IDLE_FRAMES - 1) - current_idle_frame)], ANIM_SIZE); + } + + if (get_current_wpm() > IDLE_SPEED && get_current_wpm() < TAP_SPEED) { + oled_write_raw_P(prep[0], ANIM_SIZE); + } + + if (get_current_wpm() >= TAP_SPEED) { + current_tap_frame = (current_tap_frame + 1) % TAP_FRAMES; + oled_write_raw_P(tap[abs((TAP_FRAMES - 1) - current_tap_frame)], ANIM_SIZE); + } + } + if (get_current_wpm() != 000) { + oled_on(); // Enables OLED on any alpha keypress + + if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + + anim_sleep = timer_read32(); + } else { + if (timer_elapsed32(anim_sleep) > OLED_TIMEOUT) { + oled_off(); + } else { + if (timer_elapsed32(anim_timer) > ANIM_FRAME_DURATION) { + anim_timer = timer_read32(); + animation_phase(); + } + } + } +} + +// Draw to OLED +bool oled_task_user(void) { + // Render Bongo Cat + render_animation(); + + // WPM text + oled_set_cursor(0, 0); + sprintf(wpm_str, "%03d", get_current_wpm()); // %03d defines digits to display + oled_write(wpm_str, false); + + // Layer text + oled_set_cursor(0, 1); + switch (get_highest_layer(layer_state)) { + case _MAC_DEFAULT : + oled_write_P(PSTR("MAC"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("MAIN"), false); + break; + case _MAC_CODE : + oled_write_P(PSTR("MAC"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("CODE"), false); + break; + case _MAC_NUM : + oled_write_P(PSTR("MAC"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("NUM"), false); + break; + case _MAC_FUNC : + oled_write_P(PSTR("MAC"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("FUNC"), false); + break; + case _WIN_DEFAULT : + oled_write_P(PSTR("WIN"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("MAIN"), false); + break; + case _WIN_CODE : + oled_write_P(PSTR("WIN"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("CODE"), false); + break; + case _WIN_NUM : + oled_write_P(PSTR("WIN"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("NUM"), false); + break; + case _WIN_FUNC : + oled_write_P(PSTR("WIN"), false); + oled_set_cursor(0, 2); + oled_write_P(PSTR("FUNC"), false); + break; + } + + // Caps lock text + led_t led_state = host_keyboard_led_state(); + oled_set_cursor(0, 3); + oled_write_P(led_state.caps_lock ? PSTR("CAPS") : PSTR(""), false); + + return false; +} +#endif + diff --git a/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/rules.mk b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/rules.mk new file mode 100644 index 000000000000..6e339da6c697 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/keymaps/scotto/rules.mk @@ -0,0 +1,4 @@ +OLED_ENABLE = yes +WPM_ENABLE = yes +LTO_ENABLE = yes +TAP_DANCE_ENABLE = yes \ No newline at end of file diff --git a/keyboards/handwired/scottokeebs/scotto36/readme.md b/keyboards/handwired/scottokeebs/scotto36/readme.md new file mode 100644 index 000000000000..a8cbe3cf41c0 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/readme.md @@ -0,0 +1,27 @@ +# Scotto36 + +![Scotto36](https://i.imgur.com/MCGv0ZHh.jpeg) + +A 36-key split monoblock ergonomic ortholinear keyboard with 15° of angle on each half. Case files available [here](https://github.com/joe-scotto/scottokeebs). + +* Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) +* Hardware Supported: ATmega32U4 +* Hardware Availability: [Amazon](https://amazon.com) + +Make example for this keyboard (after setting up your build environment): + + make handwired/scottokeebs/scotto36:default + +Flashing example for this keyboard: + + make handwired/scottokeebs/scotto36: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 \ No newline at end of file diff --git a/keyboards/handwired/scottokeebs/scotto36/rules.mk b/keyboards/handwired/scottokeebs/scotto36/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto36/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/handwired/scottokeebs/scotto40/info.json b/keyboards/handwired/scottokeebs/scotto40/info.json new file mode 100644 index 000000000000..b10f677c4d39 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/info.json @@ -0,0 +1,183 @@ +{ + "manufacturer": "ScottoKeebs", + "keyboard_name": "Scotto40", + "maintainer": "joe-scotto", + "diode_direction": "COL2ROW", + "development_board": "promicro", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + // 2, 3, 4, 5, 6, 7, 8, 9, A3, A2 + "cols": ["D1", "D0", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5"], + + // 15, 14, 16, 10 + "rows": ["B1", "B3", "B2", "B6"] + }, + "url": "https://scottokeebs.com", + "usb": { + "device_version": "1.0.0", + "pid": "0x0001", + "vid": "0x534B" + }, + "community_layouts": ["ortho_4x10"], + "layouts": { + "LAYOUT_ortho_3x10_7": { + "layout": [ + // Row 1 + {"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}, + + // Row 2 + {"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}, + + // Row 3 + {"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}, + + // Row 4 + {"matrix": [3, 0], "x": 0, "y": 3}, + + {"matrix": [3, 2], "x": 2, "y": 3}, + {"matrix": [3, 3], "x": 3, "y": 3}, + {"matrix": [3, 4], "x": 4, "y": 3, "w": 2}, + {"matrix": [3, 6], "x": 6, "y": 3}, + {"matrix": [3, 7], "x": 7, "y": 3}, + + {"matrix": [3, 9], "x": 9, "y": 3} + ] + }, + "LAYOUT_ortho_3x10_8": { + "layout": [ + // Row 1 + {"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}, + + // Row 2 + {"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}, + + // Row 3 + {"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}, + + // Row 4 + {"matrix": [3, 0], "x": 0, "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, 9], "x": 9, "y": 3} + ] + }, + "LAYOUT_ortho_4x10": { + "layout": [ + // Row 1 + {"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}, + + // Row 2 + {"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}, + + // Row 3 + {"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}, + + // Row 4 + {"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} + ] + } + } +} diff --git a/keyboards/giabalanai/keymaps/2firmware/config.h b/keyboards/handwired/scottokeebs/scotto40/keymaps/default/config.h similarity index 73% rename from keyboards/giabalanai/keymaps/2firmware/config.h rename to keyboards/handwired/scottokeebs/scotto40/keymaps/default/config.h index e5ec1d73e28a..1a6512052c1d 100644 --- a/keyboards/giabalanai/keymaps/2firmware/config.h +++ b/keyboards/handwired/scottokeebs/scotto40/keymaps/default/config.h @@ -1,5 +1,5 @@ /* -Copyright 2023 3araht +Copyright 2022 Joe Scotto 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 @@ -8,18 +8,16 @@ the Free Software Foundation, either version 2 of the License, or 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 +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 . */ -#pragma once - -//#define USE_MATRIX_I2C -/* Select hand configuration */ +#pragma once -// #define MASTER_LEFT -// #define MASTER_RIGHT -#define EE_HANDS +// Define options +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/scottokeebs/scotto40/keymaps/default/keymap.c b/keyboards/handwired/scottokeebs/scotto40/keymaps/default/keymap.c new file mode 100644 index 000000000000..63aa76084332 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/keymaps/default/keymap.c @@ -0,0 +1,45 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_ortho_4x10( + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_BSPC, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_NO, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), KC_ESC, KC_NO, KC_NO + ), + [1] = LAYOUT_ortho_4x10( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [2] = LAYOUT_ortho_4x10( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ), + [3] = LAYOUT_ortho_4x10( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS + ) +}; diff --git a/quantum/led_tables.h b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/config.h similarity index 73% rename from quantum/led_tables.h rename to keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/config.h index cd3e5d74c11d..1a6512052c1d 100644 --- a/quantum/led_tables.h +++ b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/config.h @@ -1,23 +1,23 @@ /* -Copyright 2017 Fred Sundvik +Copyright 2022 Joe Scotto 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 +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 . */ #pragma once -#include "progmem.h" -#include - -#ifdef USE_CIE1931_CURVE -extern const uint8_t CIE1931_CURVE[] PROGMEM; -#endif +// Define options +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/keymap.c b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/keymap.c new file mode 100644 index 000000000000..ba5f7bc7a8ca --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/keymap.c @@ -0,0 +1,114 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +// Tap Dance declarations +enum { + TD_ESC_SPOTLIGHT_EMOJI, + TD_ESC_WINDOWS_EMOJI +}; + +void td_esc_spotlight_emoji (tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code16(G(KC_SPC)); + } else if (state->count == 3) { + tap_code16(C(G(KC_SPC))); + } +} + +void td_esc_windows_emoji (tap_dance_state_t *state, void *user_data) { + if (state->count == 1) { + tap_code(KC_ESC); + } else if (state->count == 2) { + tap_code(KC_LGUI); + } else if (state->count == 3) { + tap_code16(G(KC_DOT)); + } +}; + + // Tap Dance definitions +tap_dance_action_t tap_dance_actions[] = { + [TD_ESC_SPOTLIGHT_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_spotlight_emoji), + [TD_ESC_WINDOWS_EMOJI] = ACTION_TAP_DANCE_FN(td_esc_windows_emoji) +}; + +uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { + switch (keycode) { + case TD(TD_ESC_SPOTLIGHT_EMOJI) : + case TD(TD_ESC_WINDOWS_EMOJI) : + case LGUI_T(KC_SPC) : + case LT(1, KC_TAB) : + case LT(2, KC_ENT) : + return 200; + default: + return TAPPING_TERM; + } +}; + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_ortho_3x10_7( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), LT(1, KC_TAB), LT(2, KC_ENT), TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [1] = LAYOUT_ortho_3x10_7( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [2] = LAYOUT_ortho_3x10_7( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [3] = LAYOUT_ortho_3x10_7( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_ESC, KC_LCTL, KC_LALT, LGUI_T(KC_SPC), KC_TRNS, KC_TRNS, TD(TD_ESC_SPOTLIGHT_EMOJI) + ), + [4] = LAYOUT_ortho_3x10_7( + KC_Q, KC_W, KC_F, KC_P, KC_G, KC_J, KC_L, KC_U, KC_Y, KC_BSPC, + KC_A, KC_R, KC_S, KC_T, KC_D, KC_H, KC_N, KC_E, KC_I, KC_O, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_K, KC_M, KC_COMMA, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [5] = LAYOUT_ortho_3x10_7( + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_DEL, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILDE, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [6] = LAYOUT_ortho_3x10_7( + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(7), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ), + [7] = LAYOUT_ortho_3x10_7( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(0), + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, + KC_ESC, KC_LALT, KC_LCTL, KC_SPC, LT(5, KC_TAB), LT(6, KC_ENT), TD(TD_ESC_WINDOWS_EMOJI) + ) +}; diff --git a/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/rules.mk b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/rules.mk new file mode 100644 index 000000000000..e5ddcae8d927 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/keymaps/scotto/rules.mk @@ -0,0 +1 @@ +TAP_DANCE_ENABLE = yes diff --git a/keyboards/handwired/scottokeebs/scotto40/readme.md b/keyboards/handwired/scottokeebs/scotto40/readme.md new file mode 100644 index 000000000000..f81e63984748 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/readme.md @@ -0,0 +1,27 @@ +# Scotto40 + +![Scotto40](https://i.imgur.com/wtW5xOth.jpeg) + +An ortholinear keyboard that features either a 37, 38, or 40-key layout. Case files available [here](https://github.com/joe-scotto/scottokeebs). + +* Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) +* Hardware Supported: ATmega32U4 +* Hardware Availability: [Amazon](https://amazon.com) + +Make example for this keyboard (after setting up your build environment): + + make handwired/scottokeebs/scotto40:default + +Flashing example for this keyboard: + + make handwired/scottokeebs/scotto40: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 \ No newline at end of file diff --git a/keyboards/handwired/scottokeebs/scotto40/rules.mk b/keyboards/handwired/scottokeebs/scotto40/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scotto40/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/handwired/scottokeebs/scottostarter/info.json b/keyboards/handwired/scottokeebs/scottostarter/info.json new file mode 100644 index 000000000000..ade3db28a0ee --- /dev/null +++ b/keyboards/handwired/scottokeebs/scottostarter/info.json @@ -0,0 +1,94 @@ +{ + "manufacturer": "ScottoKeebs", + "keyboard_name": "ScottoStarter", + "maintainer": "joe-scotto", + "diode_direction": "COL2ROW", + "development_board": "promicro", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + // RX1, 4, 5, 6, 7, 8, 9, A3, A2, A1, TX0 + "cols": ["D2", "D4", "C6", "D7", "E6", "B4", "B5", "F4", "F5", "F6", "D3"], + // A0, 15, 14, 16, 10 + "rows": ["F7", "B1", "B3", "B2", "B6"] + }, + "url": "https://scottokeebs.com", + "usb": { + "device_version": "1.0.0", + "pid": "0x0008", + "vid": "0xFEED" + }, + "layouts": { + "LAYOUT_ortho_4x11_8": { + "layout": [ + // Row 1 + {"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}, + + // Row 2 + {"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}, + + // Row 3 + {"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}, + + // Row 4 + {"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}, + + // Row 5 + {"matrix": [4, 0], "x": 0, "y": 4}, + {"matrix": [4, 1], "x": 1, "y": 4}, + {"matrix": [4, 2], "x": 2, "y": 4}, + {"matrix": [4, 4], "x": 4, "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} + ] + } + } +} diff --git a/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/config.h b/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/config.h new file mode 100644 index 000000000000..1a6512052c1d --- /dev/null +++ b/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/config.h @@ -0,0 +1,23 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#pragma once + +// Define options +#define TAPPING_TERM 135 +#define PERMISSIVE_HOLD +#define TAPPING_TERM_PER_KEY diff --git a/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/keymap.c b/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/keymap.c new file mode 100644 index 000000000000..fb47637f189d --- /dev/null +++ b/keyboards/handwired/scottokeebs/scottostarter/keymaps/default/keymap.c @@ -0,0 +1,52 @@ +/* +Copyright 2022 Joe Scotto + +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 . +*/ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_ortho_4x11_8( + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, + KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, KC_TAB, + KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, + LSFT_T(KC_Z), KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), KC_ENT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), MO(2), KC_ESC, KC_CAPS + ), + [1] = LAYOUT_ortho_4x11_8( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_DEL, + KC_UNDS, KC_MINS, KC_PLUS, KC_EQL, KC_COLN, KC_GRV, KC_MRWD, KC_MPLY, KC_MFFD, KC_NO, KC_TAB, + KC_LCBR, KC_LPRN, KC_RPRN, KC_RCBR, KC_PIPE, KC_ESC, KC_LEFT, KC_UP, KC_DOWN, KC_RGHT, KC_QUOT, + LSFT_T(KC_LBRC), KC_QUOT, KC_DQUO, KC_RBRC, KC_SCLN, KC_TILD, KC_VOLD, KC_MUTE, KC_VOLU, RSFT_T(KC_BSLS), KC_ENT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS + ), + [2] = LAYOUT_ortho_4x11_8( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSPC, + KC_EXLM, KC_AT, KC_HASH, KC_DLR, KC_PERC, KC_CIRC, KC_AMPR, KC_ASTR, KC_CAPS, KC_BSPC, KC_TAB, + KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, KC_QUOT, + KC_LSFT, KC_NO, KC_NO, KC_NO, MO(3), KC_NO, KC_NO, KC_COMM, KC_DOT, RSFT_T(KC_SLSH), KC_ENT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS + ), + [3] = LAYOUT_ortho_4x11_8( + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_BSPC, + KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, KC_NO, TO(4), KC_TAB, + KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, KC_QUOT, + KC_F11, KC_NO, KC_NO, QK_BOOT, KC_TRNS, KC_NO, KC_NO, KC_NO, KC_NO, KC_F12, KC_ENT, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_TRNS, KC_TRNS, KC_ESC, KC_CAPS + ) +}; + + + diff --git a/keyboards/handwired/scottokeebs/scottostarter/readme.md b/keyboards/handwired/scottokeebs/scottostarter/readme.md new file mode 100644 index 000000000000..346db2f5fd64 --- /dev/null +++ b/keyboards/handwired/scottokeebs/scottostarter/readme.md @@ -0,0 +1,27 @@ +# ScottoStarter + +![ScottoStarter](https://i.imgur.com/bspbVPah.jpg) + +A 52-key ortholinear keyboard designed to help ease the transition into smaller layouts. Case files available [here](https://github.com/joe-scotto/scottokeebs). + +* Keyboard Maintainer: [Joe Scotto](https://github.com/joe-scotto) +* Hardware Supported: ATmega32U4 +* Hardware Availability: [Amazon](https://amazon.com) + +Make example for this keyboard (after setting up your build environment): + + make handwired/scottokeebs/scottostarter:default + +Flashing example for this keyboard: + + make handwired/scottokeebs/scottostarter: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 \ No newline at end of file diff --git a/keyboards/handwired/scottokeebs/scottostarter/rules.mk b/keyboards/handwired/scottokeebs/scottostarter/rules.mk new file mode 100644 index 000000000000..7ff128fa692e --- /dev/null +++ b/keyboards/handwired/scottokeebs/scottostarter/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank \ No newline at end of file diff --git a/keyboards/handwired/splittest/config.h b/keyboards/handwired/splittest/config.h index 49bc3cbddb45..c656f9681536 100644 --- a/keyboards/handwired/splittest/config.h +++ b/keyboards/handwired/splittest/config.h @@ -35,7 +35,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 6, 6 } /* * Feature disable options diff --git a/keyboards/handwired/splittest/info.json b/keyboards/handwired/splittest/info.json index efd82d20c47e..b301ffeaaf34 100644 --- a/keyboards/handwired/splittest/info.json +++ b/keyboards/handwired/splittest/info.json @@ -8,6 +8,9 @@ "pid": "0x1111", "device_version": "1.0.0" }, + "rgblight": { + "split_count": [6, 6] + }, "layouts": { "LAYOUT": { "layout": [ diff --git a/keyboards/handwired/t111/keymaps/oleg/keymap.c b/keyboards/handwired/t111/keymaps/oleg/keymap.c index dd0c0971970d..b372de027bfd 100644 --- a/keyboards/handwired/t111/keymaps/oleg/keymap.c +++ b/keyboards/handwired/t111/keymaps/oleg/keymap.c @@ -117,10 +117,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { */ [1] = LAYOUT( VRSN, KC_SLEP, _______, UC_NEXT, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, X(UAT), X(UHSH), X(UDLR), X(USCT), X(UCFX), X(UAMP), X(UAST), _______, _______, _______, _______, _______, _______, _______, _______, KC_CALC, _______, _______, _______, - _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_BTN3, _______, _______, _______, KC_SYRQ, KC_SCRL, KC_PAUS, XP(ULSB, ULCB), XP(URSB, URCB), _______, _______, _______, _______, _______, _______, _______, - _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_BTN5, _______, _______, _______, _______, _______, XP(USCO, UCLN), XP(UAPO, UQOT), _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, KC_BTN4, _______, _______, _______, _______, XP(UCOM, ULTH), XP(UDOT, UGTH), XP(USLS, UQUE), KC_APP, _______, _______, _______, _______, _______, _______, _______, + _______, _______, UM(UAT), UM(UHSH), UM(UDLR), UM(USCT), UM(UCFX), UM(UAMP), UM(UAST), _______, _______, _______, _______, _______, _______, _______, _______, KC_CALC, _______, _______, _______, + _______, KC_BTN1, KC_MS_U, KC_BTN2, KC_BTN3, _______, _______, _______, KC_SYRQ, KC_SCRL, KC_PAUS, UP(ULSB, ULCB), UP(URSB, URCB), _______, _______, _______, _______, _______, _______, _______, + _______, KC_MS_L, KC_MS_D, KC_MS_R, KC_BTN5, _______, _______, _______, _______, _______, UP(USCO, UCLN), UP(UAPO, UQOT), _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, KC_BTN4, _______, _______, _______, _______, UP(UCOM, ULTH), UP(UDOT, UGTH), UP(USLS, UQUE), KC_APP, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ) }; diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h index a0355469e91e..9ed3bc9702d1 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h +++ b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/config.h @@ -21,8 +21,6 @@ along with this program. If not, see . // WS2812 RGB LED strip input and number of LEDs #define RGBLED_NUM 20 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT \ - { 10, 10 } #define AUDIO_PIN C6 diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/info.json b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/info.json index e0d074c2b6d6..3ea61f0a1a4a 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/info.json +++ b/keyboards/handwired/tractyl_manuform/5x6_right/elite_c/info.json @@ -17,7 +17,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 80 + "max_brightness": 80, + "split_count": [10, 10] }, "processor": "atmega32u4", "bootloader": "atmel-dfu" diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h index 2d05b71c92ee..9c02cc3b2895 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f303/config.h @@ -31,8 +31,6 @@ along with this program. If not, see . #define RGBLED_NUM 20 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT \ - { 10, 10 } #define DEBUG_LED_PIN C13 diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f303/info.json b/keyboards/handwired/tractyl_manuform/5x6_right/f303/info.json index 0e0e020ddfb5..7e9f90fb1f03 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f303/info.json +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f303/info.json @@ -5,6 +5,9 @@ "rows": ["B10", "B11", "B12", "A14", "A13", "A15"] }, "diode_direction": "COL2ROW", + "rgblight": { + "split_count": [10, 10] + }, "ws2812": { "pin": "A6", "driver": "pwm" diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h index 73ea40fb764c..532ca017fba7 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f411/config.h @@ -34,8 +34,6 @@ along with this program. If not, see . #define RGBLED_NUM 57 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT \ - { 26, 31 } #define DEBUG_LED_PIN C13 diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/f411/info.json b/keyboards/handwired/tractyl_manuform/5x6_right/f411/info.json index 671e3746c66b..ca4f930cbf5f 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/f411/info.json +++ b/keyboards/handwired/tractyl_manuform/5x6_right/f411/info.json @@ -5,6 +5,9 @@ "rows": ["B12", "B13", "B14", "B15", "A8", "A10"] }, "diode_direction": "COL2ROW", + "rgblight": { + "split_count": [26, 31] + }, "ws2812": { "pin": "A1", "driver": "pwm" diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h index ce8e65e92486..c45500050ae6 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h +++ b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/config.h @@ -21,8 +21,6 @@ along with this program. If not, see . // WS2812 RGB LED strip input and number of LEDs #define RGBLED_NUM 20 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT \ - { 10, 10 } #define RGBLIGHT_LIMIT_VAL 80 #define DEBUG_LED_PIN D6 diff --git a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/info.json b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/info.json index c65b2266015d..725c519c0ec8 100644 --- a/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/info.json +++ b/keyboards/handwired/tractyl_manuform/5x6_right/teensy2pp/info.json @@ -17,7 +17,8 @@ "pin": "E7" }, "rgblight": { - "max_brightness": 80 + "max_brightness": 80, + "split_count": [10, 10] }, "processor": "at90usb1286", "bootloader": "halfkay" diff --git a/keyboards/handwired/tsubasa/config.h b/keyboards/handwired/tsubasa/config.h index dee2156fb544..fee26e10350f 100644 --- a/keyboards/handwired/tsubasa/config.h +++ b/keyboards/handwired/tsubasa/config.h @@ -20,7 +20,6 @@ along with this program. If not, see . # define RGBLED_NUM 12 # define RGBLIGHT_SPLIT -# define RGBLED_SPLIT {6, 6} # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 1 # define RGBLIGHT_VAL_STEP 1 diff --git a/keyboards/handwired/tsubasa/info.json b/keyboards/handwired/tsubasa/info.json index 351731a6139d..e1966467597a 100644 --- a/keyboards/handwired/tsubasa/info.json +++ b/keyboards/handwired/tsubasa/info.json @@ -8,6 +8,9 @@ "pid": "0x0000", "device_version": "1.0.0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D2" }, diff --git a/keyboards/handwired/wulkan/keymaps/default/keymap.c b/keyboards/handwired/wulkan/keymaps/default/keymap.c index b73592760e2b..3a333198a44b 100644 --- a/keyboards/handwired/wulkan/keymaps/default/keymap.c +++ b/keyboards/handwired/wulkan/keymaps/default/keymap.c @@ -95,8 +95,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * `-----------------------------------------------------------------------------------' */ [_ADJUST] = LAYOUT_ortho_4x12( - _______, QK_BOOT, _______, _______, KC_WH_U, _______, _______, KC_MS_U, _______, _______, XP(SE_ARNG_LOW, SE_ARNG_HIGH), KC_DEL, - _______, _______, _______, _______, KC_WH_D, _______, KC_MS_L, KC_MS_D, KC_MS_R, XP(SE_ODIA_LOW, SE_ODIA_HIGH), XP(SE_ADIA_LOW, SE_ADIA_HIGH), _______, + _______, QK_BOOT, _______, _______, KC_WH_U, _______, _______, KC_MS_U, _______, _______, UP(SE_ARNG_LOW, SE_ARNG_HIGH), KC_DEL, + _______, _______, _______, _______, KC_WH_D, _______, KC_MS_L, KC_MS_D, KC_MS_R, UP(SE_ODIA_LOW, SE_ODIA_HIGH), UP(SE_ADIA_LOW, SE_ADIA_HIGH), _______, _______, KC_ACL0, KC_ACL1, KC_ACL2, _______, _______, KC_BTN1, _______, KC_BTN2, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ) diff --git a/keyboards/helix/rev3_4rows/config.h b/keyboards/helix/rev3_4rows/config.h index 2eda425a4f13..8a29ae41f707 100644 --- a/keyboards/helix/rev3_4rows/config.h +++ b/keyboards/helix/rev3_4rows/config.h @@ -65,7 +65,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 25, 25 } // #define RGBLIGHT_HUE_STEP 8 // #define RGBLIGHT_SAT_STEP 8 // #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/helix/rev3_4rows/info.json b/keyboards/helix/rev3_4rows/info.json index 9a832bbb5b9f..ed2c1544b85d 100644 --- a/keyboards/helix/rev3_4rows/info.json +++ b/keyboards/helix/rev3_4rows/info.json @@ -23,7 +23,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [25, 25] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/helix/rev3_5rows/config.h b/keyboards/helix/rev3_5rows/config.h index bd09cc60abef..716bdf162fcf 100644 --- a/keyboards/helix/rev3_5rows/config.h +++ b/keyboards/helix/rev3_5rows/config.h @@ -65,7 +65,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 32, 32 } // #define RGBLIGHT_HUE_STEP 8 // #define RGBLIGHT_SAT_STEP 8 // #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/helix/rev3_5rows/info.json b/keyboards/helix/rev3_5rows/info.json index 2ae80dd90113..bdb5bfaf6b28 100644 --- a/keyboards/helix/rev3_5rows/info.json +++ b/keyboards/helix/rev3_5rows/info.json @@ -23,7 +23,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [32, 32] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/hidtech/bastyl/keymaps/nstickney/keymap.c b/keyboards/hidtech/bastyl/keymaps/nstickney/keymap.c index 8dbb31130913..e068f81a73f5 100644 --- a/keyboards/hidtech/bastyl/keymaps/nstickney/keymap.c +++ b/keyboards/hidtech/bastyl/keymaps/nstickney/keymap.c @@ -33,15 +33,15 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { //-------------------------------// KC_LBRC, TD(LOCKS), TD(LAYERS), KC_RBRC), - [SYMB] = LAYOUT(_______, XP(IEX, SS1), X(SS2), X(SS3), XP(CUR, GBP), X(EUR), X(V14), X(V12), X(V34), XP(LSQ, LDQ), XP(RSQ, RDQ), _______, + [SYMB] = LAYOUT(_______, UP(IEX, SS1), UM(SS2), UM(SS3), UP(CUR, GBP), UM(EUR), UM(V14), UM(V12), UM(V34), UP(LSQ, LDQ), UP(RSQ, RDQ), _______, //-------------------------------// - _______, XP(A_D, AXD), XP(A_R, ACR), XP(E_A, ECA), XP(REG, CPL), X(THR), XP(U_D, UCD), XP(U_A, UCA), XP(I_A, ICA), XP(O_A, OCA), XP(O_D, OCD), _______, + _______, UP(A_D, AXD), UP(A_R, ACR), UP(E_A, ECA), UP(REG, CPL), UM(THR), UP(U_D, UCD), UP(U_A, UCA), UP(I_A, ICA), UP(O_A, OCA), UP(O_D, OCD), _______, //-------------------------------// - _______, XP(A_A, ACA), XP(S_S, SEC), XP(ETH, ETC), X(EMD), _______, _______, _______, _______, XP(O_S, OCS), XP(PLC, DEG), XP(ACT, DIS), + _______, UP(A_A, ACA), UP(S_S, SEC), UP(ETH, ETC), UM(EMD), _______, _______, _______, _______, UP(O_S, OCS), UP(PLC, DEG), UP(ACT, DIS), //-------------------------------// - _______, XP(AEL, AEC), _______, XP(CPR, CNT), _______, _______, _______, _______, XP(N_T, NCT), X(MCR), XP(C_C, CCC), _______, + _______, UP(AEL, AEC), _______, UP(CPR, CNT), _______, _______, _______, _______, UP(N_T, NCT), UM(MCR), UP(C_C, CCC), _______, //-------------------------------// - X(IQM), XP(NOT, BKB), _______, _______, X(YEN), XP(MLT, DIV), + UM(IQM), UP(NOT, BKB), _______, _______, UM(YEN), UP(MLT, DIV), //-------------------------------// _______, _______, _______, _______), diff --git a/keyboards/jiran/rev2/config.h b/keyboards/jiran/rev2/config.h index ce78530cb76e..39e1eaae4c7a 100644 --- a/keyboards/jiran/rev2/config.h +++ b/keyboards/jiran/rev2/config.h @@ -29,7 +29,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 56 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 28, 28 } #define RGBLIGHT_HUE_STEP 10 #define RGBLIGHT_SAT_STEP 17 #define RGBLIGHT_VAL_STEP 17 diff --git a/keyboards/jiran/rev2/info.json b/keyboards/jiran/rev2/info.json index 8539b47652e2..9ee15f7af11a 100644 --- a/keyboards/jiran/rev2/info.json +++ b/keyboards/jiran/rev2/info.json @@ -1,4 +1,7 @@ { + "rgblight": { + "split_count": [28, 28] + }, "ws2812": { "pin": "B6" }, diff --git a/keyboards/jorne/rev1/config.h b/keyboards/jorne/rev1/config.h index 73e2d8219ba4..4a41d3e358e7 100644 --- a/keyboards/jorne/rev1/config.h +++ b/keyboards/jorne/rev1/config.h @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#define RGBLED_SPLIT { 28, 28 } #define RGBLED_NUM 56 /* Mechanical locking support. Use KC_LCAP, KC_LNUM or KC_LSCR instead in keymap */ diff --git a/keyboards/jorne/rev1/info.json b/keyboards/jorne/rev1/info.json index f07f99e4a691..f0a1817e8b79 100644 --- a/keyboards/jorne/rev1/info.json +++ b/keyboards/jorne/rev1/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [28, 28] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/kakunpc/rabbit_capture_plan/config.h b/keyboards/kakunpc/rabbit_capture_plan/config.h index 6a6c2678bf37..f6b85fddb2db 100644 --- a/keyboards/kakunpc/rabbit_capture_plan/config.h +++ b/keyboards/kakunpc/rabbit_capture_plan/config.h @@ -17,7 +17,6 @@ along with this program. If not, see . #pragma once -#define RGBLED_SPLIT {32, 37} # define RGBLED_NUM 69 # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 diff --git a/keyboards/kakunpc/rabbit_capture_plan/info.json b/keyboards/kakunpc/rabbit_capture_plan/info.json index d988e940341f..b68e6a7e6192 100644 --- a/keyboards/kakunpc/rabbit_capture_plan/info.json +++ b/keyboards/kakunpc/rabbit_capture_plan/info.json @@ -12,7 +12,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 200 + "max_brightness": 200, + "split_count": [32, 37] }, "matrix_pins": { "cols": ["F4", "F5", "F6", "F7", "B1", "B3", "B2", "B6"], diff --git a/keyboards/kakunpc/suihankey/alpha/config.h b/keyboards/kakunpc/suihankey/alpha/config.h index 2e4fa2625f04..20d6d77f7aec 100644 --- a/keyboards/kakunpc/suihankey/alpha/config.h +++ b/keyboards/kakunpc/suihankey/alpha/config.h @@ -53,5 +53,3 @@ along with this program. If not, see . //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT - -// #define RGBLED_SPLIT {18,18} diff --git a/keyboards/kakunpc/suihankey/rev1/config.h b/keyboards/kakunpc/suihankey/rev1/config.h index 2e4fa2625f04..20d6d77f7aec 100644 --- a/keyboards/kakunpc/suihankey/rev1/config.h +++ b/keyboards/kakunpc/suihankey/rev1/config.h @@ -53,5 +53,3 @@ along with this program. If not, see . //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT - -// #define RGBLED_SPLIT {18,18} diff --git a/keyboards/kakunpc/suihankey/split/alpha/config.h b/keyboards/kakunpc/suihankey/split/alpha/config.h index 1fda3473f375..4ea307997455 100644 --- a/keyboards/kakunpc/suihankey/split/alpha/config.h +++ b/keyboards/kakunpc/suihankey/split/alpha/config.h @@ -47,5 +47,3 @@ along with this program. If not, see . //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT - -// #define RGBLED_SPLIT {18,18} diff --git a/keyboards/kakunpc/suihankey/split/rev1/config.h b/keyboards/kakunpc/suihankey/split/rev1/config.h index 86e33438b5e4..340f8030b945 100644 --- a/keyboards/kakunpc/suihankey/split/rev1/config.h +++ b/keyboards/kakunpc/suihankey/split/rev1/config.h @@ -57,5 +57,3 @@ along with this program. If not, see . //#define NO_ACTION_LAYER //#define NO_ACTION_TAPPING //#define NO_ACTION_ONESHOT - -// #define RGBLED_SPLIT {18,18} diff --git a/keyboards/kapl/rev1/config.h b/keyboards/kapl/rev1/config.h index 8dc6718d1a03..82df4355ead9 100644 --- a/keyboards/kapl/rev1/config.h +++ b/keyboards/kapl/rev1/config.h @@ -6,7 +6,6 @@ #define MASTER_LEFT #define RGBLED_NUM 88 -#define RGBLED_SPLIT { 44, 44 } #define RGBLIGHT_SPLIT #define RGB_MATRIX_LED_COUNT 88 diff --git a/keyboards/kapl/rev1/info.json b/keyboards/kapl/rev1/info.json index ad310fa87cef..cab51ec837d8 100644 --- a/keyboards/kapl/rev1/info.json +++ b/keyboards/kapl/rev1/info.json @@ -15,7 +15,8 @@ "driver": "WS2812" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [44, 44] }, "matrix_pins": { "cols": ["F5", "F6", "F7", "B1", "B3", "B2", "B6"], diff --git a/keyboards/keebio/bfo9000/config.h b/keyboards/keebio/bfo9000/config.h index 48fd0aaf0cba..ecc01620e649 100644 --- a/keyboards/keebio/bfo9000/config.h +++ b/keyboards/keebio/bfo9000/config.h @@ -25,7 +25,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 20 // Number of LEDs -#define RGBLED_SPLIT { 10, 10 } /* * Feature disable options diff --git a/keyboards/keebio/bfo9000/info.json b/keyboards/keebio/bfo9000/info.json index 9900dbe951d5..39b8cd7e2ceb 100644 --- a/keyboards/keebio/bfo9000/info.json +++ b/keyboards/keebio/bfo9000/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [10, 10] + }, "ws2812": { "pin": "B4" }, diff --git a/keyboards/keebio/foldkb/rev1/config.h b/keyboards/keebio/foldkb/rev1/config.h index 30154273b736..efdd195b5d1a 100644 --- a/keyboards/keebio/foldkb/rev1/config.h +++ b/keyboards/keebio/foldkb/rev1/config.h @@ -35,6 +35,5 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 0, 1, 2, 3, 12, 13, 14, 15, 4, 5, 6, 7, 8, 9, 10, 11 } #define RGBLIGHT_DEFAULT_MODE (RGBLIGHT_MODE_RAINBOW_SWIRL + 2) diff --git a/keyboards/keebio/foldkb/rev1/info.json b/keyboards/keebio/foldkb/rev1/info.json index e17389cc2c55..705bd7cc8a6d 100644 --- a/keyboards/keebio/foldkb/rev1/info.json +++ b/keyboards/keebio/foldkb/rev1/info.json @@ -24,6 +24,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/fourier/config.h b/keyboards/keebio/fourier/config.h index 904658ff8ad5..59ea066451c9 100644 --- a/keyboards/keebio/fourier/config.h +++ b/keyboards/keebio/fourier/config.h @@ -38,7 +38,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 14 // Number of LEDs -#define RGBLED_SPLIT { 7, 7 } /* * Feature disable options diff --git a/keyboards/keebio/fourier/info.json b/keyboards/keebio/fourier/info.json index a9b37bda0081..7d12c8c60bd0 100644 --- a/keyboards/keebio/fourier/info.json +++ b/keyboards/keebio/fourier/info.json @@ -22,6 +22,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [7, 7] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/iris/keymaps/nstickney/keymap.c b/keyboards/keebio/iris/keymaps/nstickney/keymap.c index cc4c5bf37539..cf53ffd93485 100644 --- a/keyboards/keebio/iris/keymaps/nstickney/keymap.c +++ b/keyboards/keebio/iris/keymaps/nstickney/keymap.c @@ -27,11 +27,11 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), [SYMB] = LAYOUT( - _______, XP(IEX, SS1), X(SS2), X(SS3), XP(CUR, GBP), X(EUR), X(V14), X(V12), X(V34), XP(LSQ, LDQ), XP(RSQ, RDQ), _______, - _______, XP(A_D, AXD), XP(A_R, ACR), XP(E_A, ECA), XP(REG, CPL), X(THR), XP(U_D, UCD), XP(U_A, UCA), XP(I_A, ICA), XP(O_A, OCA), XP(O_D, OCD), _______, - _______, XP(A_A, ACA), XP(S_S, SEC), XP(ETH, ETC), X(EMD), _______, _______, _______, _______, XP(O_S, OCS), XP(PLC, DEG), XP(ACT, DIS), - _______, XP(AEL, AEC), _______, XP(CPR, CNT), _______, _______, _______, _______, XP(N_T, NCT), X(MCR), XP(C_C, CCC), _______, _______, _______, - X(IQM), XP(NOT, BKB), _______, _______, X(YEN), XP(MLT, DIV) + _______, UP(IEX, SS1), UM(SS2), UM(SS3), UP(CUR, GBP), UM(EUR), UM(V14), UM(V12), UM(V34), UP(LSQ, LDQ), UP(RSQ, RDQ), _______, + _______, UP(A_D, AXD), UP(A_R, ACR), UP(E_A, ECA), UP(REG, CPL), UM(THR), UP(U_D, UCD), UP(U_A, UCA), UP(I_A, ICA), UP(O_A, OCA), UP(O_D, OCD), _______, + _______, UP(A_A, ACA), UP(S_S, SEC), UP(ETH, ETC), UM(EMD), _______, _______, _______, _______, UP(O_S, OCS), UP(PLC, DEG), UP(ACT, DIS), + _______, UP(AEL, AEC), _______, UP(CPR, CNT), _______, _______, _______, _______, UP(N_T, NCT), UM(MCR), UP(C_C, CCC), _______, _______, _______, + UM(IQM), UP(NOT, BKB), _______, _______, UM(YEN), UP(MLT, DIV) ), [NUMP] = LAYOUT( diff --git a/keyboards/keebio/iris/rev2/config.h b/keyboards/keebio/iris/rev2/config.h index 59867e6ef907..7fd5c0ff951e 100644 --- a/keyboards/keebio/iris/rev2/config.h +++ b/keyboards/keebio/iris/rev2/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/keebio/iris/rev2/info.json b/keyboards/keebio/iris/rev2/info.json index 80e65aa8e2e3..2eef2853d87b 100644 --- a/keyboards/keebio/iris/rev2/info.json +++ b/keyboards/keebio/iris/rev2/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/iris/rev3/config.h b/keyboards/keebio/iris/rev3/config.h index c7a7222fdcf9..2bc112261ad2 100644 --- a/keyboards/keebio/iris/rev3/config.h +++ b/keyboards/keebio/iris/rev3/config.h @@ -26,7 +26,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/keebio/iris/rev3/info.json b/keyboards/keebio/iris/rev3/info.json index adc4b713548f..4d427f752784 100644 --- a/keyboards/keebio/iris/rev3/info.json +++ b/keyboards/keebio/iris/rev3/info.json @@ -18,6 +18,9 @@ "pin": "B6", "levels": 5 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "F7" }, diff --git a/keyboards/keebio/iris/rev4/config.h b/keyboards/keebio/iris/rev4/config.h index eaeca3a4b98d..2a278b2fb289 100644 --- a/keyboards/keebio/iris/rev4/config.h +++ b/keyboards/keebio/iris/rev4/config.h @@ -26,7 +26,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/keebio/iris/rev4/info.json b/keyboards/keebio/iris/rev4/info.json index 6ddb257d21be..d0aa0d12c999 100644 --- a/keyboards/keebio/iris/rev4/info.json +++ b/keyboards/keebio/iris/rev4/info.json @@ -18,6 +18,9 @@ "pin": "B5", "levels": 5 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D6" }, diff --git a/keyboards/keebio/iris/rev5/config.h b/keyboards/keebio/iris/rev5/config.h index 12ff3a2a4d17..78e747168d24 100644 --- a/keyboards/keebio/iris/rev5/config.h +++ b/keyboards/keebio/iris/rev5/config.h @@ -23,7 +23,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/keebio/iris/rev5/info.json b/keyboards/keebio/iris/rev5/info.json index 98c0d3bf2dea..ec8b01893a8c 100644 --- a/keyboards/keebio/iris/rev5/info.json +++ b/keyboards/keebio/iris/rev5/info.json @@ -18,6 +18,9 @@ "pin": "B5", "levels": 5 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D6" }, diff --git a/keyboards/keebio/iris/rev6/config.h b/keyboards/keebio/iris/rev6/config.h index 79f92b75a939..a7a588a6866f 100644 --- a/keyboards/keebio/iris/rev6/config.h +++ b/keyboards/keebio/iris/rev6/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ # define RGBLED_NUM 68 -# define RGBLED_SPLIT { 34, 34 } # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/keebio/iris/rev6/info.json b/keyboards/keebio/iris/rev6/info.json index 632b5f10d89a..a7df66990434 100644 --- a/keyboards/keebio/iris/rev6/info.json +++ b/keyboards/keebio/iris/rev6/info.json @@ -21,7 +21,8 @@ "pin": "E6" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [34, 34] }, "split": { "soft_serial_pin": "D0", diff --git a/keyboards/keebio/iris/rev7/config.h b/keyboards/keebio/iris/rev7/config.h index dd4284cb9b2a..248cf16a0367 100644 --- a/keyboards/keebio/iris/rev7/config.h +++ b/keyboards/keebio/iris/rev7/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ # define RGBLED_NUM 68 -# define RGBLED_SPLIT { 34, 34 } # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/keebio/iris/rev7/info.json b/keyboards/keebio/iris/rev7/info.json index 7ed57fb873bf..9d6cad296ede 100644 --- a/keyboards/keebio/iris/rev7/info.json +++ b/keyboards/keebio/iris/rev7/info.json @@ -22,7 +22,8 @@ "pin": "E6" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [34, 34] }, "split": { "soft_serial_pin": "D0", diff --git a/keyboards/keebio/kbo5000/rev1/config.h b/keyboards/keebio/kbo5000/rev1/config.h index f02c15c4a78c..c22aff38be5c 100644 --- a/keyboards/keebio/kbo5000/rev1/config.h +++ b/keyboards/keebio/kbo5000/rev1/config.h @@ -39,5 +39,4 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 } diff --git a/keyboards/keebio/kbo5000/rev1/info.json b/keyboards/keebio/kbo5000/rev1/info.json index d40c12b52d64..e1b4d90492f8 100644 --- a/keyboards/keebio/kbo5000/rev1/info.json +++ b/keyboards/keebio/kbo5000/rev1/info.json @@ -21,6 +21,9 @@ "backlight": { "pin": "B5" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/levinson/rev1/config.h b/keyboards/keebio/levinson/rev1/config.h index b1922fb9c3b1..b6d4d6471922 100644 --- a/keyboards/keebio/levinson/rev1/config.h +++ b/keyboards/keebio/levinson/rev1/config.h @@ -26,4 +26,3 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } diff --git a/keyboards/keebio/levinson/rev1/info.json b/keyboards/keebio/levinson/rev1/info.json index c23887a49f2c..f947546b3d59 100644 --- a/keyboards/keebio/levinson/rev1/info.json +++ b/keyboards/keebio/levinson/rev1/info.json @@ -16,6 +16,9 @@ "pin": "C6", "levels": 7 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/levinson/rev2/config.h b/keyboards/keebio/levinson/rev2/config.h index b1922fb9c3b1..b6d4d6471922 100644 --- a/keyboards/keebio/levinson/rev2/config.h +++ b/keyboards/keebio/levinson/rev2/config.h @@ -26,4 +26,3 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } diff --git a/keyboards/keebio/levinson/rev2/info.json b/keyboards/keebio/levinson/rev2/info.json index aab339166e6a..ea62141edd2b 100644 --- a/keyboards/keebio/levinson/rev2/info.json +++ b/keyboards/keebio/levinson/rev2/info.json @@ -16,6 +16,9 @@ "pin": "B5", "levels": 7 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/levinson/rev3/config.h b/keyboards/keebio/levinson/rev3/config.h index d2e19703c106..3521356e7d09 100644 --- a/keyboards/keebio/levinson/rev3/config.h +++ b/keyboards/keebio/levinson/rev3/config.h @@ -28,4 +28,3 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } diff --git a/keyboards/keebio/levinson/rev3/info.json b/keyboards/keebio/levinson/rev3/info.json index e5e479ba7ae1..81230247b681 100644 --- a/keyboards/keebio/levinson/rev3/info.json +++ b/keyboards/keebio/levinson/rev3/info.json @@ -22,6 +22,9 @@ "pin": "B6", "levels": 7 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D7" }, diff --git a/keyboards/keebio/nyquist/keymaps/bramver/keymap.c b/keyboards/keebio/nyquist/keymaps/bramver/keymap.c index 04433c41cde8..4518cb326d88 100644 --- a/keyboards/keebio/nyquist/keymaps/bramver/keymap.c +++ b/keyboards/keebio/nyquist/keymaps/bramver/keymap.c @@ -232,9 +232,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_EMOJI] = LAYOUT( TO(0) , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , /**/ QK_BOOT , XXXXXXX , XXXXXXX , XXXXXXX , XXXXXXX , _______ , - _______ , X(CLAP) , X(CUM) , X(BNIS) , X(BUTT) , X(CAR) , /**/ X(FIRE) , X(REDB) , X(MONY) , X(HNDR) , X(SOS) , _______ , - XXXXXXX , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , /**/ X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , KC_DEL , - _______ , X(TRIU) , X(SCRM) , X(VOMI) , X(DTIV) , X(EXPL) , /**/ X(HAIR) , X(DANC) , X(STRN) , X(LEFT) , X(RGHT) , _______ , + _______ , UM(CLAP) , UM(CUM) , UM(BNIS) , UM(BUTT) , UM(CAR) , /**/ UM(FIRE) , UM(REDB) , UM(MONY) , UM(HNDR) , UM(SOS) , _______ , + XXXXXXX , UM(CELE) , UM(PRAY) , UM(NAIL) , UM(OK) , UM(THNK) , /**/ UM(UNAM) , UM(HEYE) , UM(COOL) , UM(EYES) , UM(SMIR) , KC_DEL , + _______ , UM(TRIU) , UM(SCRM) , UM(VOMI) , UM(DTIV) , UM(EXPL) , /**/ UM(HAIR) , UM(DANC) , UM(STRN) , UM(LEFT) , UM(RGHT) , _______ , _______ , _______ , _______ , _______ , _______ , XXXXXXX , /**/ XXXXXXX , _______ , _______ , _______ , XXXXXXX , _______ ), diff --git a/keyboards/keebio/nyquist/rev1/config.h b/keyboards/keebio/nyquist/rev1/config.h index ab1c967e70d2..e4878b790a67 100644 --- a/keyboards/keebio/nyquist/rev1/config.h +++ b/keyboards/keebio/nyquist/rev1/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 6, 6 } /* * Feature disable options diff --git a/keyboards/keebio/nyquist/rev1/info.json b/keyboards/keebio/nyquist/rev1/info.json index 64d613dccf0d..b75a6787976b 100644 --- a/keyboards/keebio/nyquist/rev1/info.json +++ b/keyboards/keebio/nyquist/rev1/info.json @@ -12,6 +12,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/nyquist/rev2/config.h b/keyboards/keebio/nyquist/rev2/config.h index ab1c967e70d2..e4878b790a67 100644 --- a/keyboards/keebio/nyquist/rev2/config.h +++ b/keyboards/keebio/nyquist/rev2/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 6, 6 } /* * Feature disable options diff --git a/keyboards/keebio/nyquist/rev2/info.json b/keyboards/keebio/nyquist/rev2/info.json index 05b4ea0b7ef1..4a802ad45493 100644 --- a/keyboards/keebio/nyquist/rev2/info.json +++ b/keyboards/keebio/nyquist/rev2/info.json @@ -13,6 +13,9 @@ "pin": "B6", "levels": 7 }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/nyquist/rev3/config.h b/keyboards/keebio/nyquist/rev3/config.h index 7b014e4fc563..8d3be7827d98 100644 --- a/keyboards/keebio/nyquist/rev3/config.h +++ b/keyboards/keebio/nyquist/rev3/config.h @@ -36,7 +36,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 12 -#define RGBLED_SPLIT { 6, 6 } /* * Feature disable options diff --git a/keyboards/keebio/nyquist/rev3/info.json b/keyboards/keebio/nyquist/rev3/info.json index eb17350d6399..9eb4c51323fd 100644 --- a/keyboards/keebio/nyquist/rev3/info.json +++ b/keyboards/keebio/nyquist/rev3/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "B4" }, diff --git a/keyboards/keebio/quefrency/keymaps/bramver/README.md b/keyboards/keebio/quefrency/keymaps/bramver/README.md index 547e2686f88b..1665e4fd3eb9 100644 --- a/keyboards/keebio/quefrency/keymaps/bramver/README.md +++ b/keyboards/keebio/quefrency/keymaps/bramver/README.md @@ -51,9 +51,9 @@ Mostly based off of my other XD75 and Nyquist layouts. /* EMOJ * * _______ , _______ , _______ , _______ , _______ , _______ , _______ , /**/ _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , - * _______ , X(CLAP) , X(CUM) , X(BNIS) , X(BUTT) , X(CAR) , /**/ X(FIRE) , X(REDB) , X(MONY) , X(HNDR) , X(SOS) , _______ , _______ , _______ , - * _______ , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , /**/ X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , _______ , _______ , - * _______ , X(TRIU) , X(SCRM) , X(VOMI) , X(DTIV) , X(EXPL) , /**/ X(HAIR) , X(DANC) , X(STRN) , X(LEFT) , X(RGHT) , _______ , _______ , + * _______ , UM(CLAP) , UM(CUM) , UM(BNIS) , UM(BUTT) , UM(CAR) , /**/ UM(FIRE) , UM(REDB) , UM(MONY) , UM(HNDR) , UM(SOS) , _______ , _______ , _______ , + * _______ , UM(CELE) , UM(PRAY) , UM(NAIL) , UM(OK) , UM(THNK) , /**/ UM(UNAM) , UM(HEYE) , UM(COOL) , UM(EYES) , UM(SMIR) , _______ , _______ , + * _______ , UM(TRIU) , UM(SCRM) , UM(VOMI) , UM(DTIV) , UM(EXPL) , /**/ UM(HAIR) , UM(DANC) , UM(STRN) , UM(LEFT) , UM(RGHT) , _______ , _______ , * _______ , _______ , _______ , _______ , _______ , /**/ _______ , _______ , _______ , _______ , _______ , _______ , _______ * */ diff --git a/keyboards/keebio/quefrency/keymaps/bramver/keymap.c b/keyboards/keebio/quefrency/keymaps/bramver/keymap.c index f855425ec018..9c6729e91e2f 100644 --- a/keyboards/keebio/quefrency/keymaps/bramver/keymap.c +++ b/keyboards/keebio/quefrency/keymaps/bramver/keymap.c @@ -118,9 +118,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_EMOJ] = LAYOUT( _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , - _______ , X(CLAP) , X(CUM) , X(BNIS) , X(BUTT) , X(CAR) , X(FIRE) , X(REDB) , X(MONY) , X(HNDR) , X(SOS) , _______ , _______ , _______ , - _______ , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , _______ , _______ , - _______ , X(TRIU) , X(SCRM) , X(VOMI) , X(DTIV) , X(EXPL) , X(HAIR) , X(DANC) , X(STRN) , X(LEFT) , X(RGHT) , _______ , _______ , + _______ , UM(CLAP) , UM(CUM) , UM(BNIS) , UM(BUTT) , UM(CAR) , UM(FIRE) , UM(REDB) , UM(MONY) , UM(HNDR) , UM(SOS) , _______ , _______ , _______ , + _______ , UM(CELE) , UM(PRAY) , UM(NAIL) , UM(OK) , UM(THNK) , UM(UNAM) , UM(HEYE) , UM(COOL) , UM(EYES) , UM(SMIR) , _______ , _______ , + _______ , UM(TRIU) , UM(SCRM) , UM(VOMI) , UM(DTIV) , UM(EXPL) , UM(HAIR) , UM(DANC) , UM(STRN) , UM(LEFT) , UM(RGHT) , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ), diff --git a/keyboards/keebio/quefrency/rev1/config.h b/keyboards/keebio/quefrency/rev1/config.h index 83fcd1fe0ac9..f439fd05af74 100644 --- a/keyboards/keebio/quefrency/rev1/config.h +++ b/keyboards/keebio/quefrency/rev1/config.h @@ -37,7 +37,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } // Set 65% column (option 1) and Macro (option 2) on by default #define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x60 diff --git a/keyboards/keebio/quefrency/rev1/info.json b/keyboards/keebio/quefrency/rev1/info.json index 7fb5ca8153d4..cf44ce3b8195 100644 --- a/keyboards/keebio/quefrency/rev1/info.json +++ b/keyboards/keebio/quefrency/rev1/info.json @@ -8,6 +8,9 @@ "pid": "0x1257", "device_version": "1.0.0" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/quefrency/rev2/config.h b/keyboards/keebio/quefrency/rev2/config.h index e7774432dfa3..20f625af304a 100644 --- a/keyboards/keebio/quefrency/rev2/config.h +++ b/keyboards/keebio/quefrency/rev2/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/keebio/quefrency/rev2/info.json b/keyboards/keebio/quefrency/rev2/info.json index d73c1af308f0..d9bbab9795df 100644 --- a/keyboards/keebio/quefrency/rev2/info.json +++ b/keyboards/keebio/quefrency/rev2/info.json @@ -21,6 +21,9 @@ "backlight": { "pin": "B5" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/quefrency/rev3/config.h b/keyboards/keebio/quefrency/rev3/config.h index e7774432dfa3..20f625af304a 100644 --- a/keyboards/keebio/quefrency/rev3/config.h +++ b/keyboards/keebio/quefrency/rev3/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/keebio/quefrency/rev3/info.json b/keyboards/keebio/quefrency/rev3/info.json index fb204ab91072..4f14a0f6a829 100644 --- a/keyboards/keebio/quefrency/rev3/info.json +++ b/keyboards/keebio/quefrency/rev3/info.json @@ -21,6 +21,9 @@ "backlight": { "pin": "B5" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/quefrency/rev4/config.h b/keyboards/keebio/quefrency/rev4/config.h index b27ba56d538c..da173dde3ee5 100644 --- a/keyboards/keebio/quefrency/rev4/config.h +++ b/keyboards/keebio/quefrency/rev4/config.h @@ -25,7 +25,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 } #define RGBLIGHT_DEFAULT_MODE (RGBLIGHT_MODE_RAINBOW_SWIRL + 2) #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/keebio/quefrency/rev4/info.json b/keyboards/keebio/quefrency/rev4/info.json index 55fb4adda497..64a2361f81b0 100644 --- a/keyboards/keebio/quefrency/rev4/info.json +++ b/keyboards/keebio/quefrency/rev4/info.json @@ -18,6 +18,9 @@ {"pin_a": "F5", "pin_b": "F6"} ] }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/quefrency/rev5/config.h b/keyboards/keebio/quefrency/rev5/config.h index b27ba56d538c..da173dde3ee5 100644 --- a/keyboards/keebio/quefrency/rev5/config.h +++ b/keyboards/keebio/quefrency/rev5/config.h @@ -25,7 +25,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 16 // Number of LEDs -#define RGBLED_SPLIT { 8, 8 } #define RGBLIGHT_LED_MAP { 1, 2, 3, 12, 13, 14, 15, 0, 7, 6, 5, 4, 11, 10, 9, 8 } #define RGBLIGHT_DEFAULT_MODE (RGBLIGHT_MODE_RAINBOW_SWIRL + 2) #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/keebio/quefrency/rev5/info.json b/keyboards/keebio/quefrency/rev5/info.json index 78a44dfc8019..3d60d7904876 100644 --- a/keyboards/keebio/quefrency/rev5/info.json +++ b/keyboards/keebio/quefrency/rev5/info.json @@ -18,6 +18,9 @@ {"pin_a": "F5", "pin_b": "F6"} ] }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/keebio/viterbi/rev1/config.h b/keyboards/keebio/viterbi/rev1/config.h index 1dfed1a82f42..204afe952cfd 100644 --- a/keyboards/keebio/viterbi/rev1/config.h +++ b/keyboards/keebio/viterbi/rev1/config.h @@ -24,4 +24,3 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 14 -#define RGBLED_SPLIT { 7, 7 } diff --git a/keyboards/keebio/viterbi/rev1/info.json b/keyboards/keebio/viterbi/rev1/info.json index 01ec06bc512c..19dba2798407 100644 --- a/keyboards/keebio/viterbi/rev1/info.json +++ b/keyboards/keebio/viterbi/rev1/info.json @@ -7,6 +7,9 @@ "pid": "0x1157", "device_version": "1.0.0" }, + "rgblight": { + "split_count": [7, 7] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keebio/viterbi/rev2/config.h b/keyboards/keebio/viterbi/rev2/config.h index 56151a002818..0c858c616471 100644 --- a/keyboards/keebio/viterbi/rev2/config.h +++ b/keyboards/keebio/viterbi/rev2/config.h @@ -26,4 +26,3 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 14 -#define RGBLED_SPLIT { 7, 7 } diff --git a/keyboards/keebio/viterbi/rev2/info.json b/keyboards/keebio/viterbi/rev2/info.json index 10f36652ab2c..0dfbc12a173b 100644 --- a/keyboards/keebio/viterbi/rev2/info.json +++ b/keyboards/keebio/viterbi/rev2/info.json @@ -16,6 +16,9 @@ "pin": "B6", "levels": 7 }, + "rgblight": { + "split_count": [7, 7] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keycapsss/kimiko/rev1/config.h b/keyboards/keycapsss/kimiko/rev1/config.h index 27049500bc13..60d11111ace6 100644 --- a/keyboards/keycapsss/kimiko/rev1/config.h +++ b/keyboards/keycapsss/kimiko/rev1/config.h @@ -18,7 +18,6 @@ #ifdef RGBLIGHT_ENABLE # define RGBLED_NUM 60 // Total number of LEDs -# define RGBLED_SPLIT { 30, 30 } // LEDs per side # define RGBLIGHT_SPLIT #endif diff --git a/keyboards/keycapsss/kimiko/rev1/info.json b/keyboards/keycapsss/kimiko/rev1/info.json index 56028f3f81ae..c9af182427de 100644 --- a/keyboards/keycapsss/kimiko/rev1/info.json +++ b/keyboards/keycapsss/kimiko/rev1/info.json @@ -21,6 +21,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [30, 30] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/keychron/q1/iso/keymaps/victorsavu3/keymap.c b/keyboards/keychron/q1/iso/keymaps/victorsavu3/keymap.c index b97e6bfb9224..5256c97dca7b 100644 --- a/keyboards/keychron/q1/iso/keymaps/victorsavu3/keymap.c +++ b/keyboards/keychron/q1/iso/keymaps/victorsavu3/keymap.c @@ -55,8 +55,8 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS), [WIN_BASE] = LAYOUT_iso_83( - KC_ESC, 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, X(SAD), - KC_GRV, 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, X(GRIN), + KC_ESC, 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, UM(SAD), + KC_GRV, 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, UM(GRIN), 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_PGUP, QK_LEAD, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, KC_SCLN, KC_QUOT, KC_NUHS, KC_ENT, KC_PGDN, KC_LSFT, KC_NUBS, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, KC_SLSH, KC_RSFT, KC_UP, diff --git a/keyboards/kibou/harbour/info.json b/keyboards/kibou/harbour/info.json new file mode 100644 index 000000000000..ae5fe10d68d7 --- /dev/null +++ b/keyboards/kibou/harbour/info.json @@ -0,0 +1,102 @@ +{ + "manufacturer": "kibou", + "keyboard_name": "harbour", + "maintainer": "kibou", + "bootloader": "stm32-dfu", + "diode_direction": "ROW2COL", + "features": { + "bootmagic": true, + "command": false, + "console": false, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "matrix_pins": { + "cols": ["C9", "A8", "A15", "C10", "C11", "B5", "B6", "B7", "A0", "A1", "A2", "C3", "C2", "C1", "A3", "A4"], + "rows": ["C12", "D2", "B3", "B4", "C13"] + }, + "processor": "STM32F401", + "url": "https://kibou.store/", + "usb": { + "device_version": "0.0.1", + "pid": "0xA002", + "vid": "0x586A" + }, + "indicators": { + "caps_lock": "C8" + }, + "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": [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,2], "x": 1.5, "y": 1 }, + { "matrix": [1,3], "x": 2.5, "y": 1 }, + { "matrix": [1,4], "x": 3.5, "y": 1 }, + { "matrix": [1,5], "x": 4.5, "y": 1 }, + { "matrix": [1,6], "x": 5.5, "y": 1 }, + { "matrix": [1,7], "x": 6.5, "y": 1 }, + { "matrix": [1,8], "x": 7.5, "y": 1 }, + { "matrix": [1,9], "x": 8.5, "y": 1 }, + { "matrix": [1,10], "x": 9.5, "y": 1 }, + { "matrix": [1,11], "x": 10.5, "y": 1 }, + { "matrix": [1,12], "x": 11.5, "y": 1 }, + { "matrix": [1,13], "x": 12.5, "y": 1 }, + { "matrix": [1,14], "x": 13.5, "y": 1, "w": 1.5 }, + { "matrix": [1,15], "x": 15, "y": 1 }, + { "matrix": [2,0], "x": 0, "y": 2, "w": 1.75 }, + { "matrix": [2,2], "x": 1.75, "y": 2 }, + { "matrix": [2,3], "x": 2.75, "y": 2 }, + { "matrix": [2,4], "x": 3.75, "y": 2 }, + { "matrix": [2,5], "x": 4.75, "y": 2 }, + { "matrix": [2,6], "x": 5.75, "y": 2 }, + { "matrix": [2,7], "x": 6.75, "y": 2 }, + { "matrix": [2,8], "x": 7.75, "y": 2 }, + { "matrix": [2,9], "x": 8.75, "y": 2 }, + { "matrix": [2,10], "x": 9.75, "y": 2 }, + { "matrix": [2,11], "x": 10.75, "y": 2 }, + { "matrix": [2,12], "x": 11.75, "y": 2 }, + { "matrix": [2,14], "x": 12.75, "y": 2, "w": 2.25 }, + { "matrix": [2,15], "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,13], "x": 12.25, "y": 3, "w": 1.75 }, + { "matrix": [3,14], "x": 14, "y": 3 }, + { "matrix": [3,15], "x": 15, "y": 3 }, + { "matrix": [4,0], "x": 0, "y": 4, "w": 1.5 }, + { "matrix": [4,2], "x": 1.5, "y": 4 }, + { "matrix": [4,3], "x": 2.5, "y": 4, "w": 1.5 }, + { "matrix": [4,7], "x": 4, "y": 4, "w": 7 }, + { "matrix": [4,11], "x": 11, "y": 4, "w": 1.75 }, + { "matrix": [4,13], "x": 13, "y": 4 }, + { "matrix": [4,14], "x": 14, "y": 4 }, + { "matrix": [4,15], "x": 15, "y": 4 } + ] + } + } +} \ No newline at end of file diff --git a/keyboards/kibou/harbour/keymaps/default/keymap.c b/keyboards/kibou/harbour/keymaps/default/keymap.c new file mode 100644 index 000000000000..7586fc24e066 --- /dev/null +++ b/keyboards/kibou/harbour/keymaps/default/keymap.c @@ -0,0 +1,13 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, 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_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_INS, + 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_LSFT, KC_UP, KC_PGDN, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_LALT, KC_LEFT, KC_DOWN, KC_RGHT) +}; diff --git a/keyboards/kibou/harbour/keymaps/via/keymap.c b/keyboards/kibou/harbour/keymaps/via/keymap.c new file mode 100644 index 000000000000..7586fc24e066 --- /dev/null +++ b/keyboards/kibou/harbour/keymaps/via/keymap.c @@ -0,0 +1,13 @@ +// Copyright 2023 QMK +// SPDX-License-Identifier: GPL-2.0-or-later + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT( + KC_ESC, KC_1, 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_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_INS, + 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_LSFT, KC_UP, KC_PGDN, + KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_LALT, KC_LEFT, KC_DOWN, KC_RGHT) +}; diff --git a/keyboards/kibou/harbour/keymaps/via/rules.mk b/keyboards/kibou/harbour/keymaps/via/rules.mk new file mode 100644 index 000000000000..036bd6d1c3ec --- /dev/null +++ b/keyboards/kibou/harbour/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes \ No newline at end of file diff --git a/keyboards/kibou/harbour/readme.md b/keyboards/kibou/harbour/readme.md new file mode 100644 index 000000000000..f957e3179535 --- /dev/null +++ b/keyboards/kibou/harbour/readme.md @@ -0,0 +1,23 @@ +# harbour + +* Keyboard Maintainer: [kibou](https://kibou.store/) +* Hardware Supported: harbour PCBs, STM32F401 +* Hardware Availability: https://kibou.store/ + +Make example for this keyboard (after setting up your build environment): + + make kibou/harbour:default + +Flashing example for this keyboard: + + make kibou/harbour: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 diff --git a/keyboards/kibou/harbour/rules.mk b/keyboards/kibou/harbour/rules.mk new file mode 100644 index 000000000000..6e7633bfe015 --- /dev/null +++ b/keyboards/kibou/harbour/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank diff --git a/keyboards/ktec/ergodone/keymaps/vega/keymap.c b/keyboards/ktec/ergodone/keymaps/vega/keymap.c index 8e460d7b4c39..d668f9b41eaa 100644 --- a/keyboards/ktec/ergodone/keymaps/vega/keymap.c +++ b/keyboards/ktec/ergodone/keymaps/vega/keymap.c @@ -686,112 +686,112 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [MATH] = LAYOUT_ergodox( KC_ESC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_GRV, - KC_TAB, X(Mc), X(Munion), X(arwl), X(or), X(exists), KC_BSLS, - X(arwr), X(root), X(and), X(imply), X(nexists), X(forall), - SC_LSPO, KC_SCLN, X(intgrl), X(Mn), X(Mz), X(member), X(arwl), + KC_TAB, UM(Mc), UM(Munion), UM(arwl), UM(or), UM(exists), KC_BSLS, + UM(arwr), UM(root), UM(and), UM(imply), UM(nexists), UM(forall), + SC_LSPO, KC_SCLN, UM(intgrl), UM(Mn), UM(Mz), UM(member), UM(arwl), KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, TT(FNLR), KC_6, KC_7, KC_8, KC_9, KC_0, KC_BSPC, - KC_PGUP, X(plsminus), X(infin), X(neleof), X(equiv), X(Mq), KC_EQL, - X(sum), X(emtyset), X(porp), X(suprsetof), X(not), X(neq), - KC_PGDN, X(subsetof), X(intersection), X(angl), X(nmember), X(eleof), SC_RSPC, + KC_PGUP, UM(plsminus), UM(infin), UM(neleof), UM(equiv), UM(Mq), KC_EQL, + UM(sum), UM(emtyset), UM(porp), UM(suprsetof), UM(not), UM(neq), + KC_PGDN, UM(subsetof), UM(intersection), UM(angl), UM(nmember), UM(eleof), SC_RSPC, KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), [SYMB] = LAYOUT_ergodox( - X(Os), X(Oa), X(Ob), X(Oc), X(Od), X(Oe), X(mdot), - X(boxemp), X(bbstr), X(bbrtr), X(bbrtl), X(bbstl), X(degree), X(brkdn), - X(boxchk), X(bbmbl), X(bbml), X(bbmr), X(bbmbr), X(neteen), - X(boxX), X(bbsbr), X(bbrbr), X(bbrbl), X(bbsbl), X(uxclm), X(brkup), - X(floppy), TO(BASE), TO(BASE), X(arwu), X(arwd), - X(fire), X(lshade), X(mshade), KC_SPC, X(OS), X(dshade), - - X(Ox), X(Of), X(Og), X(Oh), X(Oi), X(OA), X(OB), - X(numero), X(trade), X(copy), X(cleft), X(cent), X(OED), X(OC), - X(Agrave), X(gnd), X(sqr), X(sine), X(opt), X(OD), - X(sect), X(Aacute), X(Acircm), X(Adiaer), X(Abreve), X(Atilde), X(OE), - X(arwl), X(arwr), X(geq), X(leq), X(OF), - X(rang), X(water), X(perup), X(perdn), X(baster), KC_ENT + UM(Os), UM(Oa), UM(Ob), UM(Oc), UM(Od), UM(Oe), UM(mdot), + UM(boxemp), UM(bbstr), UM(bbrtr), UM(bbrtl), UM(bbstl), UM(degree), UM(brkdn), + UM(boxchk), UM(bbmbl), UM(bbml), UM(bbmr), UM(bbmbr), UM(neteen), + UM(boxX), UM(bbsbr), UM(bbrbr), UM(bbrbl), UM(bbsbl), UM(uxclm), UM(brkup), + UM(floppy), TO(BASE), TO(BASE), UM(arwu), UM(arwd), + UM(fire), UM(lshade), UM(mshade), KC_SPC, UM(OS), UM(dshade), + + UM(Ox), UM(Of), UM(Og), UM(Oh), UM(Oi), UM(OA), UM(OB), + UM(numero), UM(trade), UM(copy), UM(cleft), UM(cent), UM(OED), UM(OC), + UM(Agrave), UM(gnd), UM(sqr), UM(sine), UM(opt), UM(OD), + UM(sect), UM(Aacute), UM(Acircm), UM(Adiaer), UM(Abreve), UM(Atilde), UM(OE), + UM(arwl), UM(arwr), UM(geq), UM(leq), UM(OF), + UM(rang), UM(water), UM(perup), UM(perdn), UM(baster), KC_ENT ), [GREL] = LAYOUT_ergodox( - KC_ESC, X(Rone), X(Rtwo), X(Rthree), X(Rfour), X(Rfive), KC_GRV, - KC_TAB, KC_QUOT, KC_COMM, KC_DOT, X(gp), X(gy), KC_SLSH, - KC_SLSH, X(ga), X(go), X(ge), X(gu), X(gi), - MO(GREU), KC_SCLN, X(gq), X(gj), X(gk), X(gx), KC_AMPR, + KC_ESC, UM(Rone), UM(Rtwo), UM(Rthree), UM(Rfour), UM(Rfive), KC_GRV, + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, UM(gp), UM(gy), KC_SLSH, + KC_SLSH, UM(ga), UM(go), UM(ge), UM(gu), UM(gi), + MO(GREU), KC_SCLN, UM(gq), UM(gj), UM(gk), UM(gx), KC_AMPR, KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, - TO(BASE), X(Rsix), X(Rseven), X(Reight), X(Rnine), X(Rten), KC_BSPC, - KC_PGUP, X(gf), X(gg), X(gc), X(gr), X(gl), KC_EQL, - X(gd), X(gh), X(gt), X(gn), X(gs), KC_MINS, - KC_PGDN, X(gb), X(gm), X(gw), X(gv), X(gz), MO(GREU), + TO(BASE), UM(Rsix), UM(Rseven), UM(Reight), UM(Rnine), UM(Rten), KC_BSPC, + KC_PGUP, UM(gf), UM(gg), UM(gc), UM(gr), UM(gl), KC_EQL, + UM(gd), UM(gh), UM(gt), UM(gn), UM(gs), KC_MINS, + KC_PGDN, UM(gb), UM(gm), UM(gw), UM(gv), UM(gz), MO(GREU), KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), [GREU] = LAYOUT_ergodox( - KC_ESC, X(Rone), X(Rtwo), X(Rthree), X(Rfour), X(Rfive), KC_GRV, - KC_TAB, KC_QUOT, KC_COMM, KC_DOT, X(Gp), X(Gy), KC_SLSH, - KC_SLSH, X(Ga), X(Go), X(Ge), X(Gu), X(Gi), - KC_TRNS, KC_SCLN, X(Gq), X(Gj), X(Gk), X(Gx), KC_AMPR, + KC_ESC, UM(Rone), UM(Rtwo), UM(Rthree), UM(Rfour), UM(Rfive), KC_GRV, + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, UM(Gp), UM(Gy), KC_SLSH, + KC_SLSH, UM(Ga), UM(Go), UM(Ge), UM(Gu), UM(Gi), + KC_TRNS, KC_SCLN, UM(Gq), UM(Gj), UM(Gk), UM(Gx), KC_AMPR, KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, - TO(BASE), X(Rsix), X(Rseven), X(Reight), X(Rnine), X(Rten), KC_BSPC, - KC_PGUP, X(Gf), X(Gg), X(Gc), X(Gr), X(Gl), KC_EQL, - X(Gd), X(Gh), X(Gt), X(Gn), X(Gs), KC_MINS, - KC_PGDN, X(Gb), X(Gm), X(Gw), X(Gv), X(Gz), KC_TRNS, + TO(BASE), UM(Rsix), UM(Rseven), UM(Reight), UM(Rnine), UM(Rten), KC_BSPC, + KC_PGUP, UM(Gf), UM(Gg), UM(Gc), UM(Gr), UM(Gl), KC_EQL, + UM(Gd), UM(Gh), UM(Gt), UM(Gn), UM(Gs), KC_MINS, + KC_PGDN, UM(Gb), UM(Gm), UM(Gw), UM(Gv), UM(Gz), KC_TRNS, KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), [TINY] = LAYOUT_ergodox( - KC_ESC, X(tone), X(ttwo), X(tthree), X(tfour), X(tfive), KC_GRV, - KC_TAB, KC_QUOT, KC_COMM, KC_DOT, X(tp), X(ty), KC_SLSH, - KC_SLSH, X(ta), X(to), X(te), X(tu), X(ti), - KC_TRNS, KC_SCLN, X(tq), X(tj), X(tk), X(tx), KC_AMPR, + KC_ESC, UM(tone), UM(ttwo), UM(tthree), UM(tfour), UM(tfive), KC_GRV, + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, UM(tp), UM(ty), KC_SLSH, + KC_SLSH, UM(ta), UM(to), UM(te), UM(tu), UM(ti), + KC_TRNS, KC_SCLN, UM(tq), UM(tj), UM(tk), UM(tx), KC_AMPR, KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, - TO(BASE), X(tsix), X(tseven), X(teight), X(tnine), X(tzero), KC_BSPC, - KC_PGUP, X(tf), X(tg), X(tc), X(tr), X(tl), KC_EQL, - X(td), X(th), X(tt), X(tn), X(ts), KC_MINS, - KC_PGDN, X(tb), X(tm), X(tw), X(tv), X(tz), KC_TRNS, + TO(BASE), UM(tsix), UM(tseven), UM(teight), UM(tnine), UM(tzero), KC_BSPC, + KC_PGUP, UM(tf), UM(tg), UM(tc), UM(tr), UM(tl), KC_EQL, + UM(td), UM(th), UM(tt), UM(tn), UM(ts), KC_MINS, + KC_PGDN, UM(tb), UM(tm), UM(tw), UM(tv), UM(tz), KC_TRNS, KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), [FULL] = LAYOUT_ergodox( - KC_ESC, X(fwone), X(fwtwo), X(fwthree), X(fwfour), X(fwfive), KC_GRV, - KC_TAB, KC_QUOT, KC_COMM, KC_DOT, X(fwp), X(fwy), KC_SLSH, - KC_SLSH, X(fwa), X(fwo), X(fwe), X(fwu), X(fwi), - MO(FULU), KC_SCLN, X(fwq), X(fwj), X(fwk), X(fwx), KC_AMPR, + KC_ESC, UM(fwone), UM(fwtwo), UM(fwthree), UM(fwfour), UM(fwfive), KC_GRV, + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, UM(fwp), UM(fwy), KC_SLSH, + KC_SLSH, UM(fwa), UM(fwo), UM(fwe), UM(fwu), UM(fwi), + MO(FULU), KC_SCLN, UM(fwq), UM(fwj), UM(fwk), UM(fwx), KC_AMPR, KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, - TO(BASE), X(fwsix), X(fwseven), X(fweight), X(fwnine), X(fwzero), KC_BSPC, - KC_PGUP, X(fwf), X(fwg), X(fwc), X(fwr), X(fwl), KC_EQL, - X(fwd), X(fwh), X(fwt), X(fwn), X(fws), KC_MINS, - KC_PGDN, X(fwb), X(fwm), X(fww), X(fwv), X(fwz), MO(FULU), + TO(BASE), UM(fwsix), UM(fwseven), UM(fweight), UM(fwnine), UM(fwzero), KC_BSPC, + KC_PGUP, UM(fwf), UM(fwg), UM(fwc), UM(fwr), UM(fwl), KC_EQL, + UM(fwd), UM(fwh), UM(fwt), UM(fwn), UM(fws), KC_MINS, + KC_PGDN, UM(fwb), UM(fwm), UM(fww), UM(fwv), UM(fwz), MO(FULU), KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), [FULU] = LAYOUT_ergodox( - KC_ESC, X(Fwone), X(Fwtwo), X(Fwthree), X(Fwfour), X(Fwfive), KC_GRV, - KC_TAB, KC_QUOT, KC_COMM, KC_DOT, X(Fwp), X(Fwy), KC_SLSH, - KC_SLSH, X(Fwa), X(Fwo), X(Fwe), X(Fwu), X(Fwi), - KC_TRNS, KC_SCLN, X(Fwq), X(Fwj), X(Fwk), X(Fwx), KC_AMPR, + KC_ESC, UM(Fwone), UM(Fwtwo), UM(Fwthree), UM(Fwfour), UM(Fwfive), KC_GRV, + KC_TAB, KC_QUOT, KC_COMM, KC_DOT, UM(Fwp), UM(Fwy), KC_SLSH, + KC_SLSH, UM(Fwa), UM(Fwo), UM(Fwe), UM(Fwu), UM(Fwi), + KC_TRNS, KC_SCLN, UM(Fwq), UM(Fwj), UM(Fwk), UM(Fwx), KC_AMPR, KC_MS_L, TO(BASE), TO(BASE), KC_INS, KC_DEL, KC_LBRC, KC_HOME, KC_UP, KC_SPC, KC_LGUI, KC_DOWN, - TO(BASE), X(Fwsix), X(Fwseven), X(Fweight), X(Fwnine), X(Fwzero), KC_BSPC, - KC_PGUP, X(Fwf), X(Fwg), X(Fwc), X(Fwr), X(Fwl), KC_EQL, - X(Fwd), X(Fwh), X(Fwt), X(Fwn), X(Fws), KC_MINS, - KC_PGDN, X(Fwb), X(Fwm), X(Fww), X(Fwv), X(Fwz), KC_TRNS, + TO(BASE), UM(Fwsix), UM(Fwseven), UM(Fweight), UM(Fwnine), UM(Fwzero), KC_BSPC, + KC_PGUP, UM(Fwf), UM(Fwg), UM(Fwc), UM(Fwr), UM(Fwl), KC_EQL, + UM(Fwd), UM(Fwh), UM(Fwt), UM(Fwn), UM(Fws), KC_MINS, + KC_PGDN, UM(Fwb), UM(Fwm), UM(Fww), UM(Fwv), UM(Fwz), KC_TRNS, KC_RCTL, KC_RALT, KC_APP, TO(BASE), TO(BASE), KC_END, KC_RBRC, KC_LEFT, KC_RGHT, KC_ENT, KC_SPC ), diff --git a/keyboards/lily58/glow_enc/config.h b/keyboards/lily58/glow_enc/config.h index cf58b0fe4573..6c1cad1103a9 100644 --- a/keyboards/lily58/glow_enc/config.h +++ b/keyboards/lily58/glow_enc/config.h @@ -22,5 +22,4 @@ along with this program. If not, see . #define RGBLED_NUM 72 // Number of LEDs -#define RGBLED_SPLIT { 36, 36 } #define RGBLIGHT_SPLIT diff --git a/keyboards/lily58/glow_enc/info.json b/keyboards/lily58/glow_enc/info.json index 79358416f590..2b3e2700266b 100644 --- a/keyboards/lily58/glow_enc/info.json +++ b/keyboards/lily58/glow_enc/info.json @@ -38,7 +38,8 @@ "pin": "F4" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [36, 36] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/lily58/light/config.h b/keyboards/lily58/light/config.h index 88cb95c24387..1080139430aa 100644 --- a/keyboards/lily58/light/config.h +++ b/keyboards/lily58/light/config.h @@ -20,6 +20,5 @@ along with this program. If not, see . #pragma once -#define RGBLED_SPLIT { 35, 35 } #define RGBLED_NUM 70 #define RGBLIGHT_SPLIT diff --git a/keyboards/lily58/light/info.json b/keyboards/lily58/light/info.json index 7cca1288a392..ca3ad342fb6c 100644 --- a/keyboards/lily58/light/info.json +++ b/keyboards/lily58/light/info.json @@ -39,7 +39,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [35, 35] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/manta60/config.h b/keyboards/manta60/config.h index 918edbdbb048..dbda0b7fed7e 100644 --- a/keyboards/manta60/config.h +++ b/keyboards/manta60/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . # define RGBLED_NUM 68 # define RGBLIGHT_SPLIT -# define RGBLED_SPLIT { 34, 34 } # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # ifndef IOS_DEVICE_ENABLE diff --git a/keyboards/manta60/info.json b/keyboards/manta60/info.json index ba48f72ad233..3f75de7ddfb9 100644 --- a/keyboards/manta60/info.json +++ b/keyboards/manta60/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [34, 34] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/maple_computing/lets_split_eh/eh/config.h b/keyboards/maple_computing/lets_split_eh/eh/config.h index c64be02975a8..27de26f6b8ee 100644 --- a/keyboards/maple_computing/lets_split_eh/eh/config.h +++ b/keyboards/maple_computing/lets_split_eh/eh/config.h @@ -20,7 +20,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLED_NUM 12 // Number of LEDs (each hand) -#define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/maple_computing/lets_split_eh/eh/info.json b/keyboards/maple_computing/lets_split_eh/eh/info.json index 1908f56eeb1c..f14888862f0c 100644 --- a/keyboards/maple_computing/lets_split_eh/eh/info.json +++ b/keyboards/maple_computing/lets_split_eh/eh/info.json @@ -16,6 +16,9 @@ "backlight": { "pin": "B7" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "B2" }, diff --git a/keyboards/marksard/rhymestone/rev1/config.h b/keyboards/marksard/rhymestone/rev1/config.h index d3250461b2d9..b313d95e2b99 100644 --- a/keyboards/marksard/rhymestone/rev1/config.h +++ b/keyboards/marksard/rhymestone/rev1/config.h @@ -19,7 +19,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE #define RGBLED_NUM 40 - #define RGBLED_SPLIT {20, 20} #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/marksard/rhymestone/rev1/info.json b/keyboards/marksard/rhymestone/rev1/info.json index fc4ee548d168..35d4afdca19c 100644 --- a/keyboards/marksard/rhymestone/rev1/info.json +++ b/keyboards/marksard/rhymestone/rev1/info.json @@ -23,7 +23,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 150 + "max_brightness": 150, + "split_count": [20, 20] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/massdrop/alt/keymaps/charlesrocket/keymap.c b/keyboards/massdrop/alt/keymaps/charlesrocket/keymap.c index edd906deb513..8df4376806b8 100644 --- a/keyboards/massdrop/alt/keymaps/charlesrocket/keymap.c +++ b/keyboards/massdrop/alt/keymaps/charlesrocket/keymap.c @@ -65,10 +65,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { _______, LAG_SWP, LAG_NRM, _______, _______, TG(3), _______, _______, _______ ), [3] = LAYOUT( - XP(0,1), XP(2,3), XP(4,5), XP(6,7), XP(8,9), XP(10,11), XP(12,13), XP(14,15), XP(16,17), XP(18,19), XP(20,21), XP(22,23), XP(24,25), _______, _______, - _______, KC_QUES, XP(27,28), XP(29,31), X(32), XP(33,34), X(35), X(36), XP(37,38), XP(39,40), XP(41,42), XP(43,44), XP(45,46), _______, _______, - _______, XP(47,48), X(49), X(50), KC_UNDS, XP(52,5), XP(53,54), XP(55,56), KC_QUOT, XP(59,60), XP(61,62), XP(63,64), _______, _______, - _______, XP(65,66), X(67), XP(68,69), X(70), X(71), X(72), X(73), KC_PIPE, XP(75,76), X(77), XP(78,79), _______, _______, + UP(0,1), UP(2,3), UP(4,5), UP(6,7), UP(8,9), UP(10,11), UP(12,13), UP(14,15), UP(16,17), UP(18,19), UP(20,21), UP(22,23), UP(24,25), _______, _______, + _______, KC_QUES, UP(27,28), UP(29,31), UM(32), UP(33,34), UM(35), UM(36), UP(37,38), UP(39,40), UP(41,42), UP(43,44), UP(45,46), _______, _______, + _______, UP(47,48), UM(49), UM(50), KC_UNDS, UP(52,5), UP(53,54), UP(55,56), KC_QUOT, UP(59,60), UP(61,62), UP(63,64), _______, _______, + _______, UP(65,66), UM(67), UP(68,69), UM(70), UM(71), UM(72), UM(73), KC_PIPE, UP(75,76), UM(77), UP(78,79), _______, _______, _______, _______, _______, _______, _______, TG(3), _______, _______, _______ ), }; diff --git a/keyboards/mechlovin/zed65/info.json b/keyboards/mechlovin/zed65/info.json index cf993be24710..c255dd23c6e0 100644 --- a/keyboards/mechlovin/zed65/info.json +++ b/keyboards/mechlovin/zed65/info.json @@ -1,4 +1,11 @@ { "processor": "STM32F103", - "bootloader": "stm32duino" + "bootloader": "stm32duino", + "features": { + "bootmagic": true, + "command": true, + "console": true, + "extrakey": true, + "mousekey": true + }, } diff --git a/quantum/logging/sendchar.h b/keyboards/mechlovin/zed65/rev1/config.h similarity index 69% rename from quantum/logging/sendchar.h rename to keyboards/mechlovin/zed65/rev1/config.h index edcddaa6bb97..24efedfffba6 100644 --- a/quantum/logging/sendchar.h +++ b/keyboards/mechlovin/zed65/rev1/config.h @@ -1,5 +1,5 @@ /* -Copyright 2011 Jun Wako +Copyright 2022 Mechlovin' 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 @@ -17,17 +17,8 @@ along with this program. If not, see . #pragma once -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef int8_t (*sendchar_func_t)(uint8_t c); - -/* transmit a character. return 0 on success, -1 on error. */ -int8_t sendchar(uint8_t c); - -#ifdef __cplusplus -} +#ifdef RGBLIGHT_ENABLE +#define WS2812_SPI SPID1 // default: SPID1 +#define WS2812_SPI_MOSI_PAL_MODE 6 // MOSI pin "alternate function", see the respective datasheet for the appropriate values for your MCU. default: 5 +#define WS2812_SPI_USE_CIRCULAR_BUFFER #endif diff --git a/quantum/process_keycode/process_magic.h b/keyboards/mechlovin/zed65/rev1/halconf.h similarity index 87% rename from quantum/process_keycode/process_magic.h rename to keyboards/mechlovin/zed65/rev1/halconf.h index 1eb39f14557c..ccf744728563 100644 --- a/quantum/process_keycode/process_magic.h +++ b/keyboards/mechlovin/zed65/rev1/halconf.h @@ -1,4 +1,4 @@ -/* Copyright 2019 +/* Copyright 2022 QMK * * 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 @@ -13,8 +13,10 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ + #pragma once -#include "quantum.h" +#define HAL_USE_SPI TRUE + +#include_next -bool process_magic(uint16_t keycode, keyrecord_t *record); diff --git a/keyboards/mechlovin/zed65/rev1/info.json b/keyboards/mechlovin/zed65/rev1/info.json new file mode 100644 index 000000000000..869564c6716c --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/info.json @@ -0,0 +1,354 @@ +{ + "manufacturer": "Mechlovin Studio", + "url": "https://mechlovin.studio/", + "maintainer": "mechlovin", + "keyboard_name": "Zed65 Rev1", + "usb": { + "vid": "0x4D4C", + "pid": "0x6505", + "device_version": "0.0.1" + }, + "features": { + "nkro": true, + "rgblight": true + }, + "matrix_pins": { + "rows": ["B12", "B13", "B14", "B15", "A1"], + "cols": ["B11", "B10", "B2", "B1", "B0", "A6", "A5", "A4", "A3", "C13", "B7", "B6", "B5", "B4", "B3"] + }, + "indicators": { + "caps_lock": "B9", + "on_state": 0 + }, + "diode_direction": "COL2ROW", + "rgblight": { + "led_count": 24, + "sleep": true, + "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 + } + }, + "ws2812": { + "pin": "A7", + "driver": "spi" + }, + "community_layouts": ["65_ansi_blocker_tsangan"], + "layouts": { + "LAYOUT_65_iso_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": [2, 12], "x": 14, "y": 0}, + {"matrix": [0, 14], "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": [2, 13], "x": 13.75, "y": 1, "w": 1.25, "h": 2}, + {"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": [1, 13], "x": 12.75, "y": 2}, + {"matrix": [2, 14], "x": 15, "y": 2}, + + {"matrix": [3, 0], "x": 0, "y": 3, "w": 1.25}, + {"matrix": [3, 1], "x": 1.25, "y": 3}, + {"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.25}, + {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25}, + {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25}, + {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25}, + {"matrix": [4, 9], "x": 10, "y": 4}, + {"matrix": [4, 10], "x": 11, "y": 4}, + {"matrix": [4, 11], "x": 12, "y": 4}, + {"matrix": [4, 12], "x": 13, "y": 4}, + {"matrix": [4, 13], "x": 14, "y": 4}, + {"matrix": [4, 14], "x": 15, "y": 4} + ] + }, + "LAYOUT_65_ansi_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": [2, 12], "x": 14, "y": 0}, + {"matrix": [0, 14], "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": 1.25}, + {"matrix": [3, 1], "x": 1.25, "y": 3}, + {"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.25}, + {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25}, + {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25}, + {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25}, + {"matrix": [4, 9], "x": 10, "y": 4}, + {"matrix": [4, 10], "x": 11, "y": 4}, + {"matrix": [4, 11], "x": 12, "y": 4}, + {"matrix": [4, 12], "x": 13, "y": 4}, + {"matrix": [4, 13], "x": 14, "y": 4}, + {"matrix": [4, 14], "x": 15, "y": 4} + ] + }, + "LAYOUT_65_ansi_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, 14], "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.25}, + {"matrix": [4, 1], "x": 1.25, "y": 4, "w": 1.25}, + {"matrix": [4, 2], "x": 2.5, "y": 4, "w": 1.25}, + {"matrix": [4, 6], "x": 3.75, "y": 4, "w": 6.25}, + {"matrix": [4, 9], "x": 10, "y": 4}, + {"matrix": [4, 10], "x": 11, "y": 4}, + {"matrix": [4, 11], "x": 12, "y": 4}, + {"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, 14], "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, 10], "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} + ] + } + } +} diff --git a/keyboards/mechlovin/zed65/rev1/keymaps/default/keymap.c b/keyboards/mechlovin/zed65/rev1/keymaps/default/keymap.c new file mode 100644 index 000000000000..7a922d6b850c --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/keymaps/default/keymap.c @@ -0,0 +1,28 @@ +/* +Copyright 2023 Mechlovin' + +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 . +*/ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_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_DEL, 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_NUBS, 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, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ) +}; \ No newline at end of file diff --git a/keyboards/mechlovin/zed65/rev1/keymaps/via/keymap.c b/keyboards/mechlovin/zed65/rev1/keymaps/via/keymap.c new file mode 100644 index 000000000000..333f14ec70ef --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/keymaps/via/keymap.c @@ -0,0 +1,29 @@ +/* +Copyright 2023 Mechlovin' + +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 . +*/ + +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_65_ansi_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_DEL, 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_NUBS, 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, KC_RALT, KC_RGUI, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT + ) +}; + diff --git a/keyboards/mechlovin/zed65/rev1/keymaps/via/rules.mk b/keyboards/mechlovin/zed65/rev1/keymaps/via/rules.mk new file mode 100644 index 000000000000..36b7ba9cbc98 --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/keymaps/via/rules.mk @@ -0,0 +1,2 @@ +VIA_ENABLE = yes +LTO_ENABLE = yes diff --git a/quantum/unicode/utf8.h b/keyboards/mechlovin/zed65/rev1/mcuconf.h similarity index 86% rename from quantum/unicode/utf8.h rename to keyboards/mechlovin/zed65/rev1/mcuconf.h index 521dd1918c36..0a9c3ca2c5ae 100644 --- a/quantum/unicode/utf8.h +++ b/keyboards/mechlovin/zed65/rev1/mcuconf.h @@ -1,4 +1,4 @@ -/* Copyright 2021 QMK +/* Copyright 2022 QMK * * 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 @@ -16,6 +16,8 @@ #pragma once -#include +#include_next -const char *decode_utf8(const char *str, int32_t *code_point); + +#undef STM32_SPI_USE_SPI1 +#define STM32_SPI_USE_SPI1 TRUE diff --git a/keyboards/mechlovin/zed65/rev1/readme.md b/keyboards/mechlovin/zed65/rev1/readme.md new file mode 100644 index 000000000000..ca4d2b796e7c --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/readme.md @@ -0,0 +1,28 @@ +# zed65 + +![Zed65](https://i.imgur.com/IbsSLb6h.jpeg) + +A 65% PCB with centered USB and JST-SH support, using APM32F103. + +* Keyboard Maintainer: [Mechlovin](https://github.com/mechlovin) +* Hardware Supported: Ori, No2//65, Iron165... +* Hardware Availability: [Mechlovin' Studio](https://mechlovin.studio/) + +Make example for this keyboard (after setting up your build environment): + + make mechlovin/zed65/rev1 + +Flashing example for this keyboard: + + make mechlovin/zed65/rev1: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 4 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 +* **Bootloader reset**: Hold down the key at (0,13) in the matrix (usually the Back Space) 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 diff --git a/keyboards/mechlovin/zed65/rev1/rules.mk b/keyboards/mechlovin/zed65/rev1/rules.mk new file mode 100644 index 000000000000..7ff128fa692e --- /dev/null +++ b/keyboards/mechlovin/zed65/rev1/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank \ No newline at end of file diff --git a/keyboards/mechlovin/zed65/rules.mk b/keyboards/mechlovin/zed65/rules.mk index 8e2643d31fc1..a699765498bb 100644 --- a/keyboards/mechlovin/zed65/rules.mk +++ b/keyboards/mechlovin/zed65/rules.mk @@ -1,13 +1 @@ -# Build Options -# change yes to no to disable -# -BOOTMAGIC_ENABLE = yes # Enable Bootmagic Lite -MOUSEKEY_ENABLE = yes # Mouse keys -EXTRAKEY_ENABLE = yes # Audio control and System control -CONSOLE_ENABLE = yes # Console for debug -COMMAND_ENABLE = yes # Commands for debug and configuration -NKRO_ENABLE = no # Enable N-Key Rollover -RGBLIGHT_ENABLE = no # Enable keyboard RGB underglow -AUDIO_ENABLE = no # Audio output - DEFAULT_FOLDER = mechlovin/zed65/no_backlight/wearhaus66 diff --git a/keyboards/mechwild/mokulua/mirrored/config.h b/keyboards/mechwild/mokulua/mirrored/config.h index c8381bc63614..29100a303fa4 100644 --- a/keyboards/mechwild/mokulua/mirrored/config.h +++ b/keyboards/mechwild/mokulua/mirrored/config.h @@ -10,7 +10,6 @@ #define MASTER_LEFT //#define MASTER_RIGHT #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 8, 8 } #define SPLIT_LAYER_STATE_ENABLE #define SPLIT_LED_STATE_ENABLE #define SPLIT_MODS_ENABLE diff --git a/keyboards/mechwild/mokulua/mirrored/info.json b/keyboards/mechwild/mokulua/mirrored/info.json index 5401c8898f23..4bba231daf7b 100644 --- a/keyboards/mechwild/mokulua/mirrored/info.json +++ b/keyboards/mechwild/mokulua/mirrored/info.json @@ -21,6 +21,9 @@ "split": { "soft_serial_pin": "D3" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "B6" }, diff --git a/keyboards/mechwild/mokulua/standard/config.h b/keyboards/mechwild/mokulua/standard/config.h index 7f902d0ca47f..14afeae3421a 100644 --- a/keyboards/mechwild/mokulua/standard/config.h +++ b/keyboards/mechwild/mokulua/standard/config.h @@ -10,7 +10,6 @@ #define MASTER_LEFT //#define MASTER_RIGHT #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 8, 8 } #define SPLIT_LAYER_STATE_ENABLE #define SPLIT_LED_STATE_ENABLE #define SPLIT_MODS_ENABLE diff --git a/keyboards/mechwild/mokulua/standard/info.json b/keyboards/mechwild/mokulua/standard/info.json index 4ab38d9d370f..b6dbf6186be7 100644 --- a/keyboards/mechwild/mokulua/standard/info.json +++ b/keyboards/mechwild/mokulua/standard/info.json @@ -21,6 +21,9 @@ "split": { "soft_serial_pin": "D3" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "B6" }, diff --git a/keyboards/merge/um70/config.h b/keyboards/merge/um70/config.h index bbc2f5b5fbbd..1e13c06ed3e7 100644 --- a/keyboards/merge/um70/config.h +++ b/keyboards/merge/um70/config.h @@ -22,10 +22,9 @@ #define RGBLIGHT_SPLIT #define RGBLED_NUM 83 -#define RGBLED_SPLIT { 39, 44 } #ifdef RGB_MATRIX_ENABLE # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 39, 44 } #endif #define RGBLIGHT_SLEEP diff --git a/keyboards/merge/um70/info.json b/keyboards/merge/um70/info.json index 84f44ba6d141..bc9d0683f253 100644 --- a/keyboards/merge/um70/info.json +++ b/keyboards/merge/um70/info.json @@ -25,7 +25,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 150 + "max_brightness": 150, + "split_count": [39, 44] }, "processor": "atmega32u4", "bootloader": "atmel-dfu", diff --git a/keyboards/merge/um80/config.h b/keyboards/merge/um80/config.h index 84b23cd33b76..c1fe7248799e 100644 --- a/keyboards/merge/um80/config.h +++ b/keyboards/merge/um80/config.h @@ -22,10 +22,9 @@ #define RGBLIGHT_SPLIT #define RGBLED_NUM 100 -#define RGBLED_SPLIT { 48, 52 } #ifdef RGB_MATRIX_ENABLE # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 48, 52 } #endif #define RGBLIGHT_SLEEP diff --git a/keyboards/merge/um80/info.json b/keyboards/merge/um80/info.json index 2223b3d4c045..d91a4d93bac2 100644 --- a/keyboards/merge/um80/info.json +++ b/keyboards/merge/um80/info.json @@ -25,7 +25,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [48, 52] }, "processor": "atmega32u4", "bootloader": "atmel-dfu", diff --git a/keyboards/meson/config.h b/keyboards/meson/config.h index e89409d47742..ff11830e6d23 100644 --- a/keyboards/meson/config.h +++ b/keyboards/meson/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . #define RGBLED_NUM 10 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 5, 5 } #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/meson/info.json b/keyboards/meson/info.json index 62aa154c0b4a..3346458e7cbf 100644 --- a/keyboards/meson/info.json +++ b/keyboards/meson/info.json @@ -15,6 +15,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [5, 5] + }, "ws2812": { "pin": "B5" }, diff --git a/keyboards/mlego/m60_split/rev1/config.h b/keyboards/mlego/m60_split/rev1/config.h index f6f86beed1cd..06da0e11dfb0 100644 --- a/keyboards/mlego/m60_split/rev1/config.h +++ b/keyboards/mlego/m60_split/rev1/config.h @@ -30,8 +30,6 @@ #define RGBLIGHT_DEFAULT_HUE 213 #define RGBLED_NUM 16 -#define RGBLED_SPLIT \ - { 8, 8 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/mlego/m60_split/rev1/info.json b/keyboards/mlego/m60_split/rev1/info.json index 6fe572fcf1a4..8d236baac168 100644 --- a/keyboards/mlego/m60_split/rev1/info.json +++ b/keyboards/mlego/m60_split/rev1/info.json @@ -22,7 +22,8 @@ "pin": "B15" }, "rgblight": { - "max_brightness": 128 + "max_brightness": 128, + "split_count": [8, 8] }, "split": { "bootmagic": { diff --git a/keyboards/mlego/m60_split/rev2/config.h b/keyboards/mlego/m60_split/rev2/config.h index cfcb26edc104..061bc5c460dd 100644 --- a/keyboards/mlego/m60_split/rev2/config.h +++ b/keyboards/mlego/m60_split/rev2/config.h @@ -29,8 +29,6 @@ #define RGBLIGHT_SPLIT #define RGBLIGHT_LAYERS #define RGBLED_NUM 16 -#define RGBLED_SPLIT \ - { 8, 8 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/mlego/m60_split/rev2/info.json b/keyboards/mlego/m60_split/rev2/info.json index 40718aa64795..f0e64efb0bea 100644 --- a/keyboards/mlego/m60_split/rev2/info.json +++ b/keyboards/mlego/m60_split/rev2/info.json @@ -18,6 +18,9 @@ "num_lock": "B12", "scroll_lock": "B13" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "B15" }, diff --git a/keyboards/mlego/m65/keymaps/uk/keymap.c b/keyboards/mlego/m65/keymaps/uk/keymap.c index 8a711234b52c..ee4887243316 100644 --- a/keyboards/mlego/m65/keymaps/uk/keymap.c +++ b/keyboards/mlego/m65/keymaps/uk/keymap.c @@ -190,9 +190,9 @@ MS - mouse directions */ [_LWR] = LAYOUT_ortho_5x13( KC_GRV , KC_MUTE, KC_VOLU, KC_VOLD, KC_MPRV, KC_MPLY, KC_MNXT, G(KC_P), KC_SLEP, KC_WAKE, KC_PSCR, KC_DEL, UK_EQL, - KC_BTN3,XP(lq,lQ),XP(lw,lW),XP(le,lE),XP(lr,lR),XP(lt,lT),XP(ly,lY),XP(lu,lU),XP(li,lI), XP(lo,lO), XP(lp,lP), _______, _______, - KC_BTN2,XP(la,lA),XP(ls,lS),XP(ld,lD),XP(lf,lF),XP(lg,lG),XP(lh,lH),XP(lj,lJ),XP(lk,lK), XP(ll,lL),XP(ll1,lL1), XP(lk1,lK1), _______, - _______, KC_BTN1,XP(lz,lZ),XP(lx,lX),XP(lc,lC),XP(lv,lV),XP(lb,lB),XP(ln,lN),XP(lm,lM),XP(lc1,lC1),XP(lp1,lP1), KC_MS_U, XP(lq1,lQ1), + KC_BTN3,UP(lq,lQ),UP(lw,lW),UP(le,lE),UP(lr,lR),UP(lt,lT),UP(ly,lY),UP(lu,lU),UP(li,lI), UP(lo,lO), UP(lp,lP), _______, _______, + KC_BTN2,UP(la,lA),UP(ls,lS),UP(ld,lD),UP(lf,lF),UP(lg,lG),UP(lh,lH),UP(lj,lJ),UP(lk,lK), UP(ll,lL),UP(ll1,lL1), UP(lk1,lK1), _______, + _______, KC_BTN1,UP(lz,lZ),UP(lx,lX),UP(lc,lC),UP(lv,lV),UP(lb,lB),UP(ln,lN),UP(lm,lM),UP(lc1,lC1),UP(lp1,lP1), KC_MS_U, UP(lq1,lQ1), _______, KC_BTN4, _______, _______, _______, _______, _______, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R), /* @@ -224,9 +224,9 @@ raise layer shifted */ [_RSE] = LAYOUT_ortho_5x13( KC_ESC , KC_F1 , KC_F2 , KC_F3 , KC_F4 , KC_F5 , KC_F6 , KC_F7 , KC_F8 , KC_F9 , KC_F10 , KC_F11 , KC_F12 , - _______,XP(ra1,rA1), _______, _______, _______,XP(rt,rT), _______, _______,XP(ri,rI), _______, _______, _______, _______ , - KC_CAPS, XP(ra,rA), XP(rs,rS), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ , - _______, KC_F20 , _______, _______,XP(rc,rC), _______, _______, _______, _______, _______, _______, KC_WH_U, _______ , + _______,UP(ra1,rA1), _______, _______, _______,UP(rt,rT), _______, _______,UP(ri,rI), _______, _______, _______, _______ , + KC_CAPS, UP(ra,rA), UP(rs,rS), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ , + _______, KC_F20 , _______, _______,UP(rc,rC), _______, _______, _______, _______, _______, _______, KC_WH_U, _______ , _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_WH_L, KC_WH_D, KC_WH_R), /* adj layer diff --git a/keyboards/momoka_ergo/config.h b/keyboards/momoka_ergo/config.h index 014b1f93a5f2..9f4cc586e4c6 100644 --- a/keyboards/momoka_ergo/config.h +++ b/keyboards/momoka_ergo/config.h @@ -26,7 +26,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_RAINBOW_SWIRL #define RGBLIGHT_EFFECT_STATIC_GRADIENT #define RGBLIGHT_EFFECT_TWINKLE -#define RGBLED_SPLIT { 11, 11 } #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/momoka_ergo/info.json b/keyboards/momoka_ergo/info.json index fa116fd1c0cb..99f8dbd51a48 100644 --- a/keyboards/momoka_ergo/info.json +++ b/keyboards/momoka_ergo/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D1" }, + "rgblight": { + "split_count": [11, 11] + }, "ws2812": { "pin": "C7" }, diff --git a/keyboards/nacly/splitreus62/config.h b/keyboards/nacly/splitreus62/config.h index 9c6773547e8d..7a5962801c0a 100644 --- a/keyboards/nacly/splitreus62/config.h +++ b/keyboards/nacly/splitreus62/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #define RGBLED_NUM 12 // Number of LEDs -#define RGBLED_SPLIT { 6, 6 } /* * Feature disable options * These options are also useful to firmware size reduction. diff --git a/keyboards/nacly/splitreus62/info.json b/keyboards/nacly/splitreus62/info.json index 5c61b6f5fe42..775f3c2497c7 100644 --- a/keyboards/nacly/splitreus62/info.json +++ b/keyboards/nacly/splitreus62/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "B1" }, diff --git a/keyboards/nullbitsco/snap/config.h b/keyboards/nullbitsco/snap/config.h index 24e9340c0e3a..cbc354a13a1b 100644 --- a/keyboards/nullbitsco/snap/config.h +++ b/keyboards/nullbitsco/snap/config.h @@ -59,7 +59,6 @@ /* Optional SMT LED pins */ #define RGBLED_NUM 10 -#define RGBLED_SPLIT { 5, 5 } #define RGBLIGHT_LED_MAP { 8, 9, 0, 1, 2, 6, 7, 3, 4, 5 } #define RGBLIGHT_SLEEP #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/nullbitsco/snap/info.json b/keyboards/nullbitsco/snap/info.json index 560389a11fda..fcb224d30ad9 100644 --- a/keyboards/nullbitsco/snap/info.json +++ b/keyboards/nullbitsco/snap/info.json @@ -7,6 +7,9 @@ "pid": "0x6063", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [5, 5] + }, "ws2812": { "pin": "B2" }, diff --git a/keyboards/obosob/arch_36/config.h b/keyboards/obosob/arch_36/config.h index 068a231f434e..3852baf5a7fa 100644 --- a/keyboards/obosob/arch_36/config.h +++ b/keyboards/obosob/arch_36/config.h @@ -18,7 +18,6 @@ along with this program. If not, see . #pragma once #ifdef RGBLIGHT_ENABLE -#define RGBLED_SPLIT { 6, 6 } #define RGBLED_NUM 12 #define RGBLIGHT_LED_MAP { 0, 1, 2, 3, 4, 5, \ 11, 10, 9, 8, 7, 6 } diff --git a/keyboards/obosob/arch_36/info.json b/keyboards/obosob/arch_36/info.json index d978080a2f73..cffa4e8e4466 100644 --- a/keyboards/obosob/arch_36/info.json +++ b/keyboards/obosob/arch_36/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/ogre/ergo_split/config.h b/keyboards/ogre/ergo_split/config.h index 92535947de1b..20bff507def5 100644 --- a/keyboards/ogre/ergo_split/config.h +++ b/keyboards/ogre/ergo_split/config.h @@ -19,7 +19,6 @@ along with this program. If not, see . #define SPLIT_HAND_PIN D1 -#define RGBLED_SPLIT { 7, 7 } #define RGBLED_NUM 14 #define RGBLIGHT_LED_MAP { 6, 5, 4, 3, 2, 1, 0, 13, 12,11, 10, 9, 8, 7} #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/ogre/ergo_split/info.json b/keyboards/ogre/ergo_split/info.json index 2a1bbbdcd650..1055724b5ffa 100644 --- a/keyboards/ogre/ergo_split/info.json +++ b/keyboards/ogre/ergo_split/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D3" }, + "rgblight": { + "split_count": [7, 7] + }, "ws2812": { "pin": "B6" }, diff --git a/keyboards/omkbd/ergodash/mini/config.h b/keyboards/omkbd/ergodash/mini/config.h index c66f9ef044b7..743db387e8bf 100644 --- a/keyboards/omkbd/ergodash/mini/config.h +++ b/keyboards/omkbd/ergodash/mini/config.h @@ -41,7 +41,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 20 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 10, 10 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/ergodash/mini/info.json b/keyboards/omkbd/ergodash/mini/info.json index 0c62ef58fdf8..169bc9f0c568 100644 --- a/keyboards/omkbd/ergodash/mini/info.json +++ b/keyboards/omkbd/ergodash/mini/info.json @@ -20,6 +20,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [10, 10] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/omkbd/ergodash/rev1/config.h b/keyboards/omkbd/ergodash/rev1/config.h index 03eea39fd6ec..851116d455ae 100644 --- a/keyboards/omkbd/ergodash/rev1/config.h +++ b/keyboards/omkbd/ergodash/rev1/config.h @@ -41,7 +41,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 24 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 12, 12 } // Number of LEDs // The LEDs on the slave half go in reverse order #define RGBLIGHT_LED_MAP { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, \ diff --git a/keyboards/omkbd/ergodash/rev1/info.json b/keyboards/omkbd/ergodash/rev1/info.json index 1ec059bd82bf..3a395bde83ec 100644 --- a/keyboards/omkbd/ergodash/rev1/info.json +++ b/keyboards/omkbd/ergodash/rev1/info.json @@ -20,6 +20,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [12, 12] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/omkbd/runner3680/3x6/config.h b/keyboards/omkbd/runner3680/3x6/config.h index d2cd91cbc547..282dda9dcda1 100644 --- a/keyboards/omkbd/runner3680/3x6/config.h +++ b/keyboards/omkbd/runner3680/3x6/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 36 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 18, 18 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/3x6/info.json b/keyboards/omkbd/runner3680/3x6/info.json index c197f04207c8..7a7141816b91 100644 --- a/keyboards/omkbd/runner3680/3x6/info.json +++ b/keyboards/omkbd/runner3680/3x6/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [18, 18] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/3x7/config.h b/keyboards/omkbd/runner3680/3x7/config.h index b8c601b56426..37610bc4ba48 100644 --- a/keyboards/omkbd/runner3680/3x7/config.h +++ b/keyboards/omkbd/runner3680/3x7/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 42 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 21, 21 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/3x7/info.json b/keyboards/omkbd/runner3680/3x7/info.json index 458fab653c02..d23f6f509896 100644 --- a/keyboards/omkbd/runner3680/3x7/info.json +++ b/keyboards/omkbd/runner3680/3x7/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [21, 21] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/3x8/config.h b/keyboards/omkbd/runner3680/3x8/config.h index 3a273e8bb958..f53b886d7e96 100644 --- a/keyboards/omkbd/runner3680/3x8/config.h +++ b/keyboards/omkbd/runner3680/3x8/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 48 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 24, 24 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/3x8/info.json b/keyboards/omkbd/runner3680/3x8/info.json index 33fcc3228f9a..9f3d4b6bc2e7 100644 --- a/keyboards/omkbd/runner3680/3x8/info.json +++ b/keyboards/omkbd/runner3680/3x8/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [24, 24] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/4x6/config.h b/keyboards/omkbd/runner3680/4x6/config.h index 3a273e8bb958..f53b886d7e96 100644 --- a/keyboards/omkbd/runner3680/4x6/config.h +++ b/keyboards/omkbd/runner3680/4x6/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 48 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 24, 24 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/4x6/info.json b/keyboards/omkbd/runner3680/4x6/info.json index 2e6eda2a2eee..a21eb2f4bbe4 100644 --- a/keyboards/omkbd/runner3680/4x6/info.json +++ b/keyboards/omkbd/runner3680/4x6/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [24, 24] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/4x7/config.h b/keyboards/omkbd/runner3680/4x7/config.h index f6b5dcf1450f..326d9427408e 100644 --- a/keyboards/omkbd/runner3680/4x7/config.h +++ b/keyboards/omkbd/runner3680/4x7/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 56 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 28, 28 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/4x7/info.json b/keyboards/omkbd/runner3680/4x7/info.json index af1a4375d635..e3d06566d633 100644 --- a/keyboards/omkbd/runner3680/4x7/info.json +++ b/keyboards/omkbd/runner3680/4x7/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [28, 28] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/4x8/config.h b/keyboards/omkbd/runner3680/4x8/config.h index 9a53d1968852..193bf611cbad 100644 --- a/keyboards/omkbd/runner3680/4x8/config.h +++ b/keyboards/omkbd/runner3680/4x8/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 64 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 32, 32 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/4x8/info.json b/keyboards/omkbd/runner3680/4x8/info.json index 88dc1455ce26..90b63fb9ff7e 100644 --- a/keyboards/omkbd/runner3680/4x8/info.json +++ b/keyboards/omkbd/runner3680/4x8/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [32, 32] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/5x6/config.h b/keyboards/omkbd/runner3680/5x6/config.h index 52626f1de345..8f4f682a688a 100644 --- a/keyboards/omkbd/runner3680/5x6/config.h +++ b/keyboards/omkbd/runner3680/5x6/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 60 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 30, 30 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/5x6/info.json b/keyboards/omkbd/runner3680/5x6/info.json index 08c4950b807b..c41074c9c129 100644 --- a/keyboards/omkbd/runner3680/5x6/info.json +++ b/keyboards/omkbd/runner3680/5x6/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [30, 30] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/5x6_5x8/config.h b/keyboards/omkbd/runner3680/5x6_5x8/config.h index 33f41e5289ca..261afc1d025d 100644 --- a/keyboards/omkbd/runner3680/5x6_5x8/config.h +++ b/keyboards/omkbd/runner3680/5x6_5x8/config.h @@ -38,7 +38,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 70 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 30, 40 } // Number of LEDs #endif #ifdef RGB_MATRIX_ENABLE #define RGB_MATRIX_LED_COUNT 70 diff --git a/keyboards/omkbd/runner3680/5x6_5x8/info.json b/keyboards/omkbd/runner3680/5x6_5x8/info.json index 8b1b7054a5ea..754135e4c319 100644 --- a/keyboards/omkbd/runner3680/5x6_5x8/info.json +++ b/keyboards/omkbd/runner3680/5x6_5x8/info.json @@ -23,7 +23,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [30, 40] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/5x7/config.h b/keyboards/omkbd/runner3680/5x7/config.h index 7b60494fcbc3..ee1b1d674101 100644 --- a/keyboards/omkbd/runner3680/5x7/config.h +++ b/keyboards/omkbd/runner3680/5x7/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 70 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 35, 35 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/5x7/info.json b/keyboards/omkbd/runner3680/5x7/info.json index 0c0c8670f2b1..f27590f4022f 100644 --- a/keyboards/omkbd/runner3680/5x7/info.json +++ b/keyboards/omkbd/runner3680/5x7/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [35, 35] }, "layouts": { "LAYOUT": { diff --git a/keyboards/omkbd/runner3680/5x8/config.h b/keyboards/omkbd/runner3680/5x8/config.h index 55d8ae5c97fb..a0a4d4b9829a 100644 --- a/keyboards/omkbd/runner3680/5x8/config.h +++ b/keyboards/omkbd/runner3680/5x8/config.h @@ -37,7 +37,6 @@ #define RGBLIGHT_EFFECT_TWINKLE #define RGBLED_NUM 80 #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 40, 40 } // Number of LEDs #define SELECT_SOFT_SERIAL_SPEED 1 /*Sets the protocol speed when using serial communication*/ diff --git a/keyboards/omkbd/runner3680/5x8/info.json b/keyboards/omkbd/runner3680/5x8/info.json index 41e95e583a94..ae35f6112825 100644 --- a/keyboards/omkbd/runner3680/5x8/info.json +++ b/keyboards/omkbd/runner3680/5x8/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [40, 40] }, "layouts": { "LAYOUT": { diff --git a/keyboards/peej/tripel/left/info.json b/keyboards/peej/tripel/left/info.json index b938ef9b9a34..e9833e2464bc 100644 --- a/keyboards/peej/tripel/left/info.json +++ b/keyboards/peej/tripel/left/info.json @@ -70,7 +70,7 @@ {"matrix": [5, 7], "x": 1, "y": 4}, {"matrix": [4, 6], "x": 2, "y": 4}, {"matrix": [4, 7], "x": 3, "y": 4}, - {"matrix": [7, 6], "x": 7, "y": 4, "w": 7}, + {"matrix": [7, 6], "x": 4, "y": 4, "w": 7}, {"matrix": [2, 7], "x": 11, "y": 4}, {"matrix": [1, 6], "x": 12, "y": 4}, {"matrix": [1, 7], "x": 13, "y": 4}, diff --git a/keyboards/peej/tripel/middle/info.json b/keyboards/peej/tripel/middle/info.json index b1bdf10f82e5..98d854e4893a 100644 --- a/keyboards/peej/tripel/middle/info.json +++ b/keyboards/peej/tripel/middle/info.json @@ -70,7 +70,7 @@ {"matrix": [2, 7], "x": 1, "y": 4}, {"matrix": [1, 6], "x": 2, "y": 4}, {"matrix": [1, 7], "x": 3, "y": 4}, - {"matrix": [4, 6], "x": 7, "y": 4, "w": 7}, + {"matrix": [4, 6], "x": 4, "y": 4, "w": 7}, {"matrix": [8, 7], "x": 11, "y": 4}, {"matrix": [7, 6], "x": 12, "y": 4}, {"matrix": [7, 7], "x": 13, "y": 4}, diff --git a/keyboards/peej/tripel/right/info.json b/keyboards/peej/tripel/right/info.json index 9916d317f2fc..c9f31f46797f 100644 --- a/keyboards/peej/tripel/right/info.json +++ b/keyboards/peej/tripel/right/info.json @@ -70,7 +70,7 @@ {"matrix": [8, 7], "x": 1, "y": 4}, {"matrix": [7, 6], "x": 2, "y": 4}, {"matrix": [7, 7], "x": 3, "y": 4}, - {"matrix": [1, 6], "x": 7, "y": 4, "w": 7}, + {"matrix": [1, 6], "x": 4, "y": 4, "w": 7}, {"matrix": [5, 7], "x": 11, "y": 4}, {"matrix": [4, 6], "x": 12, "y": 4}, {"matrix": [4, 7], "x": 13, "y": 4}, diff --git a/keyboards/planck/keymaps/mwpeterson/keymap.c b/keyboards/planck/keymaps/mwpeterson/keymap.c index 5871fe4bfe35..065750434f4c 100644 --- a/keyboards/planck/keymaps/mwpeterson/keymap.c +++ b/keyboards/planck/keymaps/mwpeterson/keymap.c @@ -102,7 +102,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [LOWER_LAYER] = LAYOUT_planck_grid( KC_GRV, KC_F1, KC_F2, KC_F3, KC_F4, KC_F5, KC_F6, KC_F7, KC_F8, KC_F9, KC_F10, S(KC_3), _______, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, _______, - _______, KC_MINS, KC_PLUS, KC_GRV, SFT_INS, KC_COLN, KC_PIPE, X(IBANG), KC_COMM, KC_DOT, KC_BSLS, _______, + _______, KC_MINS, KC_PLUS, KC_GRV, SFT_INS, KC_COLN, KC_PIPE, UM(IBANG), KC_COMM, KC_DOT, KC_BSLS, _______, _______, _______, _______, _______, _______, KC_BSPC, KC_BSPC, _______, _______, _______, _______, _______ ), diff --git a/keyboards/planck/keymaps/zach/zach_common_functions.c b/keyboards/planck/keymaps/zach/zach_common_functions.c index 6ad1c7bed337..ae5f44e71363 100644 --- a/keyboards/planck/keymaps/zach/zach_common_functions.c +++ b/keyboards/planck/keymaps/zach/zach_common_functions.c @@ -141,31 +141,31 @@ tap_dance_action_t tap_dance_actions[] = { //#ifdef UNICODE_ENABLE // Unicode shortcuts -#define IBANG X(0x203D) -#define RAROW X(0x2192) -#define LAROW X(0x2190) -#define DEGREE X(0x00B0) -#define OMEGA X(0x03A9) -#define WOMEGA X(0x03C9) -#define MICRO X(0x00B5) -#define PLUMIN X(0x00B1) -#define SUPA2 X(0x00B2) -#define ROMAN1 X(0x2160) -#define ROMAN2 X(0x2161) -#define ROMAN3 X(0x2162) -#define ROMAN4 X(0x2163) -#define ROMAN5 X(0x2164) -#define ROMAN6 X(0x2165) -#define ROMAN7 X(0x2166) -#define roman1 X(0x2170) -#define roman2 X(0x2171) -#define roman3 X(0x2172) -#define roman4 X(0x2173) -#define roman5 X(0x2174) -#define roman6 X(0x2175) -#define roman7 X(0x2176) +#define IBANG UM(0x203D) +#define RAROW UM(0x2192) +#define LAROW UM(0x2190) +#define DEGREE UM(0x00B0) +#define OMEGA UM(0x03A9) +#define WOMEGA UM(0x03C9) +#define MICRO UM(0x00B5) +#define PLUMIN UM(0x00B1) +#define SUPA2 UM(0x00B2) +#define ROMAN1 UM(0x2160) +#define ROMAN2 UM(0x2161) +#define ROMAN3 UM(0x2162) +#define ROMAN4 UM(0x2163) +#define ROMAN5 UM(0x2164) +#define ROMAN6 UM(0x2165) +#define ROMAN7 UM(0x2166) +#define roman1 UM(0x2170) +#define roman2 UM(0x2171) +#define roman3 UM(0x2172) +#define roman4 UM(0x2173) +#define roman5 UM(0x2174) +#define roman6 UM(0x2175) +#define roman7 UM(0x2176) -#ifdef UNICODEMAP_ENABLE // For Unicode characters larger than 0x8000. Send with X() +#ifdef UNICODEMAP_ENABLE enum Ext_Unicode{ PENGUIN = 0, BOAR, @@ -182,12 +182,12 @@ const uint32_t unicode_map[] PROGMEM = { [CHICK] = 0x1F425, [TUMBLER] = 0x1F943 }; -#define PENGY X(PENGUIN) -#define BOARY X(BOAR) -#define MNKY X(MONKEY) -#define DRGN X(DRAGON) -#define DUCK X(CHICK) -#define TMBL X(TUMBLER) +#define PENGY UM(PENGUIN) +#define BOARY UM(BOAR) +#define MNKY UM(MONKEY) +#define DRGN UM(DRAGON) +#define DUCK UM(CHICK) +#define TMBL UM(TUMBLER) #endif //#endif diff --git a/keyboards/preonic/keymaps/zach/zach_common_functions.c b/keyboards/preonic/keymaps/zach/zach_common_functions.c index 6ad1c7bed337..ae5f44e71363 100644 --- a/keyboards/preonic/keymaps/zach/zach_common_functions.c +++ b/keyboards/preonic/keymaps/zach/zach_common_functions.c @@ -141,31 +141,31 @@ tap_dance_action_t tap_dance_actions[] = { //#ifdef UNICODE_ENABLE // Unicode shortcuts -#define IBANG X(0x203D) -#define RAROW X(0x2192) -#define LAROW X(0x2190) -#define DEGREE X(0x00B0) -#define OMEGA X(0x03A9) -#define WOMEGA X(0x03C9) -#define MICRO X(0x00B5) -#define PLUMIN X(0x00B1) -#define SUPA2 X(0x00B2) -#define ROMAN1 X(0x2160) -#define ROMAN2 X(0x2161) -#define ROMAN3 X(0x2162) -#define ROMAN4 X(0x2163) -#define ROMAN5 X(0x2164) -#define ROMAN6 X(0x2165) -#define ROMAN7 X(0x2166) -#define roman1 X(0x2170) -#define roman2 X(0x2171) -#define roman3 X(0x2172) -#define roman4 X(0x2173) -#define roman5 X(0x2174) -#define roman6 X(0x2175) -#define roman7 X(0x2176) +#define IBANG UM(0x203D) +#define RAROW UM(0x2192) +#define LAROW UM(0x2190) +#define DEGREE UM(0x00B0) +#define OMEGA UM(0x03A9) +#define WOMEGA UM(0x03C9) +#define MICRO UM(0x00B5) +#define PLUMIN UM(0x00B1) +#define SUPA2 UM(0x00B2) +#define ROMAN1 UM(0x2160) +#define ROMAN2 UM(0x2161) +#define ROMAN3 UM(0x2162) +#define ROMAN4 UM(0x2163) +#define ROMAN5 UM(0x2164) +#define ROMAN6 UM(0x2165) +#define ROMAN7 UM(0x2166) +#define roman1 UM(0x2170) +#define roman2 UM(0x2171) +#define roman3 UM(0x2172) +#define roman4 UM(0x2173) +#define roman5 UM(0x2174) +#define roman6 UM(0x2175) +#define roman7 UM(0x2176) -#ifdef UNICODEMAP_ENABLE // For Unicode characters larger than 0x8000. Send with X() +#ifdef UNICODEMAP_ENABLE enum Ext_Unicode{ PENGUIN = 0, BOAR, @@ -182,12 +182,12 @@ const uint32_t unicode_map[] PROGMEM = { [CHICK] = 0x1F425, [TUMBLER] = 0x1F943 }; -#define PENGY X(PENGUIN) -#define BOARY X(BOAR) -#define MNKY X(MONKEY) -#define DRGN X(DRAGON) -#define DUCK X(CHICK) -#define TMBL X(TUMBLER) +#define PENGY UM(PENGUIN) +#define BOARY UM(BOAR) +#define MNKY UM(MONKEY) +#define DRGN UM(DRAGON) +#define DUCK UM(CHICK) +#define TMBL UM(TUMBLER) #endif //#endif diff --git a/keyboards/rate/pistachio/rev1/config.h b/keyboards/rate/pistachio/rev1/config.h index cf7e2cdfb027..e74350e8e595 100644 --- a/keyboards/rate/pistachio/rev1/config.h +++ b/keyboards/rate/pistachio/rev1/config.h @@ -21,7 +21,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 1, 1 } #define RGBLED_NUM 2 #define RGBLIGHT_LAYERS #define RGBLIGHT_HUE_STEP 10 diff --git a/keyboards/rate/pistachio/rev1/info.json b/keyboards/rate/pistachio/rev1/info.json index a50ae8b99194..60b907c809ba 100644 --- a/keyboards/rate/pistachio/rev1/info.json +++ b/keyboards/rate/pistachio/rev1/info.json @@ -1,4 +1,7 @@ { + "rgblight": { + "split_count": [1, 1] + }, "ws2812": { "pin": "D2" }, diff --git a/keyboards/rate/pistachio/rev2/config.h b/keyboards/rate/pistachio/rev2/config.h index 5ac0b8fbfa48..adec2ec66a2b 100644 --- a/keyboards/rate/pistachio/rev2/config.h +++ b/keyboards/rate/pistachio/rev2/config.h @@ -24,7 +24,6 @@ along with this program. If not, see . /* ws2812 RGB LED */ #define RGBLIGHT_SPLIT -#define RGBLED_SPLIT { 38, 46 } #define RGBLED_NUM 84 #define RGBLIGHT_LAYERS #define RGBLIGHT_HUE_STEP 10 diff --git a/keyboards/rate/pistachio/rev2/info.json b/keyboards/rate/pistachio/rev2/info.json index a1ea3be3cb34..cf2c1db741bd 100644 --- a/keyboards/rate/pistachio/rev2/info.json +++ b/keyboards/rate/pistachio/rev2/info.json @@ -3,7 +3,8 @@ "pin": "D2" }, "rgblight": { - "max_brightness": 195 + "max_brightness": 195, + "split_count": [38, 46] }, "matrix_pins": { "cols": ["B6", "B2", "B3", "B1", "F7", "F6", "F5", "F4", "D3"], diff --git a/keyboards/reviung/reviung41/keymaps/ciutadellla/keymap.c b/keyboards/reviung/reviung41/keymaps/ciutadellla/keymap.c index 98dda7fe1994..a4279821ccc1 100644 --- a/keyboards/reviung/reviung41/keymaps/ciutadellla/keymap.c +++ b/keyboards/reviung/reviung41/keymaps/ciutadellla/keymap.c @@ -265,7 +265,7 @@ * +-------------/ \--------------+ */ - [_ADJUST] = LAYOUT_reviung41(X(GRINNING_FACE), X(GRINNING_FACE_WITH_SWEAT), X(ROLLING_LAUGHING), X(WINKING_FACE), X(SMILING_FACE_HALO), X(SMILING_FACE_HEARTS), RGB_VAI, RGB_HUI, RGB_MOD, KC_BRIU, KC_MPLY, KC_VOLU, X(SMILING_FACE_HEART_EYES), X(FACE_BLOWING_KISS), X(FACE_ROLLING_EYES), X(PENSIVE_FACE), X(LOUDLY_CRYING_FACE), X(PILE_POO), RGB_VAD, RGB_HUD, RGB_RMOD, KC_BRID, KC_MSTP, KC_VOLD, X(THUMBSUP), X(THUMBSDOWN), X(CLAPPING_HANDS), X(EYES), X(MAN_FACEPALMING), X(GHOST), RGB_TOG, RGB_SAD, RGB_SAI, RGB_SPD, RGB_SPI, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS) + [_ADJUST] = LAYOUT_reviung41(UM(GRINNING_FACE), UM(GRINNING_FACE_WITH_SWEAT), UM(ROLLING_LAUGHING), UM(WINKING_FACE), UM(SMILING_FACE_HALO), UM(SMILING_FACE_HEARTS), RGB_VAI, RGB_HUI, RGB_MOD, KC_BRIU, KC_MPLY, KC_VOLU, UM(SMILING_FACE_HEART_EYES), UM(FACE_BLOWING_KISS), UM(FACE_ROLLING_EYES), UM(PENSIVE_FACE), UM(LOUDLY_CRYING_FACE), UM(PILE_POO), RGB_VAD, RGB_HUD, RGB_RMOD, KC_BRID, KC_MSTP, KC_VOLD, UM(THUMBSUP), UM(THUMBSDOWN), UM(CLAPPING_HANDS), UM(EYES), UM(MAN_FACEPALMING), UM(GHOST), RGB_TOG, RGB_SAD, RGB_SAI, RGB_SPD, RGB_SPI, KC_MUTE, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS, KC_TRNS) }; diff --git a/keyboards/rgbkb/mun/config.h b/keyboards/rgbkb/mun/config.h index 5b411a8c5294..b5b7c0ce95c1 100644 --- a/keyboards/rgbkb/mun/config.h +++ b/keyboards/rgbkb/mun/config.h @@ -50,7 +50,6 @@ /* RGB LED Configuration */ #define RGBLED_NUM 98 -#define RGBLED_SPLIT { 49, 49 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/rgbkb/mun/rev1/info.json b/keyboards/rgbkb/mun/rev1/info.json index 36b1ab000309..3bf22fa65621 100644 --- a/keyboards/rgbkb/mun/rev1/info.json +++ b/keyboards/rgbkb/mun/rev1/info.json @@ -8,6 +8,9 @@ "pid": "0x3505", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [49, 49] + }, "ws2812": { "pin": "B5", "driver": "pwm" diff --git a/keyboards/rgbkb/sol3/config.h b/keyboards/rgbkb/sol3/config.h index 1b8fa2314f9b..bce51e7fcc0b 100644 --- a/keyboards/rgbkb/sol3/config.h +++ b/keyboards/rgbkb/sol3/config.h @@ -54,7 +54,6 @@ /* RGB LED Configuration */ #define RGBLED_NUM 156 -#define RGBLED_SPLIT { 78, 78 } // RGB Lighting Animation modes. Explicitly enabled // For full list of effects, see: diff --git a/keyboards/rgbkb/sol3/rev1/info.json b/keyboards/rgbkb/sol3/rev1/info.json index 74af9d21faf5..192760068d0a 100644 --- a/keyboards/rgbkb/sol3/rev1/info.json +++ b/keyboards/rgbkb/sol3/rev1/info.json @@ -8,6 +8,9 @@ "pid": "0x3510", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [78, 78] + }, "ws2812": { "pin": "B5", "driver": "pwm" diff --git a/keyboards/rgbkb/zygomorph/rev1/config.h b/keyboards/rgbkb/zygomorph/rev1/config.h index 022e361de16e..a7d023893edc 100644 --- a/keyboards/rgbkb/zygomorph/rev1/config.h +++ b/keyboards/rgbkb/zygomorph/rev1/config.h @@ -25,7 +25,6 @@ along with this program. If not, see . #define RGBLED_NUM 30 #else #define RGBLED_NUM 60 - #define RGBLED_SPLIT { 30, 30 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/rgbkb/zygomorph/rev1/info.json b/keyboards/rgbkb/zygomorph/rev1/info.json index 4be3dd61d36f..893e5ff589b2 100644 --- a/keyboards/rgbkb/zygomorph/rev1/info.json +++ b/keyboards/rgbkb/zygomorph/rev1/info.json @@ -24,6 +24,9 @@ "split": { "soft_serial_pin": "D3" }, + "rgblight": { + "split_count": [30, 30] + }, "ws2812": { "pin": "B7" }, diff --git a/keyboards/rura66/rev1/config.h b/keyboards/rura66/rev1/config.h index 8afe563b68f5..5934a18162a6 100644 --- a/keyboards/rura66/rev1/config.h +++ b/keyboards/rura66/rev1/config.h @@ -23,7 +23,6 @@ along with this program. If not, see . #ifdef RGBLIGHT_ENABLE #define RGBLED_NUM 66 // Number of LEDs #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 33, 33 } #define RGBLIGHT_HUE_STEP 8 #define RGBLIGHT_SAT_STEP 8 #define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/rura66/rev1/info.json b/keyboards/rura66/rev1/info.json index e312323c4dd3..fb093b9d4ec7 100644 --- a/keyboards/rura66/rev1/info.json +++ b/keyboards/rura66/rev1/info.json @@ -12,7 +12,8 @@ "driver": "WS2812" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [33, 33] }, "matrix_pins": { "cols": ["F4", "F5", "F6", "F7", "B1", "B3", "B2"], diff --git a/keyboards/salicylic_acid3/7skb/rev1/config.h b/keyboards/salicylic_acid3/7skb/rev1/config.h index 573efb81c713..44b7b88cfaba 100644 --- a/keyboards/salicylic_acid3/7skb/rev1/config.h +++ b/keyboards/salicylic_acid3/7skb/rev1/config.h @@ -28,7 +28,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 12 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 6, 6 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/7skb/rev1/info.json b/keyboards/salicylic_acid3/7skb/rev1/info.json index 12f0b6f42481..e195344ed111 100644 --- a/keyboards/salicylic_acid3/7skb/rev1/info.json +++ b/keyboards/salicylic_acid3/7skb/rev1/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/salicylic_acid3/7splus/config.h b/keyboards/salicylic_acid3/7splus/config.h index 82eec4a3066f..e8a6d3a3935c 100644 --- a/keyboards/salicylic_acid3/7splus/config.h +++ b/keyboards/salicylic_acid3/7splus/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 31 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 11, 20 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/7splus/info.json b/keyboards/salicylic_acid3/7splus/info.json index 524ecc34ea70..fa9c166ada80 100644 --- a/keyboards/salicylic_acid3/7splus/info.json +++ b/keyboards/salicylic_acid3/7splus/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [11, 20] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/salicylic_acid3/ergoarrows/config.h b/keyboards/salicylic_acid3/ergoarrows/config.h index dcbdb0f5374a..e829c4b82751 100644 --- a/keyboards/salicylic_acid3/ergoarrows/config.h +++ b/keyboards/salicylic_acid3/ergoarrows/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 86 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 43, 43 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/ergoarrows/info.json b/keyboards/salicylic_acid3/ergoarrows/info.json index 1665fce7e8fb..b058a5367d19 100644 --- a/keyboards/salicylic_acid3/ergoarrows/info.json +++ b/keyboards/salicylic_acid3/ergoarrows/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [43, 43] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/salicylic_acid3/jisplit89/rev1/config.h b/keyboards/salicylic_acid3/jisplit89/rev1/config.h index 51b6d454e5f5..5bc8bce7d594 100644 --- a/keyboards/salicylic_acid3/jisplit89/rev1/config.h +++ b/keyboards/salicylic_acid3/jisplit89/rev1/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 32 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 11, 21 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/jisplit89/rev1/info.json b/keyboards/salicylic_acid3/jisplit89/rev1/info.json index 63feabb93937..bc2759751ed6 100644 --- a/keyboards/salicylic_acid3/jisplit89/rev1/info.json +++ b/keyboards/salicylic_acid3/jisplit89/rev1/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [11, 21] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/salicylic_acid3/nknl7en/config.h b/keyboards/salicylic_acid3/nknl7en/config.h index 9f39d06f61f3..f4a8e200d3ce 100644 --- a/keyboards/salicylic_acid3/nknl7en/config.h +++ b/keyboards/salicylic_acid3/nknl7en/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 21 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 9, 12 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/nknl7en/info.json b/keyboards/salicylic_acid3/nknl7en/info.json index f0f45f077a4c..db2460d28ab5 100644 --- a/keyboards/salicylic_acid3/nknl7en/info.json +++ b/keyboards/salicylic_acid3/nknl7en/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [9, 12] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/salicylic_acid3/nknl7jp/config.h b/keyboards/salicylic_acid3/nknl7jp/config.h index 65091cadc073..b11397bde8da 100644 --- a/keyboards/salicylic_acid3/nknl7jp/config.h +++ b/keyboards/salicylic_acid3/nknl7jp/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . #ifndef RGBLED_NUM #define RGBLED_NUM 20 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 9, 11 } #endif #define RGBLIGHT_EFFECT_BREATHING diff --git a/keyboards/salicylic_acid3/nknl7jp/info.json b/keyboards/salicylic_acid3/nknl7jp/info.json index 5713ad908469..bcbabe051d82 100644 --- a/keyboards/salicylic_acid3/nknl7jp/info.json +++ b/keyboards/salicylic_acid3/nknl7jp/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [9, 11] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/signum/3_0/keymaps/default/generate_km.py b/keyboards/signum/3_0/keymaps/default/generate_km.py index cfa8edf57a76..a939e4e73a40 100755 --- a/keyboards/signum/3_0/keymaps/default/generate_km.py +++ b/keyboards/signum/3_0/keymaps/default/generate_km.py @@ -39,7 +39,7 @@ def _translate(s): elif re.match("^TT[0-9]{1,2}$", s): # Tn, works from TT0 to TT99 return ("TT({0})".format(s[2:]), "{0:^7}".format(s)) elif s in layout.uc_dict: - return ("X("+s+")", " {0} ".format(chr(int(layout.uc_dict[s], 0)))) + return ("UM("+s+")", " {0} ".format(chr(int(layout.uc_dict[s], 0)))) elif s in layout.qmk_dict: return (layout.qmk_dict[s], "{0:^7}".format(s)) elif s == s.upper() and s.startswith("KC_"): diff --git a/keyboards/signum/3_0/keymaps/default/layout.py b/keyboards/signum/3_0/keymaps/default/layout.py index 90fb1d9c9458..4691985d29d3 100644 --- a/keyboards/signum/3_0/keymaps/default/layout.py +++ b/keyboards/signum/3_0/keymaps/default/layout.py @@ -396,7 +396,7 @@ # One Shot Keys missing # Swap Hands "_sp_swp": "SHT(KC_SPC)", - # Unicode support (via X()) included implicitly + # Unicode support included implicitly # Switching Unicode Input Modes "UC_win": "UC_WINC", "UC_lnx": "UC_LINX", "UC_mac": "UC_MAC", diff --git a/keyboards/silverbullet44/config.h b/keyboards/silverbullet44/config.h index 5485a99f59d6..67d78aa0c62d 100644 --- a/keyboards/silverbullet44/config.h +++ b/keyboards/silverbullet44/config.h @@ -20,7 +20,6 @@ along with this program. If not, see . #define MASTER_RIGHT //#define RGBLIGHT_SPLIT - #define RGBLED_SPLIT {26, 26} #define RGBLED_NUM 52 #ifdef RGB_MATRIX_ENABLE #define RGB_MATRIX_LED_COUNT 52 diff --git a/keyboards/silverbullet44/info.json b/keyboards/silverbullet44/info.json index 5fc8686de25e..9ca5218d120b 100644 --- a/keyboards/silverbullet44/info.json +++ b/keyboards/silverbullet44/info.json @@ -15,7 +15,8 @@ "driver": "WS2812" }, "rgblight": { - "max_brightness": 150 + "max_brightness": 150, + "split_count": [26, 26] }, "matrix_pins": { "cols": ["B3", "B1", "F7", "F6", "F5", "F4"], diff --git a/keyboards/soda/mango/info.json b/keyboards/soda/mango/info.json new file mode 100644 index 000000000000..a2b3d4b0e09d --- /dev/null +++ b/keyboards/soda/mango/info.json @@ -0,0 +1,49 @@ +{ + "manufacturer": "Soda", + "keyboard_name": "Mango", + "url": "https://github.com/gezhaoyou", + "maintainer": "JeayoKeh", + "diode_direction": "ROW2COL", + "processor": "STM32F072", + "bootloader": "stm32-dfu", + "matrix_pins": { + "cols": ["A6", "A5", "A4", "A3"], + "rows": ["B10", "B2", "B1", "B0", "A7"] + }, + "usb": { + "device_version": "1.0.0", + "force_nkro": true, + "vid": "0x3A54", + "pid": "0x4F5D" + }, + "features": { + "bootmagic": true, + "extrakey": true, + "mousekey": true, + "nkro": true + }, + "community_layouts": ["numpad_5x4"], + "layouts": { + "LAYOUT_numpad_5x4": { + "layout": [ + {"label": "Num Lock", "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": "7", "matrix": [1, 0], "x": 0, "y": 1}, + {"label": "8", "matrix": [1, 1], "x": 1, "y": 1}, + {"label": "9", "matrix": [1, 2], "x": 2, "y": 1}, + {"label": "4", "matrix": [2, 0], "x": 0, "y": 2}, + {"label": "5", "matrix": [2, 1], "x": 1, "y": 2}, + {"label": "6", "matrix": [2, 2], "x": 2, "y": 2}, + {"h": 2, "label": "+", "matrix": [1, 3], "x": 3, "y": 1}, + {"label": "1", "matrix": [3, 0], "x": 0, "y": 3}, + {"label": "2", "matrix": [3, 1], "x": 1, "y": 3}, + {"label": "3", "matrix": [3, 2], "x": 2, "y": 3}, + {"label": "0", "matrix": [4, 0], "w": 2, "x": 0, "y": 4}, + {"label": ".", "matrix": [4, 2], "x": 2, "y": 4}, + {"h": 2, "label": "Enter", "matrix": [3, 3], "x": 3, "y": 3} + ] + } + } +} diff --git a/keyboards/soda/mango/keymaps/default/keymap.c b/keyboards/soda/mango/keymaps/default/keymap.c new file mode 100755 index 000000000000..7497c8751431 --- /dev/null +++ b/keyboards/soda/mango/keymaps/default/keymap.c @@ -0,0 +1,32 @@ +/* +Copyright 2012,2013 gezhaoyou + +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 . +*/ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_numpad_5x4( + KC_NUM_LOCK, KC_PSLS, KC_PAST, LT(1, KC_PMNS), + KC_P7, KC_P8, KC_P9, + KC_P4, KC_P5, KC_P6, KC_PPLS, + KC_P1, KC_P2, KC_P3, + KC_P0, KC_PDOT, KC_PENT), + [1] = LAYOUT_numpad_5x4( + KC_TRNS, KC_CALCULATOR, KC_BSPC, KC_TRNS, + RGB_MODE_FORWARD, RGB_VAI, RGB_HUI, + RGB_SPD, RGB_TOG, RGB_SPI, QK_BOOTLOADER, + RGB_MODE_REVERSE, RGB_VAD, RGB_HUD, + KC_TRNS, KC_TRNS, QK_CLEAR_EEPROM), +}; \ No newline at end of file diff --git a/keyboards/soda/mango/keymaps/via/keymap.c b/keyboards/soda/mango/keymaps/via/keymap.c new file mode 100755 index 000000000000..059598a68094 --- /dev/null +++ b/keyboards/soda/mango/keymaps/via/keymap.c @@ -0,0 +1,33 @@ +/* +Copyright 2012,2013 gezhaoyou + +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 . +*/ +#include QMK_KEYBOARD_H + +const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { + [0] = LAYOUT_numpad_5x4( + KC_NUM_LOCK, KC_PSLS, KC_PAST, LT(1, KC_PMNS), + KC_P7, KC_P8, KC_P9, + KC_P4, KC_P5, KC_P6, KC_PPLS, + KC_P1, KC_P2, KC_P3, + KC_P0, KC_PDOT, KC_PENT), + [1] = LAYOUT_numpad_5x4( + KC_TRNS, KC_CALCULATOR, KC_BSPC, KC_TRNS, + RGB_MODE_FORWARD, RGB_VAI, RGB_HUI, + RGB_SPD, RGB_TOG, RGB_SPI, QK_BOOTLOADER, + RGB_MODE_REVERSE, RGB_VAD, RGB_HUD, + KC_TRNS, KC_TRNS, QK_CLEAR_EEPROM), +}; + diff --git a/keyboards/soda/mango/keymaps/via/rules.mk b/keyboards/soda/mango/keymaps/via/rules.mk new file mode 100644 index 000000000000..1e5b99807cb7 --- /dev/null +++ b/keyboards/soda/mango/keymaps/via/rules.mk @@ -0,0 +1 @@ +VIA_ENABLE = yes diff --git a/keyboards/soda/mango/readme.md b/keyboards/soda/mango/readme.md new file mode 100644 index 000000000000..1a1eb6bccc8c --- /dev/null +++ b/keyboards/soda/mango/readme.md @@ -0,0 +1,23 @@ +# mango-17 + +A customizable 17 keyboard, support both HOTSWAP and SOLDER. + +* Keyboard Maintainer: [gezhaoyou](https://github.com/gezhaoyou) +* Hardware Supported: [gezhaoyou](https://github.com/gezhaoyou) + +Make example for this keyboard (after setting up your build environment): + + make soda/mango:default + +Flashing example for this keyboard: + + make soda/mango: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: + +* **Physical reset button**: Briefly press the button: [boot] first, then press button: [reset] on the back of the PCB +* **Keycode in layout**: Press the key mapped to `QK_BOOT` if it is available diff --git a/keyboards/soda/mango/rules.mk b/keyboards/soda/mango/rules.mk new file mode 100644 index 000000000000..7ff128fa692e --- /dev/null +++ b/keyboards/soda/mango/rules.mk @@ -0,0 +1 @@ +# This file intentionally left blank \ No newline at end of file diff --git a/keyboards/sofle/keyhive/config.h b/keyboards/sofle/keyhive/config.h index 9e36e1588e46..2dccaba6ba4b 100755 --- a/keyboards/sofle/keyhive/config.h +++ b/keyboards/sofle/keyhive/config.h @@ -32,7 +32,6 @@ // by defining in the keyboard, incompatible keymaps will fail to compile. #ifdef RGBLIGHT_ENABLE # define RGBLED_NUM 74 -# define RGBLED_SPLIT {37,37} # define RGBLIGHT_HUE_STEP 10 # define RGBLIGHT_SAT_STEP 17 # define RGBLIGHT_VAL_STEP 17 diff --git a/keyboards/sofle/keyhive/info.json b/keyboards/sofle/keyhive/info.json index 7a453b675e0d..12053234fffe 100644 --- a/keyboards/sofle/keyhive/info.json +++ b/keyboards/sofle/keyhive/info.json @@ -10,7 +10,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 100 + "max_brightness": 100, + "split_count": [37, 37] }, "matrix_pins": { "cols": ["B6", "B2", "B3", "B1", "F7", "F6", null], diff --git a/keyboards/splitkb/aurora/lily58/rev1/config.h b/keyboards/splitkb/aurora/lily58/rev1/config.h index 57a420d49c7a..2e19c5d438a8 100644 --- a/keyboards/splitkb/aurora/lily58/rev1/config.h +++ b/keyboards/splitkb/aurora/lily58/rev1/config.h @@ -29,6 +29,6 @@ // Not yet available in `info.json` #ifdef RGB_MATRIX_ENABLE # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 34, 34 } # define SPLIT_TRANSPORT_MIRROR #endif diff --git a/keyboards/splitkb/aurora/sweep/rev1/config.h b/keyboards/splitkb/aurora/sweep/rev1/config.h index aa5bd24fdee3..5f58760e6a0a 100644 --- a/keyboards/splitkb/aurora/sweep/rev1/config.h +++ b/keyboards/splitkb/aurora/sweep/rev1/config.h @@ -29,6 +29,6 @@ // Not yet available in `info.json` #ifdef RGB_MATRIX_ENABLE # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 23, 23 } # define SPLIT_TRANSPORT_MIRROR #endif diff --git a/keyboards/splitkb/kyria/keymaps/lw/keymap.c b/keyboards/splitkb/kyria/keymaps/lw/keymap.c index 1ff1f54d0582..8cc29c84631c 100644 --- a/keyboards/splitkb/kyria/keymaps/lw/keymap.c +++ b/keyboards/splitkb/kyria/keymaps/lw/keymap.c @@ -52,8 +52,6 @@ const uint32_t unicode_map[] PROGMEM = { [SECTION] = 0x00A7, // § [DEGREE] = 0x00B0, // ° }; -// usage: X(ACUTE), XP(CEDIL,CEDIL_MAJ) - // clang-format off const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { @@ -74,7 +72,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { */ [_QWERTZ] = LAYOUT( KC_ESC, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Z, KC_U, KC_I, KC_O, KC_P, KC_DEL, - KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, XP(APOST,QUOTE), KC_BSPC, // XP(APOST,QUOTE) or KC_QUOT + KC_TAB, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, UP(APOST,QUOTE), KC_BSPC, // UP(APOST,QUOTE) or KC_QUOT KC_LSFT, KC_Y, KC_X, KC_C, KC_V, KC_B, KC_BSLS, KC_GRV, KC_LPRN, KC_RPRN, KC_N, KC_M, KC_COMM, KC_DOT, KC_SCLN, KC_CAPS, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, MO(1), MO(2), SC_SENT, KC_MINS, KC_EXLM, KC_SLSH ), @@ -138,7 +136,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_NAV] = LAYOUT( _______, KC_BRIU, KC_MNXT, KC_MFFD, KC_MPLY, KC_VOLU, KC_HOME, KC_PGUP, KC_UP, KC_PGDN, _______, KC_DEL, _______, KC_BRID, KC_MPRV, KC_MRWD, KC_MSTP, KC_VOLD, KC_END, KC_LEFT, KC_DOWN, KC_RGHT, KC_SCRL, KC_BSPC, - KC_LSFT, US_ACUT, US_DGRV, US_DCIR, US_DIAE, KC_MUTE, _______, UC_NEXT, KC_RSFT, KC_APP, KC_PSCR, XP(CEDIL,CEDIL_MAJ), XP(SECTION,DEGREE), _______, LCTL(KC_S), KC_INS, + KC_LSFT, US_ACUT, US_DGRV, US_DCIR, US_DIAE, KC_MUTE, _______, UC_NEXT, KC_RSFT, KC_APP, KC_PSCR, UP(CEDIL,CEDIL_MAJ), UP(SECTION,DEGREE), _______, LCTL(KC_S), KC_INS, KC_LCTL, KC_LGUI, KC_LALT, _______, MO(1), MO(2), LCTL(KC_Z), LCTL(KC_X), LCTL(KC_C), LCTL(KC_V) ), diff --git a/keyboards/splitkb/kyria/rev1/config.h b/keyboards/splitkb/kyria/rev1/config.h index 3f7655d43165..4ee4e6ae6178 100644 --- a/keyboards/splitkb/kyria/rev1/config.h +++ b/keyboards/splitkb/kyria/rev1/config.h @@ -41,8 +41,6 @@ along with this program. If not, see . # define SOFT_SERIAL_PIN D2 #endif -#define RGBLED_SPLIT \ - { 10, 10 } #define RGBLED_NUM 20 #ifdef OLED_ENABLE diff --git a/keyboards/splitkb/kyria/rev1/info.json b/keyboards/splitkb/kyria/rev1/info.json index 2e380145a082..970f759d232b 100644 --- a/keyboards/splitkb/kyria/rev1/info.json +++ b/keyboards/splitkb/kyria/rev1/info.json @@ -4,6 +4,9 @@ "pid": "0x9D9D", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [10, 10] + }, "rgb_matrix": { "driver": "WS2812" }, diff --git a/keyboards/splitkb/kyria/rev2/config.h b/keyboards/splitkb/kyria/rev2/config.h index 1e8dd0272798..2b05499965b1 100644 --- a/keyboards/splitkb/kyria/rev2/config.h +++ b/keyboards/splitkb/kyria/rev2/config.h @@ -47,8 +47,6 @@ along with this program. If not, see . # define SOFT_SERIAL_PIN D2 #endif -#define RGBLED_SPLIT \ - { 10, 10 } #define RGBLED_NUM 20 #ifdef OLED_ENABLE diff --git a/keyboards/splitkb/kyria/rev2/info.json b/keyboards/splitkb/kyria/rev2/info.json index 9b745dc906f2..d37794164a2a 100644 --- a/keyboards/splitkb/kyria/rev2/info.json +++ b/keyboards/splitkb/kyria/rev2/info.json @@ -4,6 +4,9 @@ "pid": "0x9D9D", "device_version": "0.0.2" }, + "rgblight": { + "split_count": [10, 10] + }, "rgb_matrix": { "driver": "WS2812" }, diff --git a/keyboards/splitkb/kyria/rev3/config.h b/keyboards/splitkb/kyria/rev3/config.h index 3c620d901977..ca97f11eeaff 100644 --- a/keyboards/splitkb/kyria/rev3/config.h +++ b/keyboards/splitkb/kyria/rev3/config.h @@ -29,6 +29,6 @@ // Not yet available in `info.json` #ifdef RGB_MATRIX_ENABLE # define RGB_MATRIX_LED_COUNT RGBLED_NUM -# define RGB_MATRIX_SPLIT RGBLED_SPLIT +# define RGB_MATRIX_SPLIT { 31, 31 } # define SPLIT_TRANSPORT_MIRROR #endif diff --git a/keyboards/takashicompany/compacx/config.h b/keyboards/takashicompany/compacx/config.h index 07287712f3b6..34ab4a1239c9 100644 --- a/keyboards/takashicompany/compacx/config.h +++ b/keyboards/takashicompany/compacx/config.h @@ -18,7 +18,6 @@ along with this program. If not, see . #pragma once # define RGBLED_NUM 12 -# define RGBLED_SPLIT {6, 6} # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/takashicompany/compacx/info.json b/keyboards/takashicompany/compacx/info.json index 2e7ef2f7a643..4c134f314588 100644 --- a/keyboards/takashicompany/compacx/info.json +++ b/keyboards/takashicompany/compacx/info.json @@ -8,6 +8,9 @@ "pid": "0x0014", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/takashicompany/heavy_left/config.h b/keyboards/takashicompany/heavy_left/config.h index df15f55f728a..cee347fc78d3 100644 --- a/keyboards/takashicompany/heavy_left/config.h +++ b/keyboards/takashicompany/heavy_left/config.h @@ -18,7 +18,6 @@ along with this program. If not, see . #pragma once # define RGBLED_NUM 6 * 2 -# define RGBLED_SPLIT {6, 6} # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/takashicompany/heavy_left/info.json b/keyboards/takashicompany/heavy_left/info.json index 1afa2b1280f5..3b677feebfbe 100644 --- a/keyboards/takashicompany/heavy_left/info.json +++ b/keyboards/takashicompany/heavy_left/info.json @@ -8,6 +8,9 @@ "pid": "0x0015", "device_version": "0.0.1" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/takashiski/hecomi/alpha/config.h b/keyboards/takashiski/hecomi/alpha/config.h index ac6c077f6b22..6a564c2da2bd 100644 --- a/keyboards/takashiski/hecomi/alpha/config.h +++ b/keyboards/takashiski/hecomi/alpha/config.h @@ -60,4 +60,3 @@ along with this program. If not, see . #define MASTER_LEFT #define EEHANDS */ -#define RGBLED_SPLIT {8,8} diff --git a/keyboards/takashiski/hecomi/alpha/info.json b/keyboards/takashiski/hecomi/alpha/info.json index 19a1f0576043..b5d4b62bdb35 100644 --- a/keyboards/takashiski/hecomi/alpha/info.json +++ b/keyboards/takashiski/hecomi/alpha/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D1" }, + "rgblight": { + "split_count": [8, 8] + }, "ws2812": { "pin": "D4" }, diff --git a/keyboards/thevankeyboards/minivan/keymaps/josjoha/keymap.c b/keyboards/thevankeyboards/minivan/keymaps/josjoha/keymap.c index a1d82e992305..145da6b2a5a2 100644 --- a/keyboards/thevankeyboards/minivan/keymaps/josjoha/keymap.c +++ b/keyboards/thevankeyboards/minivan/keymaps/josjoha/keymap.c @@ -40,7 +40,7 @@ along with this program. If not, see . * accented characters are defined in unicode_weurope.h * * Unicode macros facilitate recomputing for re-computing the Dvorak with changed letters - * ('descramble'), and exist because space ran out for * XP(…). + * ('descramble'), and exist because space ran out for * UP(…). * * The led color code might be a bit hairy, due to speed/count middle led overlapping layer color. * diff --git a/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c b/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c index f4416ca797a2..ddd37c89e354 100644 --- a/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c +++ b/keyboards/thevankeyboards/minivan/keymaps/josjoha/unicode_macros.c @@ -2022,7 +2022,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { # endif // REMOVE_DRA - /* _BON layer definitions. Due to running out of X(…), XP(…) space.*/ + /* _BON layer definitions. */ // ------------------------- row 4 # ifndef REMOVE_BON // Removes this layer entirely, if set. diff --git a/keyboards/tkw/grandiceps/config.h b/keyboards/tkw/grandiceps/config.h index 4837c2fda6cd..02746f94a815 100644 --- a/keyboards/tkw/grandiceps/config.h +++ b/keyboards/tkw/grandiceps/config.h @@ -21,7 +21,6 @@ #define TAP_CODE_DELAY 10 #define RGBLED_NUM 16 -#define RGBLED_SPLIT { 8,8 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/tkw/grandiceps/info.json b/keyboards/tkw/grandiceps/info.json index 1b16db1bf8c9..d3f6256d4628 100644 --- a/keyboards/tkw/grandiceps/info.json +++ b/keyboards/tkw/grandiceps/info.json @@ -11,7 +11,8 @@ "driver": "pwm" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [8, 8] }, "matrix_pins": { "cols": ["B0", "A7", "A3", "A5", "A4", "A2"], diff --git a/keyboards/uzu42/rev1/config.h b/keyboards/uzu42/rev1/config.h index d0bba6d5983b..033d1ab111dd 100644 --- a/keyboards/uzu42/rev1/config.h +++ b/keyboards/uzu42/rev1/config.h @@ -19,7 +19,6 @@ along with this program. If not, see . #pragma once #define RGBLED_NUM 54 // Number of LEDs -#define RGBLED_SPLIT { 27, 27 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD diff --git a/keyboards/uzu42/rev1/info.json b/keyboards/uzu42/rev1/info.json index 02d1b17be2c5..a9e0b2782645 100644 --- a/keyboards/uzu42/rev1/info.json +++ b/keyboards/uzu42/rev1/info.json @@ -20,7 +20,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [27, 27] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/viktus/sp_mini/config.h b/keyboards/viktus/sp_mini/config.h index bc80a8ebcabb..a5d99eb834fb 100644 --- a/keyboards/viktus/sp_mini/config.h +++ b/keyboards/viktus/sp_mini/config.h @@ -37,7 +37,6 @@ along with this program. If not, see . //#define RGBLIGHT_SPLIT #define RGBLED_NUM 24 // Number of LEDs -#define RGBLED_SPLIT { 12, 12 } /* * Feature disable options diff --git a/keyboards/viktus/sp_mini/info.json b/keyboards/viktus/sp_mini/info.json index 19bba8fea6a7..6c6a5a8d2dcd 100644 --- a/keyboards/viktus/sp_mini/info.json +++ b/keyboards/viktus/sp_mini/info.json @@ -26,6 +26,9 @@ } } }, + "rgblight": { + "split_count": [12, 12] + }, "ws2812": { "pin": "E6" }, diff --git a/keyboards/vitamins_included/rev2/config.h b/keyboards/vitamins_included/rev2/config.h index ce07676feeb5..b86a722674a4 100644 --- a/keyboards/vitamins_included/rev2/config.h +++ b/keyboards/vitamins_included/rev2/config.h @@ -33,7 +33,6 @@ along with this program. If not, see . #define RGBLIGHT_EFFECT_RGB_TEST #define RGBLIGHT_EFFECT_ALTERNATING #define RGBLIGHT_EFFECT_TWINKLE -#define RGBLED_SPLIT { 6, 6 } /* Audio settings */ #ifdef AUDIO_ENABLE diff --git a/keyboards/vitamins_included/rev2/info.json b/keyboards/vitamins_included/rev2/info.json index 9170f80a7d48..c90a668ba0c5 100644 --- a/keyboards/vitamins_included/rev2/info.json +++ b/keyboards/vitamins_included/rev2/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D0" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "F0" }, diff --git a/keyboards/xelus/rs108/info.json b/keyboards/xelus/rs108/info.json index 62377018b6f8..fd2358d68dd3 100644 --- a/keyboards/xelus/rs108/info.json +++ b/keyboards/xelus/rs108/info.json @@ -96,25 +96,25 @@ {"matrix": [5, 8], "x": 18.5, "y": 2.25}, {"matrix": [4, 9], "x": 19.5, "y": 2.25}, {"matrix": [5, 9], "x": 20.5, "y": 2.25}, - {"matrix": [6, 0], "x": 21.5, "y": 2.25, "h": 2}, - - {"matrix": [7, 0], "x": 0, "y": 3.25, "w": 1.75}, - {"matrix": [6, 1], "x": 1.75, "y": 3.25}, - {"matrix": [7, 1], "x": 2.75, "y": 3.25}, - {"matrix": [6, 2], "x": 3.75, "y": 3.25}, - {"matrix": [7, 2], "x": 4.75, "y": 3.25}, - {"matrix": [6, 3], "x": 5.75, "y": 3.25}, - {"matrix": [7, 3], "x": 6.75, "y": 3.25}, - {"matrix": [6, 4], "x": 7.75, "y": 3.25}, - {"matrix": [7, 4], "x": 8.75, "y": 3.25}, - {"matrix": [6, 5], "x": 9.75, "y": 3.25}, - {"matrix": [7, 5], "x": 10.75, "y": 3.25}, - {"matrix": [7, 6], "x": 11.75, "y": 3.25}, - {"matrix": [7, 8], "x": 12.75, "y": 3.25, "w": 2.25}, - - {"matrix": [6, 9], "x": 18.5, "y": 3.25}, - {"matrix": [7, 9], "x": 19.5, "y": 3.25}, - {"matrix": [6, 10], "x": 20.5, "y": 3.25}, + + {"matrix": [6, 0], "x": 0, "y": 3.25, "w": 1.75}, + {"matrix": [7, 0], "x": 1.75, "y": 3.25}, + {"matrix": [6, 1], "x": 2.75, "y": 3.25}, + {"matrix": [7, 1], "x": 3.75, "y": 3.25}, + {"matrix": [6, 2], "x": 4.75, "y": 3.25}, + {"matrix": [7, 2], "x": 5.75, "y": 3.25}, + {"matrix": [6, 3], "x": 6.75, "y": 3.25}, + {"matrix": [7, 3], "x": 7.75, "y": 3.25}, + {"matrix": [6, 4], "x": 8.75, "y": 3.25}, + {"matrix": [7, 4], "x": 9.75, "y": 3.25}, + {"matrix": [6, 5], "x": 10.75, "y": 3.25}, + {"matrix": [7, 5], "x": 11.75, "y": 3.25}, + {"matrix": [7, 6], "x": 12.75, "y": 3.25, "w": 2.25}, + + {"matrix": [7, 8], "x": 18.5, "y": 3.25}, + {"matrix": [6, 9], "x": 19.5, "y": 3.25}, + {"matrix": [7, 9], "x": 20.5, "y": 3.25}, + {"matrix": [6, 10], "x": 21.5, "y": 2.25, "h": 2}, {"matrix": [8, 0], "x": 0, "y": 4.25, "w": 2.25}, {"matrix": [9, 0], "x": 2.25, "y": 4.25}, @@ -134,23 +134,23 @@ {"matrix": [9, 8], "x": 18.5, "y": 4.25}, {"matrix": [8, 9], "x": 19.5, "y": 4.25}, {"matrix": [9, 9], "x": 20.5, "y": 4.25}, - {"matrix": [10, 0], "x": 21.5, "y": 4.25, "h": 2}, - - {"matrix": [11, 0], "x": 0, "y": 5.25, "w": 1.25}, - {"matrix": [10, 1], "x": 1.25, "y": 5.25, "w": 1.25}, - {"matrix": [11, 2], "x": 2.5, "y": 5.25, "w": 1.25}, - {"matrix": [11, 4], "x": 3.75, "y": 5.25, "w": 6.25}, - {"matrix": [10, 5], "x": 10, "y": 5.25, "w": 1.25}, - {"matrix": [10, 6], "x": 11.25, "y": 5.25, "w": 1.25}, - {"matrix": [11, 6], "x": 12.5, "y": 5.25, "w": 1.25}, - {"matrix": [10, 7], "x": 13.75, "y": 5.25, "w": 1.25}, - - {"matrix": [11, 7], "x": 15.25, "y": 5.25}, - {"matrix": [10, 8], "x": 16.25, "y": 5.25}, - {"matrix": [10, 9], "x": 17.25, "y": 5.25}, - - {"matrix": [11, 9], "x": 18.5, "y": 5.25, "w": 2}, - {"matrix": [10, 10], "x": 20.5, "y": 5.25} + + {"matrix": [10, 0], "x": 0, "y": 5.25, "w": 1.25}, + {"matrix": [11, 0], "x": 1.25, "y": 5.25, "w": 1.25}, + {"matrix": [10, 1], "x": 2.5, "y": 5.25, "w": 1.25}, + {"matrix": [11, 2], "x": 3.75, "y": 5.25, "w": 6.25}, + {"matrix": [11, 4], "x": 10, "y": 5.25, "w": 1.25}, + {"matrix": [10, 5], "x": 11.25, "y": 5.25, "w": 1.25}, + {"matrix": [10, 6], "x": 12.5, "y": 5.25, "w": 1.25}, + {"matrix": [11, 6], "x": 13.75, "y": 5.25, "w": 1.25}, + {"matrix": [10, 7], "x": 15.25, "y": 5.25}, + + {"matrix": [11, 7], "x": 16.25, "y": 5.25}, + {"matrix": [10, 8], "x": 17.25, "y": 5.25}, + {"matrix": [10, 9], "x": 18.5, "y": 5.25, "w": 2}, + + {"matrix": [11, 9], "x": 20.5, "y": 5.25}, + {"matrix": [10, 10], "x": 21.5, "y": 4.25, "h": 2} ] } } diff --git a/keyboards/xiudi/xd75/keymaps/bramver/keymap.c b/keyboards/xiudi/xd75/keymaps/bramver/keymap.c index f44adaf76862..960ef3ff1c78 100644 --- a/keyboards/xiudi/xd75/keymaps/bramver/keymap.c +++ b/keyboards/xiudi/xd75/keymaps/bramver/keymap.c @@ -85,7 +85,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { [_EMOJIFY] = LAYOUT_ortho_5x15( TO(0) , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , QK_BOOT, _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______, - _______ , X(CELE) , X(PRAY) , X(NAIL) , X(OK) , X(THNK) , _______ , _______ , _______ , X(UNAM) , X(HEYE) , X(COOL) , X(EYES) , X(SMIR) , _______, + _______ , UM(CELE), UM(PRAY), UM(NAIL), UM(OK) , UM(THNK), _______ , _______ , _______ , UM(UNAM), UM(HEYE), UM(COOL), UM(EYES), UM(SMIR), _______, _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______, _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ , _______ ) diff --git a/keyboards/xiudi/xd75/keymaps/bramver/readme.md b/keyboards/xiudi/xd75/keymaps/bramver/readme.md index a8ef38703bf9..cd1a78936e3e 100644 --- a/keyboards/xiudi/xd75/keymaps/bramver/readme.md +++ b/keyboards/xiudi/xd75/keymaps/bramver/readme.md @@ -37,7 +37,7 @@ _RAISE _EMOJIFY | TO(0) | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | RESET | | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | - | _______ | X(CELE) | X(PRAY) | X(NAIL) | X(OK) | X(THNK) | _______ | _______ | _______ | X(UNAM) | X(HEYE) | X(COOL) | X(EYES) | X(SMIR) | _______ | + | _______ | UM(CELE) | UM(PRAY) | UM(NAIL) | UM(OK) | UM(THNK) | _______ | _______ | _______ | UM(UNAM) | UM(HEYE) | UM(COOL) | UM(EYES) | UM(SMIR) | _______ | | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | _______ | ``` \ No newline at end of file diff --git a/keyboards/xiudi/xd75/keymaps/minna/keymap.c b/keyboards/xiudi/xd75/keymaps/minna/keymap.c index d3ff7557be1e..535c870ff7b0 100644 --- a/keyboards/xiudi/xd75/keymaps/minna/keymap.c +++ b/keyboards/xiudi/xd75/keymaps/minna/keymap.c @@ -50,7 +50,7 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { KC_TAB, KC_NO, KC_Q, KC_W, KC_E, KC_R, KC_T, KC_Y, KC_U, KC_I, KC_O, KC_P, FI_ARNG, FI_DIAE, KC_ENT, KC_CAPS, KC_NO, KC_A, KC_S, KC_D, KC_F, KC_G, KC_H, KC_J, KC_K, KC_L, FI_ODIA, FI_ADIA, FI_QUOT, KC_NO, KC_LSFT, FI_LABK, KC_Z, KC_X, KC_C, KC_V, KC_B, KC_N, KC_M, KC_COMM, KC_DOT, FI_MINS, KC_RSFT, KC_UP, KC_NO, - KC_LCTL, MO(1), KC_LGUI, KC_LALT, XP(BEER, BEERS), KC_SPC, KC_NO, KC_SPC, KC_NO, KC_RALT, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), + KC_LCTL, MO(1), KC_LGUI, KC_LALT, UP(BEER, BEERS), KC_SPC, KC_NO, KC_SPC, KC_NO, KC_RALT, KC_APP, KC_RCTL, KC_LEFT, KC_DOWN, KC_RGHT), /* * ┌────┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ diff --git a/keyboards/yoichiro/lunakey_mini/config.h b/keyboards/yoichiro/lunakey_mini/config.h index 8040e082a372..9c2fd0d8eff4 100644 --- a/keyboards/yoichiro/lunakey_mini/config.h +++ b/keyboards/yoichiro/lunakey_mini/config.h @@ -19,7 +19,6 @@ along with this program. If not, see . #define RGBLED_NUM 12 #define RGBLIGHT_SPLIT - #define RGBLED_SPLIT { 6, 6 } #define RGBLIGHT_LED_MAP { 0, 1, 2, 3, 4, 5, \ 11, 10, 9, 8, 7, 6 } #define RGBLIGHT_HUE_STEP 8 diff --git a/keyboards/yoichiro/lunakey_mini/info.json b/keyboards/yoichiro/lunakey_mini/info.json index 1347f73cb080..c255c431c225 100644 --- a/keyboards/yoichiro/lunakey_mini/info.json +++ b/keyboards/yoichiro/lunakey_mini/info.json @@ -16,6 +16,9 @@ "split": { "soft_serial_pin": "D2" }, + "rgblight": { + "split_count": [6, 6] + }, "ws2812": { "pin": "D3" }, diff --git a/keyboards/yushakobo/navpad/10_helix_r/config.h b/keyboards/yushakobo/navpad/10_helix_r/config.h index 95c70244a419..fd88d5eab695 100644 --- a/keyboards/yushakobo/navpad/10_helix_r/config.h +++ b/keyboards/yushakobo/navpad/10_helix_r/config.h @@ -27,7 +27,6 @@ along with this program. If not, see . 34, 35, 36, 37, 38, 39, 40 } # define RGBLED_NUM 9+32 -# define RGBLED_SPLIT { 9, 32 } # define RGBLIGHT_HUE_STEP 8 # define RGBLIGHT_SAT_STEP 8 # define RGBLIGHT_VAL_STEP 8 diff --git a/keyboards/yushakobo/navpad/10_helix_r/info.json b/keyboards/yushakobo/navpad/10_helix_r/info.json index f086173867cb..9c51e8ad746e 100644 --- a/keyboards/yushakobo/navpad/10_helix_r/info.json +++ b/keyboards/yushakobo/navpad/10_helix_r/info.json @@ -38,7 +38,8 @@ "pin": "D3" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [9, 32] }, "processor": "atmega32u4", "bootloader": "caterina", diff --git a/keyboards/zvecr/split_blackpill/config.h b/keyboards/zvecr/split_blackpill/config.h index 3cb23cdcc58f..ca2efbedc292 100644 --- a/keyboards/zvecr/split_blackpill/config.h +++ b/keyboards/zvecr/split_blackpill/config.h @@ -21,7 +21,6 @@ #define SELECT_SOFT_SERIAL_SPEED 0 #define RGBLED_NUM 24 -#define RGBLED_SPLIT { 12, 12 } #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/zvecr/split_blackpill/info.json b/keyboards/zvecr/split_blackpill/info.json index f657556db9a7..a4265c688b30 100644 --- a/keyboards/zvecr/split_blackpill/info.json +++ b/keyboards/zvecr/split_blackpill/info.json @@ -25,6 +25,9 @@ } } }, + "rgblight": { + "split_count": [12, 12] + }, "ws2812": { "pin": "B4", "driver": "pwm" diff --git a/keyboards/zvecr/zv48/config.h b/keyboards/zvecr/zv48/config.h index 25caa13057d5..e18d3bfb9996 100644 --- a/keyboards/zvecr/zv48/config.h +++ b/keyboards/zvecr/zv48/config.h @@ -22,7 +22,6 @@ #define SERIAL_USART_SPEED 921600 #define RGBLED_NUM 48 -#define RGBLED_SPLIT {24, 24} #define RGBLIGHT_EFFECT_BREATHING #define RGBLIGHT_EFFECT_RAINBOW_MOOD #define RGBLIGHT_EFFECT_RAINBOW_SWIRL diff --git a/keyboards/zvecr/zv48/info.json b/keyboards/zvecr/zv48/info.json index 942a089b649e..b0536d928484 100644 --- a/keyboards/zvecr/zv48/info.json +++ b/keyboards/zvecr/zv48/info.json @@ -23,7 +23,8 @@ "driver": "pwm" }, "rgblight": { - "max_brightness": 120 + "max_brightness": 120, + "split_count": [24, 24] }, "split": { "soft_serial_pin": "B6", diff --git a/layouts/community/60_iso/bifbofii/keymap.c b/layouts/community/60_iso/bifbofii/keymap.c index d9d7383c3d55..890bdb4c5692 100755 --- a/layouts/community/60_iso/bifbofii/keymap.c +++ b/layouts/community/60_iso/bifbofii/keymap.c @@ -123,9 +123,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { */ [UNICODE] = LAYOUT_60_iso( _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_BSPC, - _______, _______, _______, X(EUR), _______, _______, _______, XP(SUE, BUE), _______, XP(SOE, BOE), _______, _______, _______, - KC_TRNS, XP(SAE, BAE), X(SS), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ENT, - KC_LSFT, _______, _______, _______, X(CPR), _______, _______, _______, _______, _______, _______, _______, KC_RSFT, + _______, _______, _______, UM(EUR), _______, _______, _______, UP(SUE, BUE), _______, UP(SOE, BOE), _______, _______, _______, + KC_TRNS, UP(SAE, BAE), UM(SS), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, KC_ENT, + KC_LSFT, _______, _______, _______, UM(CPR), _______, _______, _______, _______, _______, _______, _______, KC_RSFT, KC_LCTL, KC_LGUI, KC_LALT, KC_SPC, KC_RALT, KC_RGUI, KC_RCTL, _______ ), diff --git a/layouts/community/65_ansi_blocker/spidey3/keymap.c b/layouts/community/65_ansi_blocker/spidey3/keymap.c index 5f8080d4711c..81ee2bf3a7d6 100644 --- a/layouts/community/65_ansi_blocker/spidey3/keymap.c +++ b/layouts/community/65_ansi_blocker/spidey3/keymap.c @@ -32,10 +32,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { ), // Glyph Transformation [_GLYPH] = LAYOUT_65_ansi_blocker( - QK_BOOT, X(SAD), X(MEH), X(HAPPY), X(ANGRY), X(THUMBDN), X(THUMBUP), X(SPIDER), X_BUL, X(LOL), X(SURPRISE),X_DASH, SPI_GFLOCK, XXXXXXX, XXXXXXX, + QK_BOOT, UM(SAD), UM(MEH), UM(HAPPY), UM(ANGRY), UM(THUMBDN),UM(THUMBUP),UM(SPIDER), X_BUL, UM(LOL), UM(SURPRISE),X_DASH, SPI_GFLOCK, XXXXXXX, XXXXXXX, EE_CLR, SPI_NORMAL, SPI_WIDE, SPI_SCRIPT, SPI_BLOCKS, SPI_CIRCLE, SPI_SQUARE, SPI_PARENS, SPI_FRAKTR, SPI_BOLD, SPI_MATH, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, X(LARR), X(RARR), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, + XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, UM(LARR), UM(RARR), XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, _______, XXXXXXX, XXXXXXX, XXXXXXX ) }; diff --git a/layouts/community/75_ansi/spidey3/keymap.c b/layouts/community/75_ansi/spidey3/keymap.c index 5c2f6a150b81..4e251b41dbeb 100644 --- a/layouts/community/75_ansi/spidey3/keymap.c +++ b/layouts/community/75_ansi/spidey3/keymap.c @@ -24,10 +24,10 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { // FN [_FN] = LAYOUT_75_ansi( QK_BOOT, SPI_NORMAL, SPI_WIDE, SPI_SCRIPT, SPI_BLOCKS, SPI_CIRCLE, SPI_SQUARE, SPI_PARENS, SPI_FRAKTR, SPI_BOLD, SPI_MATH, XXXXXXX, SPI_GFLOCK, KC_SLEP, CH_SUSP, KC_PWR, - EE_CLR, X(SAD), X(MEH), X(HAPPY), X(ANGRY), X(THUMBDN), X(THUMBUP), X(SPIDER), X_BUL, X(LOL), X(SURPRISE),X_DASH, XXXXXXX, KC_PAUS, KC_SCRL, + EE_CLR, UM(SAD), UM(MEH), UM(HAPPY), UM(ANGRY), UM(THUMBDN),UM(THUMBUP),UM(SPIDER), X_BUL, UM(LOL), UM(SURPRISE),X_DASH, XXXXXXX, KC_PAUS, KC_SCRL, XXXXXXX, RGB_TOG, RGB_MOD, RGB_HUD, RGB_HUI, RGB_SAD, RGB_SAI, RGB_VAD, RGB_VAI, SPI_GLO, VK_TOGG, XXXXXXX, XXXXXXX, XXXXXXX, KC_BRIU, XXXXXXX, RGB_M_P, RGB_M_B, RGB_M_R, RGB_M_SW, RGB_M_SN, RGB_M_K, RGB_M_G, RGB_M_TW, UC_LINX, XXXXXXX, XXXXXXX, XXXXXXX, KC_BRID, - _______, XXXXXXX, UC_EMAC, UC_WINC, UC_NEXT, NK_TOGG, TG(_NUMPAD),UC_MAC, X(LARR), X(RARR), DB_TOGG, _______, KC_VOLU, KC_MUTE, + _______, XXXXXXX, UC_EMAC, UC_WINC, UC_NEXT, NK_TOGG, TG(_NUMPAD),UC_MAC, UM(LARR), UM(RARR), DB_TOGG, _______, KC_VOLU, KC_MUTE, _______, _______, _______, KC_MPLY, KC_ASST, _______, KC_CPNL, KC_MPRV, KC_VOLD, KC_MNXT ) }; diff --git a/layouts/community/ortho_4x12/bifbofii/keymap.c b/layouts/community/ortho_4x12/bifbofii/keymap.c index 7c25fed016f6..e7f427127ee0 100644 --- a/layouts/community/ortho_4x12/bifbofii/keymap.c +++ b/layouts/community/ortho_4x12/bifbofii/keymap.c @@ -146,9 +146,9 @@ const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = { * +-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+-----+ */ [UNICODE] = LAYOUT_ortho_4x12( - _______, _______, _______, X(EUR), _______, _______, _______, XP(SUE, BUE), _______, XP(SOE, BOE), _______, _______, - _______, XP(SAE, BAE), X(SS), _______, _______, _______, _______, _______, _______, _______, _______, _______, - _______, _______, _______, X(CPR), _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, UM(EUR), _______, _______, _______, UP(SUE, BUE), _______, UP(SOE, BOE), _______, _______, + _______, UP(SAE, BAE), UM(SS), _______, _______, _______, _______, _______, _______, _______, _______, _______, + _______, _______, _______, UM(CPR), _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______, _______ ), diff --git a/layouts/default/readme.md b/layouts/default/readme.md index 839028179648..a728d93d1a22 100644 --- a/layouts/default/readme.md +++ b/layouts/default/readme.md @@ -35,33 +35,33 @@ LAYOUT_60_ansi ``` ``` -LAYOUT_60_ansi_arrow_split_bs_7u_spc -┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ -│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ -├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ +LAYOUT_60_ansi_arrow +┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ +│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴┬───┬───┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ -├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴──┬───┼───┼───┤ -│ │ │ │ │ │ │ │ │ -└─────┴───┴─────┴───────────────────────────┴───┴───┴───┴───┘ +├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬───┼───┼───┤ +│ │ │ │ │ │ │ │ │ │ +└────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┘ ``` ``` -LAYOUT_60_ansi_arrow -┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ -│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ -├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ +LAYOUT_60_ansi_arrow_split_bs_7u_spc +┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┐ +│ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ +├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴┬───┬───┤ │ │ │ │ │ │ │ │ │ │ │ │ │ │ -├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴──┬┴──┬───┼───┼───┤ -│ │ │ │ │ │ │ │ │ │ -└────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┘ +├─────┬──┴┬──┴──┬┴───┴───┴───┴───┴───┴───┴──┬┴──┬───┼───┼───┤ +│ │ │ │ │ │ │ │ │ +└─────┴───┴─────┴───────────────────────────┴───┴───┴───┴───┘ ``` ``` @@ -925,6 +925,20 @@ LAYOUT_ergodox └───┴───┴───┘ └───┴───┴───┘ ``` +``` +LAYOUT_split_3x5_2 +┌───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┐ +│ │ │ │ │ │ │ │ │ │ │ │ +├───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┤ +│ │ │ │ │ │ │ │ │ │ │ │ +├───┼───┼───┼───┼───┤ ├───┼───┼───┼───┼───┤ +│ │ │ │ │ │ │ │ │ │ │ │ +└───┴───┴───┴───┴───┘ └───┴───┴───┴───┴───┘ + ┌───┬───┐ ┌───┬───┐ + │ │ │ │ │ │ + └───┴───┘ └───┴───┘ +``` + ``` LAYOUT_split_3x5_3 ┌───┬───┬───┬───┬───┐ ┌───┬───┬───┬───┬───┐ diff --git a/layouts/default/split_3x5_2/layout.json b/layouts/default/split_3x5_2/layout.json index 1b1c3d0001a1..db47180610b8 100644 --- a/layouts/default/split_3x5_2/layout.json +++ b/layouts/default/split_3x5_2/layout.json @@ -7,5 +7,5 @@ [{y:-0.25,x:2},"",{x:6},""], [{y:-0.875,x:1},"",{x:1},"",{x:4},"",{x:1},""], [{y:-0.875},"",{x:3},"",{x:2},"",{x:3},""], -[{y:-0.75,x:3.5},"",{x:3},""], +[{y:0.25},{x:3.5},"",{x:3},""], [{y:-0.75,x:4.5},"",{x:1},""] diff --git a/platforms/chibios/wait.c b/platforms/chibios/wait.c index 88cb5e6d549d..7fe6d477b8c9 100644 --- a/platforms/chibios/wait.c +++ b/platforms/chibios/wait.c @@ -21,7 +21,7 @@ #ifdef WAIT_US_TIMER void wait_us(uint16_t duration) { - static const GPTConfig gpt_cfg = {1000000, NULL, 0, 0}; /* 1MHz timer, no callback */ + static const GPTConfig gpt_cfg = {.frequency = 1000000}; /* 1MHz timer, no callback */ if (duration == 0) { duration = 1; diff --git a/quantum/action.c b/quantum/action.c deleted file mode 100644 index a45e70c55729..000000000000 --- a/quantum/action.c +++ /dev/null @@ -1,1215 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -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 . -*/ -#include - -#include "host.h" -#include "keycode.h" -#include "keyboard.h" -#include "mousekey.h" -#include "programmable_button.h" -#include "command.h" -#include "led.h" -#include "action_layer.h" -#include "action_tapping.h" -#include "action_util.h" -#include "action.h" -#include "wait.h" -#include "keycode_config.h" -#include "debug.h" -#include "quantum.h" - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef POINTING_DEVICE_ENABLE -# include "pointing_device.h" -#endif - -#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) && defined(SWAP_HANDS_ENABLE) -# include "encoder.h" -#endif - -int tp_buttons; - -#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) -int retro_tapping_counter = 0; -#endif - -#if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) -# include "process_auto_shift.h" -#endif - -#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY -__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { - return false; -} -#endif - -#ifdef RETRO_TAPPING_PER_KEY -__attribute__((weak)) bool get_retro_tapping(uint16_t keycode, keyrecord_t *record) { - return false; -} -#endif - -/** \brief Called to execute an action. - * - * FIXME: Needs documentation. - */ -void action_exec(keyevent_t event) { - if (IS_EVENT(event)) { - ac_dprintf("\n---- action_exec: start -----\n"); - ac_dprintf("EVENT: "); - debug_event(event); - ac_dprintf("\n"); -#if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) - retro_tapping_counter++; -#endif - } - - if (event.pressed) { - // clear the potential weak mods left by previously pressed keys - clear_weak_mods(); - } - -#ifdef SWAP_HANDS_ENABLE - // Swap hands handles both keys and encoders, if ENCODER_MAP_ENABLE is defined. - if (IS_EVENT(event)) { - process_hand_swap(&event); - } -#endif - - keyrecord_t record = {.event = event}; - -#ifndef NO_ACTION_ONESHOT - if (keymap_config.oneshot_enable) { -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - if (has_oneshot_layer_timed_out()) { - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); - } - if (has_oneshot_mods_timed_out()) { - clear_oneshot_mods(); - } -# ifdef SWAP_HANDS_ENABLE - if (has_oneshot_swaphands_timed_out()) { - clear_oneshot_swaphands(); - } -# endif -# endif - } -#endif - -#ifndef NO_ACTION_TAPPING -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - if (event.pressed) { - retroshift_poll_time(&event); - } -# endif - if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { - action_tapping_process(record); - } -#else - if (IS_NOEVENT(record.event) || pre_process_record_quantum(&record)) { - process_record(&record); - } - if (IS_EVENT(record.event)) { - ac_dprintf("processed: "); - debug_record(record); - dprintln(); - } -#endif -} - -#ifdef SWAP_HANDS_ENABLE -extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; -# ifdef ENCODER_MAP_ENABLE -extern const uint8_t PROGMEM encoder_hand_swap_config[NUM_ENCODERS]; -# endif // ENCODER_MAP_ENABLE - -bool swap_hands = false; -bool swap_held = false; - -bool should_swap_hands(size_t index, uint8_t *swap_state, bool pressed) { - size_t array_index = index / (CHAR_BIT); - size_t bit_index = index % (CHAR_BIT); - uint8_t bit_val = 1 << bit_index; - bool do_swap = pressed ? swap_hands : swap_state[array_index] & bit_val; - return do_swap; -} - -void set_swap_hands_state(size_t index, uint8_t *swap_state, bool on) { - size_t array_index = index / (CHAR_BIT); - size_t bit_index = index % (CHAR_BIT); - uint8_t bit_val = 1 << bit_index; - if (on) { - swap_state[array_index] |= bit_val; - } else { - swap_state[array_index] &= ~bit_val; - } -} - -void swap_hands_on(void) { - swap_hands = true; -} - -void swap_hands_off(void) { - swap_hands = false; -} - -void swap_hands_toggle(void) { - swap_hands = !swap_hands; -} - -bool is_swap_hands_on(void) { - return swap_hands; -} - -/** \brief Process Hand Swap - * - * FIXME: Needs documentation. - */ -void process_hand_swap(keyevent_t *event) { - keypos_t pos = event->key; - if (IS_KEYEVENT(*event) && pos.row < MATRIX_ROWS && pos.col < MATRIX_COLS) { - static uint8_t matrix_swap_state[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)]; - size_t index = (size_t)(pos.row * MATRIX_COLS) + pos.col; - bool do_swap = should_swap_hands(index, matrix_swap_state, event->pressed); - if (do_swap) { - event->key.row = pgm_read_byte(&hand_swap_config[pos.row][pos.col].row); - event->key.col = pgm_read_byte(&hand_swap_config[pos.row][pos.col].col); - set_swap_hands_state(index, matrix_swap_state, true); - } else { - set_swap_hands_state(index, matrix_swap_state, false); - } - } -# ifdef ENCODER_MAP_ENABLE - else if (IS_ENCODEREVENT(*event) && (pos.row == KEYLOC_ENCODER_CW || pos.row == KEYLOC_ENCODER_CCW)) { - static uint8_t encoder_swap_state[((NUM_ENCODERS) + (CHAR_BIT)-1) / (CHAR_BIT)]; - size_t index = pos.col; - bool do_swap = should_swap_hands(index, encoder_swap_state, event->pressed); - if (do_swap) { - event->key.row = pos.row; - event->key.col = pgm_read_byte(&encoder_hand_swap_config[pos.col]); - set_swap_hands_state(index, encoder_swap_state, true); - } else { - set_swap_hands_state(index, encoder_swap_state, false); - } - } -# endif // ENCODER_MAP_ENABLE -} -#endif - -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) -bool disable_action_cache = false; - -void process_record_nocache(keyrecord_t *record) { - disable_action_cache = true; - process_record(record); - disable_action_cache = false; -} -#else -void process_record_nocache(keyrecord_t *record) { - process_record(record); -} -#endif - -__attribute__((weak)) bool process_record_quantum(keyrecord_t *record) { - return true; -} - -__attribute__((weak)) void post_process_record_quantum(keyrecord_t *record) {} - -#ifndef NO_ACTION_TAPPING -/** \brief Allows for handling tap-hold actions immediately instead of waiting for TAPPING_TERM or another keypress. - * - * FIXME: Needs documentation. - */ -void process_record_tap_hint(keyrecord_t *record) { - if (!IS_KEYEVENT(record->event)) { - return; - } - - action_t action = layer_switch_get_action(record->event.key); - - switch (action.kind.id) { -# ifdef SWAP_HANDS_ENABLE - case ACT_SWAP_HANDS: - switch (action.swap.code) { - case OP_SH_ONESHOT: - break; - case OP_SH_TAP_TOGGLE: - default: - swap_hands = !swap_hands; - swap_held = true; - } - break; -# endif - } -} -#endif - -/** \brief Take a key event (key press or key release) and processes it. - * - * FIXME: Needs documentation. - */ -void process_record(keyrecord_t *record) { - if (IS_NOEVENT(record->event)) { - return; - } - - if (!process_record_quantum(record)) { -#ifndef NO_ACTION_ONESHOT - if (is_oneshot_layer_active() && record->event.pressed && keymap_config.oneshot_enable) { - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); - } -#endif - return; - } - - process_record_handler(record); - post_process_record_quantum(record); -} - -void process_record_handler(keyrecord_t *record) { -#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE) - action_t action; - if (record->keycode) { - action = action_for_keycode(record->keycode); - } else { - action = store_or_get_action(record->event.pressed, record->event.key); - } -#else - action_t action = store_or_get_action(record->event.pressed, record->event.key); -#endif - ac_dprintf("ACTION: "); - debug_action(action); -#ifndef NO_ACTION_LAYER - ac_dprintf(" layer_state: "); - layer_debug(); - ac_dprintf(" default_layer_state: "); - default_layer_debug(); -#endif - ac_dprintf("\n"); - - process_action(record, action); -} - -/** - * @brief handles all the messy mouse stuff - * - * Handles all the edgecases and special stuff that is needed for coexistense - * of the multiple mouse subsystems. - * - * @param mouse_keycode[in] uint8_t mouse keycode - * @param pressed[in] bool - */ - -void register_mouse(uint8_t mouse_keycode, bool pressed) { -#ifdef MOUSEKEY_ENABLE - // if mousekeys is enabled, let it do the brunt of the work - if (pressed) { - mousekey_on(mouse_keycode); - } else { - mousekey_off(mouse_keycode); - } - // should mousekeys send report, or does something else handle this? - switch (mouse_keycode) { -# if defined(PS2_MOUSE_ENABLE) || defined(POINTING_DEVICE_ENABLE) - case KC_MS_BTN1 ... KC_MS_BTN8: - // let pointing device handle the buttons - // expand if/when it handles more of the code -# if defined(POINTING_DEVICE_ENABLE) - pointing_device_keycode_handler(mouse_keycode, pressed); -# endif - break; -# endif - default: - mousekey_send(); - break; - } -#elif defined(POINTING_DEVICE_ENABLE) - // if mousekeys isn't enabled, and pointing device is enabled, then - // let pointing device do all the heavy lifting, then - if (IS_MOUSE_KEYCODE(mouse_keycode)) { - pointing_device_keycode_handler(mouse_keycode, pressed); - } -#endif - -#ifdef PS2_MOUSE_ENABLE - // make sure that ps2 mouse has button report synced - if (KC_MS_BTN1 <= mouse_keycode && mouse_keycode <= KC_MS_BTN3) { - uint8_t tmp_button_msk = MOUSE_BTN_MASK(mouse_keycode - KC_MS_BTN1); - tp_buttons = pressed ? tp_buttons | tmp_button_msk : tp_buttons & ~tmp_button_msk; - } -#endif -} - -/** \brief Take an action and processes it. - * - * FIXME: Needs documentation. - */ -void process_action(keyrecord_t *record, action_t action) { - keyevent_t event = record->event; -#ifndef NO_ACTION_TAPPING - uint8_t tap_count = record->tap.count; -#endif - -#ifndef NO_ACTION_ONESHOT - bool do_release_oneshot = false; - // notice we only clear the one shot layer if the pressed key is not a modifier. - if (is_oneshot_layer_active() && event.pressed && - (action.kind.id == ACT_USAGE || !(IS_MODIFIER_KEYCODE(action.key.code) -# ifndef NO_ACTION_TAPPING - || (tap_count == 0 && (action.kind.id == ACT_LMODS_TAP || action.kind.id == ACT_RMODS_TAP)) -# endif - )) -# ifdef SWAP_HANDS_ENABLE - && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT) -# endif - && keymap_config.oneshot_enable) { - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); - do_release_oneshot = !is_oneshot_layer_active(); - } -#endif - - switch (action.kind.id) { - /* Key and Mods */ - case ACT_LMODS: - case ACT_RMODS: { - uint8_t mods = (action.kind.id == ACT_LMODS) ? action.key.mods : action.key.mods << 4; - if (event.pressed) { - if (mods) { - if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) { - // e.g. LSFT(KC_LEFT_GUI): we don't want the LSFT to be weak as it would make it useless. - // This also makes LSFT(KC_LEFT_GUI) behave exactly the same as LGUI(KC_LEFT_SHIFT). - // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). - add_mods(mods); - } else { - add_weak_mods(mods); - } - send_keyboard_report(); - } - register_code(action.key.code); - } else { - unregister_code(action.key.code); - if (mods) { - if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) { - del_mods(mods); - } else { - del_weak_mods(mods); - } - send_keyboard_report(); - } - } - } break; - case ACT_LMODS_TAP: - case ACT_RMODS_TAP: { -#ifndef NO_ACTION_TAPPING - uint8_t mods = (action.kind.id == ACT_LMODS_TAP) ? action.key.mods : action.key.mods << 4; - switch (action.layer_tap.code) { -# ifndef NO_ACTION_ONESHOT - case MODS_ONESHOT: - // Oneshot modifier - if (!keymap_config.oneshot_enable) { - if (event.pressed) { - if (mods) { - if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) { - // e.g. LSFT(KC_LGUI): we don't want the LSFT to be weak as it would make it useless. - // This also makes LSFT(KC_LGUI) behave exactly the same as LGUI(KC_LSFT). - // Same applies for some keys like KC_MEH which are declared as MEH(KC_NO). - add_mods(mods); - } else { - add_weak_mods(mods); - } - send_keyboard_report(); - } - register_code(action.key.code); - } else { - unregister_code(action.key.code); - if (mods) { - if (IS_MODIFIER_KEYCODE(action.key.code) || action.key.code == KC_NO) { - del_mods(mods); - } else { - del_weak_mods(mods); - } - send_keyboard_report(); - } - } - } else { - if (event.pressed) { - if (tap_count == 0) { - // Not a tap, but a hold: register the held mod - ac_dprintf("MODS_TAP: Oneshot: 0\n"); - register_mods(mods); - } else if (tap_count == 1) { - ac_dprintf("MODS_TAP: Oneshot: start\n"); - add_oneshot_mods(mods); -# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 - } else if (tap_count == ONESHOT_TAP_TOGGLE) { - ac_dprintf("MODS_TAP: Toggling oneshot"); - register_mods(mods); - del_oneshot_mods(mods); - add_oneshot_locked_mods(mods); -# endif - } - } else { - if (tap_count == 0) { - // Release hold: unregister the held mod and its variants - unregister_mods(mods); - del_oneshot_mods(mods); - del_oneshot_locked_mods(mods); -# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 - } else if (tap_count == 1 && (mods & get_mods())) { - unregister_mods(mods); - del_oneshot_mods(mods); - del_oneshot_locked_mods(mods); -# endif - } - } - } - break; -# endif - case MODS_TAP_TOGGLE: - if (event.pressed) { - if (tap_count <= TAPPING_TOGGLE) { - register_mods(mods); - } - } else { - if (tap_count < TAPPING_TOGGLE) { - unregister_mods(mods); - } - } - break; - default: - if (event.pressed) { - if (tap_count > 0) { -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - if ( -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - get_hold_on_other_key_press(get_event_keycode(record->event, false), record) && -# endif - record->tap.interrupted) { - ac_dprintf("mods_tap: tap: cancel: add_mods\n"); - // ad hoc: set 0 to cancel tap - record->tap.count = 0; - register_mods(mods); - } else -# endif - { - ac_dprintf("MODS_TAP: Tap: register_code\n"); - register_code(action.key.code); - } - } else { - ac_dprintf("MODS_TAP: No tap: add_mods\n"); - register_mods(mods); - } - } else { - if (tap_count > 0) { - ac_dprintf("MODS_TAP: Tap: unregister_code\n"); - if (action.layer_tap.code == KC_CAPS_LOCK) { - wait_ms(TAP_HOLD_CAPS_DELAY); - } else { - wait_ms(TAP_CODE_DELAY); - } - unregister_code(action.key.code); - } else { - ac_dprintf("MODS_TAP: No tap: add_mods\n"); - unregister_mods(mods); - } - } - break; - } -#endif // NO_ACTION_TAPPING - } break; -#ifdef EXTRAKEY_ENABLE - /* other HID usage */ - case ACT_USAGE: - switch (action.usage.page) { - case PAGE_SYSTEM: - host_system_send(event.pressed ? action.usage.code : 0); - break; - case PAGE_CONSUMER: - host_consumer_send(event.pressed ? action.usage.code : 0); - break; - } - break; -#endif // EXTRAKEY_ENABLE - /* Mouse key */ - case ACT_MOUSEKEY: - register_mouse(action.key.code, event.pressed); - break; -#ifndef NO_ACTION_LAYER - case ACT_LAYER: - if (action.layer_bitop.on == 0) { - /* Default Layer Bitwise Operation */ - if (!event.pressed) { - uint8_t shift = action.layer_bitop.part * 4; - layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; - layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; - switch (action.layer_bitop.op) { - case OP_BIT_AND: - default_layer_and(bits | mask); - break; - case OP_BIT_OR: - default_layer_or(bits | mask); - break; - case OP_BIT_XOR: - default_layer_xor(bits | mask); - break; - case OP_BIT_SET: - default_layer_set(bits | mask); - break; - } - } - } else { - /* Layer Bitwise Operation */ - if (event.pressed ? (action.layer_bitop.on & ON_PRESS) : (action.layer_bitop.on & ON_RELEASE)) { - uint8_t shift = action.layer_bitop.part * 4; - layer_state_t bits = ((layer_state_t)action.layer_bitop.bits) << shift; - layer_state_t mask = (action.layer_bitop.xbit) ? ~(((layer_state_t)0xf) << shift) : 0; - switch (action.layer_bitop.op) { - case OP_BIT_AND: - layer_and(bits | mask); - break; - case OP_BIT_OR: - layer_or(bits | mask); - break; - case OP_BIT_XOR: - layer_xor(bits | mask); - break; - case OP_BIT_SET: - layer_state_set(bits | mask); - break; - } - } - } - break; - case ACT_LAYER_MODS: - if (event.pressed) { - layer_on(action.layer_mods.layer); - register_mods(action.layer_mods.mods); - } else { - unregister_mods(action.layer_mods.mods); - layer_off(action.layer_mods.layer); - } - break; - case ACT_LAYER_TAP: - case ACT_LAYER_TAP_EXT: - switch (action.layer_tap.code) { -# ifndef NO_ACTION_TAPPING - case OP_TAP_TOGGLE: - /* tap toggle */ - if (event.pressed) { - if (tap_count < TAPPING_TOGGLE) { - layer_invert(action.layer_tap.val); - } - } else { - if (tap_count <= TAPPING_TOGGLE) { - layer_invert(action.layer_tap.val); - } - } - break; -# endif - case OP_ON_OFF: - event.pressed ? layer_on(action.layer_tap.val) : layer_off(action.layer_tap.val); - break; - case OP_OFF_ON: - event.pressed ? layer_off(action.layer_tap.val) : layer_on(action.layer_tap.val); - break; - case OP_SET_CLEAR: - event.pressed ? layer_move(action.layer_tap.val) : layer_clear(); - break; -# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - case OP_ONESHOT: - // Oneshot modifier - if (!keymap_config.oneshot_enable) { - if (event.pressed) { - layer_on(action.layer_tap.val); - } else { - layer_off(action.layer_tap.val); - } - } else { -# if defined(ONESHOT_TAP_TOGGLE) && ONESHOT_TAP_TOGGLE > 1 - do_release_oneshot = false; - if (event.pressed) { - if (get_oneshot_layer_state() == ONESHOT_TOGGLED) { - reset_oneshot_layer(); - layer_off(action.layer_tap.val); - break; - } else if (tap_count < ONESHOT_TAP_TOGGLE) { - layer_on(action.layer_tap.val); - set_oneshot_layer(action.layer_tap.val, ONESHOT_START); - } - } else { - if (tap_count >= ONESHOT_TAP_TOGGLE) { - reset_oneshot_layer(); - set_oneshot_layer(action.layer_tap.val, ONESHOT_TOGGLED); - } else { - clear_oneshot_layer_state(ONESHOT_PRESSED); - } - } -# else - if (event.pressed) { - layer_on(action.layer_tap.val); - set_oneshot_layer(action.layer_tap.val, ONESHOT_START); - } else { - clear_oneshot_layer_state(ONESHOT_PRESSED); - if (tap_count > 1) { - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); - } - } -# endif - } -# else // NO_ACTION_ONESHOT && NO_ACTION_TAPPING - if (event.pressed) { - layer_on(action.layer_tap.val); - } else { - layer_off(action.layer_tap.val); - } -# endif // !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - break; - default: -# ifndef NO_ACTION_TAPPING /* tap key */ - if (event.pressed) { - if (tap_count > 0) { - ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n"); - register_code(action.layer_tap.code); - } else { - ac_dprintf("KEYMAP_TAP_KEY: No tap: On on press\n"); - layer_on(action.layer_tap.val); - } - } else { - if (tap_count > 0) { - ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n"); - if (action.layer_tap.code == KC_CAPS_LOCK) { - wait_ms(TAP_HOLD_CAPS_DELAY); - } else { - wait_ms(TAP_CODE_DELAY); - } - unregister_code(action.layer_tap.code); - } else { - ac_dprintf("KEYMAP_TAP_KEY: No tap: Off on release\n"); - layer_off(action.layer_tap.val); - } - } -# else - if (event.pressed) { - ac_dprintf("KEYMAP_TAP_KEY: Tap: register_code\n"); - register_code(action.layer_tap.code); - } else { - ac_dprintf("KEYMAP_TAP_KEY: Tap: unregister_code\n"); - if (action.layer_tap.code == KC_CAPS) { - wait_ms(TAP_HOLD_CAPS_DELAY); - } else { - wait_ms(TAP_CODE_DELAY); - } - unregister_code(action.layer_tap.code); - } -# endif - break; - } - break; -#endif // NO_ACTION_LAYER - -#ifdef SWAP_HANDS_ENABLE - case ACT_SWAP_HANDS: - switch (action.swap.code) { - case OP_SH_TOGGLE: - if (event.pressed) { - swap_hands = !swap_hands; - } - break; - case OP_SH_ON_OFF: - swap_hands = event.pressed; - break; - case OP_SH_OFF_ON: - swap_hands = !event.pressed; - break; - case OP_SH_ON: - if (!event.pressed) { - swap_hands = true; - } - break; - case OP_SH_OFF: - if (!event.pressed) { - swap_hands = false; - } - break; -# ifndef NO_ACTION_ONESHOT - case OP_SH_ONESHOT: - if (event.pressed) { - set_oneshot_swaphands(); - } else { - release_oneshot_swaphands(); - } - break; -# endif - -# ifndef NO_ACTION_TAPPING - case OP_SH_TAP_TOGGLE: - /* tap toggle */ - - if (event.pressed) { - if (swap_held) { - swap_held = false; - } else { - swap_hands = !swap_hands; - } - } else { - if (tap_count < TAPPING_TOGGLE) { - swap_hands = !swap_hands; - } - } - break; - default: - /* tap key */ - if (tap_count > 0) { - if (swap_held) { - swap_hands = !swap_hands; // undo hold set up in _tap_hint - swap_held = false; - } - if (event.pressed) { - register_code(action.swap.code); - } else { - wait_ms(TAP_CODE_DELAY); - unregister_code(action.swap.code); - *record = (keyrecord_t){}; // hack: reset tap mode - } - } else { - if (swap_held && !event.pressed) { - swap_hands = !swap_hands; // undo hold set up in _tap_hint - swap_held = false; - } - } -# endif - } -#endif - default: - break; - } - -#ifndef NO_ACTION_LAYER - // if this event is a layer action, update the leds - switch (action.kind.id) { - case ACT_LAYER: - case ACT_LAYER_MODS: -# ifndef NO_ACTION_TAPPING - case ACT_LAYER_TAP: - case ACT_LAYER_TAP_EXT: -# endif - led_set(host_keyboard_leds()); - break; - default: - break; - } -#endif - -#ifndef NO_ACTION_TAPPING -# if defined(RETRO_TAPPING) || defined(RETRO_TAPPING_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) - if (!is_tap_action(action)) { - retro_tapping_counter = 0; - } else { - if (event.pressed) { - if (tap_count > 0) { - retro_tapping_counter = 0; - } - } else { - if (tap_count > 0) { - retro_tapping_counter = 0; - } else { - if ( -# ifdef RETRO_TAPPING_PER_KEY - get_retro_tapping(get_event_keycode(record->event, false), record) && -# endif - retro_tapping_counter == 2) { -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - process_auto_shift(action.layer_tap.code, record); -# else - tap_code(action.layer_tap.code); -# endif - } - retro_tapping_counter = 0; - } - } - } -# endif -#endif - -#ifdef SWAP_HANDS_ENABLE -# ifndef NO_ACTION_ONESHOT - if (event.pressed && !(action.kind.id == ACT_SWAP_HANDS && action.swap.code == OP_SH_ONESHOT)) { - use_oneshot_swaphands(); - } -# endif -#endif - -#ifndef NO_ACTION_ONESHOT - /* Because we switch layers after a oneshot event, we need to release the - * key before we leave the layer or no key up event will be generated. - */ - if (do_release_oneshot && !(get_oneshot_layer_state() & ONESHOT_PRESSED)) { - record->event.pressed = false; - layer_on(get_oneshot_layer()); - process_record(record); - layer_off(get_oneshot_layer()); - } -#endif -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -__attribute__((weak)) void register_code(uint8_t code) { - if (code == KC_NO) { - return; - -#ifdef LOCKING_SUPPORT_ENABLE - } else if (KC_LOCKING_CAPS_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - // Resync: ignore if caps lock already is on - if (host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK)) return; -# endif - add_key(KC_CAPS_LOCK); - send_keyboard_report(); - wait_ms(TAP_HOLD_CAPS_DELAY); - del_key(KC_CAPS_LOCK); - send_keyboard_report(); - - } else if (KC_LOCKING_NUM_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - if (host_keyboard_leds() & (1 << USB_LED_NUM_LOCK)) return; -# endif - add_key(KC_NUM_LOCK); - send_keyboard_report(); - wait_ms(100); - del_key(KC_NUM_LOCK); - send_keyboard_report(); - - } else if (KC_LOCKING_SCROLL_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - if (host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK)) return; -# endif - add_key(KC_SCROLL_LOCK); - send_keyboard_report(); - wait_ms(100); - del_key(KC_SCROLL_LOCK); - send_keyboard_report(); -#endif - - } else if (IS_BASIC_KEYCODE(code)) { - // TODO: should push command_proc out of this block? - if (command_proc(code)) return; - - // Force a new key press if the key is already pressed - // without this, keys with the same keycode, but different - // modifiers will be reported incorrectly, see issue #1708 - if (is_key_pressed(keyboard_report, code)) { - del_key(code); - send_keyboard_report(); - } - add_key(code); - send_keyboard_report(); - } else if (IS_MODIFIER_KEYCODE(code)) { - add_mods(MOD_BIT(code)); - send_keyboard_report(); - -#ifdef EXTRAKEY_ENABLE - } else if (IS_SYSTEM_KEYCODE(code)) { - host_system_send(KEYCODE2SYSTEM(code)); - } else if (IS_CONSUMER_KEYCODE(code)) { - host_consumer_send(KEYCODE2CONSUMER(code)); -#endif - - } else if (IS_MOUSE_KEYCODE(code)) { - register_mouse(code, true); - } -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -__attribute__((weak)) void unregister_code(uint8_t code) { - if (code == KC_NO) { - return; - -#ifdef LOCKING_SUPPORT_ENABLE - } else if (KC_LOCKING_CAPS_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - // Resync: ignore if caps lock already is off - if (!(host_keyboard_leds() & (1 << USB_LED_CAPS_LOCK))) return; -# endif - add_key(KC_CAPS_LOCK); - send_keyboard_report(); - del_key(KC_CAPS_LOCK); - send_keyboard_report(); - - } else if (KC_LOCKING_NUM_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - if (!(host_keyboard_leds() & (1 << USB_LED_NUM_LOCK))) return; -# endif - add_key(KC_NUM_LOCK); - send_keyboard_report(); - del_key(KC_NUM_LOCK); - send_keyboard_report(); - - } else if (KC_LOCKING_SCROLL_LOCK == code) { -# ifdef LOCKING_RESYNC_ENABLE - if (!(host_keyboard_leds() & (1 << USB_LED_SCROLL_LOCK))) return; -# endif - add_key(KC_SCROLL_LOCK); - send_keyboard_report(); - del_key(KC_SCROLL_LOCK); - send_keyboard_report(); -#endif - - } else if (IS_BASIC_KEYCODE(code)) { - del_key(code); - send_keyboard_report(); - } else if (IS_MODIFIER_KEYCODE(code)) { - del_mods(MOD_BIT(code)); - send_keyboard_report(); - -#ifdef EXTRAKEY_ENABLE - } else if (IS_SYSTEM_KEYCODE(code)) { - host_system_send(0); - } else if (IS_CONSUMER_KEYCODE(code)) { - host_consumer_send(0); -#endif - - } else if (IS_MOUSE_KEYCODE(code)) { - register_mouse(code, false); - } -} - -/** \brief Tap a keycode with a delay. - * - * \param code The basic keycode to tap. - * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. - */ -__attribute__((weak)) void tap_code_delay(uint8_t code, uint16_t delay) { - register_code(code); - for (uint16_t i = delay; i > 0; i--) { - wait_ms(1); - } - unregister_code(code); -} - -/** \brief Tap a keycode with the default delay. - * - * \param code The basic keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. - */ -__attribute__((weak)) void tap_code(uint8_t code) { - tap_code_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); -} - -/** \brief Adds the given physically pressed modifiers and sends a keyboard report immediately. - * - * \param mods A bitfield of modifiers to register. - */ -__attribute__((weak)) void register_mods(uint8_t mods) { - if (mods) { - add_mods(mods); - send_keyboard_report(); - } -} - -/** \brief Removes the given physically pressed modifiers and sends a keyboard report immediately. - * - * \param mods A bitfield of modifiers to unregister. - */ -__attribute__((weak)) void unregister_mods(uint8_t mods) { - if (mods) { - del_mods(mods); - send_keyboard_report(); - } -} - -/** \brief Adds the given weak modifiers and sends a keyboard report immediately. - * - * \param mods A bitfield of modifiers to register. - */ -__attribute__((weak)) void register_weak_mods(uint8_t mods) { - if (mods) { - add_weak_mods(mods); - send_keyboard_report(); - } -} - -/** \brief Removes the given weak modifiers and sends a keyboard report immediately. - * - * \param mods A bitfield of modifiers to unregister. - */ -__attribute__((weak)) void unregister_weak_mods(uint8_t mods) { - if (mods) { - del_weak_mods(mods); - send_keyboard_report(); - } -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void clear_keyboard(void) { - clear_mods(); - clear_keyboard_but_mods(); -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void clear_keyboard_but_mods(void) { - clear_keys(); - clear_keyboard_but_mods_and_keys(); -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void clear_keyboard_but_mods_and_keys(void) { -#ifdef EXTRAKEY_ENABLE - host_system_send(0); - host_consumer_send(0); -#endif - clear_weak_mods(); - send_keyboard_report(); -#ifdef MOUSEKEY_ENABLE - mousekey_clear(); - mousekey_send(); -#endif -#ifdef PROGRAMMABLE_BUTTON_ENABLE - programmable_button_clear(); -#endif -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -bool is_tap_record(keyrecord_t *record) { - if (IS_NOEVENT(record->event)) { - return false; - } - -#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE) - action_t action; - if (record->keycode) { - action = action_for_keycode(record->keycode); - } else { - action = layer_switch_get_action(record->event.key); - } -#else - action_t action = layer_switch_get_action(record->event.key); -#endif - return is_tap_action(action); -} - -/** \brief Utilities for actions. (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -bool is_tap_action(action_t action) { - switch (action.kind.id) { - case ACT_LMODS_TAP: - case ACT_RMODS_TAP: - case ACT_LAYER_TAP: - case ACT_LAYER_TAP_EXT: - switch (action.layer_tap.code) { - case KC_NO ... KC_RIGHT_GUI: - case OP_TAP_TOGGLE: - case OP_ONESHOT: - return true; - } - return false; - case ACT_SWAP_HANDS: - switch (action.swap.code) { - case KC_NO ... KC_RIGHT_GUI: - case OP_SH_TAP_TOGGLE: - return true; - } - return false; - } - return false; -} - -/** \brief Debug print (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void debug_event(keyevent_t event) { - ac_dprintf("%04X%c(%u)", (event.key.row << 8 | event.key.col), (event.pressed ? 'd' : 'u'), event.time); -} -/** \brief Debug print (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void debug_record(keyrecord_t record) { - debug_event(record.event); -#ifndef NO_ACTION_TAPPING - ac_dprintf(":%u%c", record.tap.count, (record.tap.interrupted ? '-' : ' ')); -#endif -} - -/** \brief Debug print (FIXME: Needs better description) - * - * FIXME: Needs documentation. - */ -void debug_action(action_t action) { - switch (action.kind.id) { - case ACT_LMODS: - ac_dprintf("ACT_LMODS"); - break; - case ACT_RMODS: - ac_dprintf("ACT_RMODS"); - break; - case ACT_LMODS_TAP: - ac_dprintf("ACT_LMODS_TAP"); - break; - case ACT_RMODS_TAP: - ac_dprintf("ACT_RMODS_TAP"); - break; - case ACT_USAGE: - ac_dprintf("ACT_USAGE"); - break; - case ACT_MOUSEKEY: - ac_dprintf("ACT_MOUSEKEY"); - break; - case ACT_LAYER: - ac_dprintf("ACT_LAYER"); - break; - case ACT_LAYER_MODS: - ac_dprintf("ACT_LAYER_MODS"); - break; - case ACT_LAYER_TAP: - ac_dprintf("ACT_LAYER_TAP"); - break; - case ACT_LAYER_TAP_EXT: - ac_dprintf("ACT_LAYER_TAP_EXT"); - break; - case ACT_SWAP_HANDS: - ac_dprintf("ACT_SWAP_HANDS"); - break; - default: - ac_dprintf("UNKNOWN"); - break; - } - ac_dprintf("[%X:%02X]", action.kind.param >> 8, action.kind.param & 0xff); -} diff --git a/quantum/action.h b/quantum/action.h deleted file mode 100644 index d5b15c6f1732..000000000000 --- a/quantum/action.h +++ /dev/null @@ -1,154 +0,0 @@ -/* -Copyright 2012,2013 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include -#include "progmem.h" -#include "keyboard.h" -#include "keycode.h" -#include "action_code.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef TAP_CODE_DELAY -# define TAP_CODE_DELAY 0 -#endif -#ifndef TAP_HOLD_CAPS_DELAY -# define TAP_HOLD_CAPS_DELAY 80 -#endif - -/* tapping count and state */ -typedef struct { - bool interrupted : 1; - bool reserved2 : 1; - bool reserved1 : 1; - bool reserved0 : 1; - uint8_t count : 4; -} tap_t; - -/* Key event container for recording */ -typedef struct { - keyevent_t event; -#ifndef NO_ACTION_TAPPING - tap_t tap; -#endif -#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE) - uint16_t keycode; -#endif -} keyrecord_t; - -/* Execute action per keyevent */ -void action_exec(keyevent_t event); - -/* action for key */ -action_t action_for_key(uint8_t layer, keypos_t key); -action_t action_for_keycode(uint16_t keycode); - -/* keyboard-specific key event (pre)processing */ -bool process_record_quantum(keyrecord_t *record); - -/* Utilities for actions. */ -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) -extern bool disable_action_cache; -#endif - -/* Code for handling one-handed key modifiers. */ -#ifdef SWAP_HANDS_ENABLE -extern bool swap_hands; -extern const keypos_t PROGMEM hand_swap_config[MATRIX_ROWS][MATRIX_COLS]; -# if (MATRIX_COLS <= 8) -typedef uint8_t swap_state_row_t; -# elif (MATRIX_COLS <= 16) -typedef uint16_t swap_state_row_t; -# elif (MATRIX_COLS <= 32) -typedef uint32_t swap_state_row_t; -# else -# error "MATRIX_COLS: invalid value" -# endif - -/** - * @brief Enable swap hands - */ -void swap_hands_on(void); -/** - * @brief Disable swap hands - */ -void swap_hands_off(void); -/** - * @brief Toggle swap hands enable state - */ -void swap_hands_toggle(void); -/** - * @brief Get the swap hands enable state - * - * @return true - * @return false - */ -bool is_swap_hands_on(void); - -void process_hand_swap(keyevent_t *record); -#endif - -void process_record_nocache(keyrecord_t *record); -void process_record(keyrecord_t *record); -void process_record_handler(keyrecord_t *record); -void post_process_record_quantum(keyrecord_t *record); -void process_action(keyrecord_t *record, action_t action); -void register_code(uint8_t code); -void unregister_code(uint8_t code); -void tap_code(uint8_t code); -void tap_code_delay(uint8_t code, uint16_t delay); -void register_mods(uint8_t mods); -void unregister_mods(uint8_t mods); -void register_weak_mods(uint8_t mods); -void unregister_weak_mods(uint8_t mods); -// void set_mods(uint8_t mods); -void clear_keyboard(void); -void clear_keyboard_but_mods(void); -void clear_keyboard_but_mods_and_keys(void); -void layer_switch(uint8_t new_layer); -bool is_tap_record(keyrecord_t *record); -bool is_tap_action(action_t action); - -#ifndef NO_ACTION_TAPPING -void process_record_tap_hint(keyrecord_t *record); -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers - -#ifdef ACTION_DEBUG -# include "debug.h" -# include "print.h" -# define ac_dprintf(...) dprintf(__VA_ARGS__) -#else -# define ac_dprintf(...) \ - do { \ - } while (0) -#endif - -void debug_event(keyevent_t event); -void debug_record(keyrecord_t record); -void debug_action(action_t action); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/action_code.h b/quantum/action_code.h deleted file mode 100644 index d9a575b51838..000000000000 --- a/quantum/action_code.h +++ /dev/null @@ -1,264 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ - -#pragma once - -#include "modifiers.h" - -/** \brief Action codes - * - * 16bit code: action_kind(4bit) + action_parameter(12bit) - * - * Key Actions(00xx) - * ----------------- - * ACT_MODS(000r): - * 000r|0000|0000 0000 No action code - * 000r|0000|0000 0001 Transparent code - * 000r|0000| keycode Key - * 000r|mods|0000 0000 Modifiers - * 000r|mods| keycode Modifiers+Key(Modified key) - * r: Left/Right flag(Left:0, Right:1) - * - * ACT_MODS_TAP(001r): - * 001r|mods|0000 0000 Modifiers with OneShot - * 001r|mods|0000 0001 Modifiers with tap toggle - * 001r|mods|0000 00xx (reserved) - * 001r|mods| keycode Modifiers with Tap Key(Dual role) - * - * Other Keys(01xx) - * ---------------- - * ACT_USAGE(0100): TODO: Not needed? - * 0100|00| usage(10) System control(0x80) - General Desktop page(0x01) - * 0100|01| usage(10) Consumer control(0x01) - Consumer page(0x0C) - * 0100|10| usage(10) (reserved) - * 0100|11| usage(10) (reserved) - * - * ACT_MOUSEKEY(0101): TODO: Merge these two actions to conserve space? - * 0101|xxxx| keycode Mouse key - * - * ACT_SWAP_HANDS(0110): - * 0110|xxxx| keycode Swap hands (keycode on tap, or options) - * - * 0111|xxxx xxxx xxxx (reserved) - * - * Layer Actions(10xx) - * ------------------- - * ACT_LAYER(1000): - * 1000|oo00|pppE BBBB Default Layer Bitwise operation - * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) - * ppp: 4-bit chunk part(0-7) - * EBBBB: bits and extra bit - * 1000|ooee|pppE BBBB Layer Bitwise Operation - * oo: operation(00:AND, 01:OR, 10:XOR, 11:SET) - * ppp: 4-bit chunk part(0-7) - * EBBBB: bits and extra bit - * ee: on event(01:press, 10:release, 11:both) - * - * ACT_LAYER_MODS(1001): - * 1001|LLLL| mods Layer with modifiers held - * - * ACT_LAYER_TAP(101x): - * 101E|LLLL| keycode On/Off with tap key (0x00-DF)[TAP] - * 101E|LLLL|1110 mods On/Off with modifiers (0xE0-EF)[NOT TAP] - * 101E|LLLL|1111 0000 Invert with tap toggle (0xF0) [TAP] - * 101E|LLLL|1111 0001 On/Off (0xF1) [NOT TAP] - * 101E|LLLL|1111 0010 Off/On (0xF2) [NOT TAP] - * 101E|LLLL|1111 0011 Set/Clear (0xF3) [NOT TAP] - * 101E|LLLL|1111 0100 One Shot Layer (0xF4) [TAP] - * 101E|LLLL|1111 xxxx Reserved (0xF5-FF) - * ELLLL: layer 0-31(E: extra bit for layer 16-31) - */ -enum action_kind_id { - /* Key Actions */ - ACT_MODS = 0b0000, - ACT_LMODS = 0b0000, - ACT_RMODS = 0b0001, - ACT_MODS_TAP = 0b0010, - ACT_LMODS_TAP = 0b0010, - ACT_RMODS_TAP = 0b0011, - /* Other Keys */ - ACT_USAGE = 0b0100, - ACT_MOUSEKEY = 0b0101, - /* One-hand Support */ - ACT_SWAP_HANDS = 0b0110, - /* Layer Actions */ - ACT_LAYER = 0b1000, - ACT_LAYER_MODS = 0b1001, - ACT_LAYER_TAP = 0b1010, /* Layer 0-15 */ - ACT_LAYER_TAP_EXT = 0b1011, /* Layer 16-31 */ -}; - -/** \brief Action Code Struct - * - * NOTE: - * In avr-gcc bit field seems to be assigned from LSB(bit0) to MSB(bit15). - * AVR looks like a little endian in avr-gcc. - * Not portable across compiler/endianness? - * - * Byte order and bit order of 0x1234: - * Big endian: Little endian: - * -------------------- -------------------- - * FEDC BA98 7654 3210 0123 4567 89AB CDEF - * 0001 0010 0011 0100 0010 1100 0100 1000 - * 0x12 0x34 0x34 0x12 - */ -typedef union { - uint16_t code; - struct action_kind { - uint16_t param : 12; - uint8_t id : 4; - } kind; - struct action_key { - uint8_t code : 8; - uint8_t mods : 4; - uint8_t kind : 4; - } key; - struct action_layer_bitop { - uint8_t bits : 4; - uint8_t xbit : 1; - uint8_t part : 3; - uint8_t on : 2; - uint8_t op : 2; - uint8_t kind : 4; - } layer_bitop; - struct action_layer_mods { - uint8_t mods : 8; - uint8_t layer : 4; - uint8_t kind : 4; - } layer_mods; - struct action_layer_tap { - uint8_t code : 8; - uint8_t val : 5; - uint8_t kind : 3; - } layer_tap; - struct action_usage { - uint16_t code : 10; - uint8_t page : 2; - uint8_t kind : 4; - } usage; - struct action_swap { - uint8_t code : 8; - uint8_t opt : 4; - uint8_t kind : 4; - } swap; -} action_t; - -/* action utility */ -#define ACTION_NO 0 -#define ACTION_TRANSPARENT 1 -#define ACTION(kind, param) ((kind) << 12 | (param)) - -enum mods_codes { - MODS_ONESHOT = 0x00, - MODS_TAP_TOGGLE = 0x01, -}; -#define ACTION_KEY(key) ACTION(ACT_MODS, (key)) -#define ACTION_MODS(mods) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | 0) -#define ACTION_MODS_KEY(mods, key) ACTION(ACT_MODS, ((mods)&0x1f) << 8 | (key)) -#define ACTION_MODS_TAP_KEY(mods, key) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | (key)) -#define ACTION_MODS_ONESHOT(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_ONESHOT) -#define ACTION_MODS_TAP_TOGGLE(mods) ACTION(ACT_MODS_TAP, ((mods)&0x1f) << 8 | MODS_TAP_TOGGLE) - -/** \brief Other Keys - */ -enum usage_pages { - PAGE_SYSTEM, - PAGE_CONSUMER, -}; - -#define ACTION_USAGE_SYSTEM(id) ACTION(ACT_USAGE, PAGE_SYSTEM << 10 | (id)) -#define ACTION_USAGE_CONSUMER(id) ACTION(ACT_USAGE, PAGE_CONSUMER << 10 | (id)) -#define ACTION_MOUSEKEY(key) ACTION(ACT_MOUSEKEY, key) - -/** \brief Layer Actions - */ -enum layer_param_on { - ON_PRESS = 1, - ON_RELEASE = 2, - ON_BOTH = 3, -}; - -/** \brief Layer Actions - */ -enum layer_param_bit_op { - OP_BIT_AND = 0, - OP_BIT_OR = 1, - OP_BIT_XOR = 2, - OP_BIT_SET = 3, -}; - -/** \brief Layer Actions - */ -enum layer_param_tap_op { - OP_TAP_TOGGLE = 0xF0, - OP_ON_OFF, - OP_OFF_ON, - OP_SET_CLEAR, - OP_ONESHOT, -}; -#define ACTION_LAYER_BITOP(op, part, bits, on) ACTION(ACT_LAYER, (op) << 10 | (on) << 8 | (part) << 5 | ((bits)&0x1f)) -#define ACTION_LAYER_TAP(layer, key) ACTION(ACT_LAYER_TAP, (layer) << 8 | (key)) -/* Default Layer */ -#define ACTION_DEFAULT_LAYER_SET(layer) ACTION_DEFAULT_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4)) -/* Layer Operation */ -#define ACTION_LAYER_CLEAR(on) ACTION_LAYER_BIT_AND(0, 0, (on)) -#define ACTION_LAYER_MOMENTARY(layer) ACTION_LAYER_ON_OFF(layer) -#define ACTION_LAYER_TOGGLE(layer) ACTION_LAYER_INVERT(layer, ON_RELEASE) -#define ACTION_LAYER_INVERT(layer, on) ACTION_LAYER_BIT_XOR((layer) / 4, 1 << ((layer) % 4), (on)) -#define ACTION_LAYER_ON(layer, on) ACTION_LAYER_BIT_OR((layer) / 4, 1 << ((layer) % 4), (on)) -#define ACTION_LAYER_OFF(layer, on) ACTION_LAYER_BIT_AND((layer) / 4, ~(1 << ((layer) % 4)), (on)) -#define ACTION_LAYER_GOTO(layer) ACTION_LAYER_SET(layer, ON_PRESS) -#define ACTION_LAYER_SET(layer, on) ACTION_LAYER_BIT_SET((layer) / 4, 1 << ((layer) % 4), (on)) -#define ACTION_LAYER_ON_OFF(layer) ACTION_LAYER_TAP((layer), OP_ON_OFF) -#define ACTION_LAYER_OFF_ON(layer) ACTION_LAYER_TAP((layer), OP_OFF_ON) -#define ACTION_LAYER_SET_CLEAR(layer) ACTION_LAYER_TAP((layer), OP_SET_CLEAR) -#define ACTION_LAYER_ONESHOT(layer) ACTION_LAYER_TAP((layer), OP_ONESHOT) -#define ACTION_LAYER_MODS(layer, mods) ACTION(ACT_LAYER_MODS, (layer) << 8 | (mods)) -/* With Tapping */ -#define ACTION_LAYER_TAP_KEY(layer, key) ACTION_LAYER_TAP((layer), (key)) -#define ACTION_LAYER_TAP_TOGGLE(layer) ACTION_LAYER_TAP((layer), OP_TAP_TOGGLE) -/* Bitwise Operation */ -#define ACTION_LAYER_BIT_AND(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), (on)) -#define ACTION_LAYER_BIT_OR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), (on)) -#define ACTION_LAYER_BIT_XOR(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), (on)) -#define ACTION_LAYER_BIT_SET(part, bits, on) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), (on)) -/* Default Layer Bitwise Operation */ -#define ACTION_DEFAULT_LAYER_BIT_AND(part, bits) ACTION_LAYER_BITOP(OP_BIT_AND, (part), (bits), 0) -#define ACTION_DEFAULT_LAYER_BIT_OR(part, bits) ACTION_LAYER_BITOP(OP_BIT_OR, (part), (bits), 0) -#define ACTION_DEFAULT_LAYER_BIT_XOR(part, bits) ACTION_LAYER_BITOP(OP_BIT_XOR, (part), (bits), 0) -#define ACTION_DEFAULT_LAYER_BIT_SET(part, bits) ACTION_LAYER_BITOP(OP_BIT_SET, (part), (bits), 0) - -/* OneHand Support */ -enum swap_hands_param_tap_op { - OP_SH_TOGGLE = 0xF0, - OP_SH_TAP_TOGGLE, - OP_SH_ON_OFF, - OP_SH_OFF_ON, - OP_SH_OFF, - OP_SH_ON, - OP_SH_ONESHOT, -}; - -#define ACTION_SWAP_HANDS() ACTION_SWAP_HANDS_ON_OFF() -#define ACTION_SWAP_HANDS_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TOGGLE) -#define ACTION_SWAP_HANDS_TAP_TOGGLE() ACTION(ACT_SWAP_HANDS, OP_SH_TAP_TOGGLE) -#define ACTION_SWAP_HANDS_ONESHOT() ACTION(ACT_SWAP_HANDS, OP_SH_ONESHOT) -#define ACTION_SWAP_HANDS_TAP_KEY(key) ACTION(ACT_SWAP_HANDS, key) -#define ACTION_SWAP_HANDS_ON_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_ON_OFF) -#define ACTION_SWAP_HANDS_OFF_ON() ACTION(ACT_SWAP_HANDS, OP_SH_OFF_ON) -#define ACTION_SWAP_HANDS_ON() ACTION(ACT_SWAP_HANDS, OP_SH_ON) -#define ACTION_SWAP_HANDS_OFF() ACTION(ACT_SWAP_HANDS, OP_SH_OFF) diff --git a/quantum/action_layer.c b/quantum/action_layer.c deleted file mode 100644 index 7c09a5bd1e54..000000000000 --- a/quantum/action_layer.c +++ /dev/null @@ -1,363 +0,0 @@ -#include -#include - -#include "keyboard.h" -#include "action.h" -#include "encoder.h" -#include "util.h" -#include "action_layer.h" - -/** \brief Default Layer State - */ -layer_state_t default_layer_state = 0; - -/** \brief Default Layer State Set At user Level - * - * Run user code on default layer state change - */ -__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state) { - return state; -} - -/** \brief Default Layer State Set At Keyboard Level - * - * Run keyboard code on default layer state change - */ -__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state) { - return default_layer_state_set_user(state); -} - -/** \brief Default Layer State Set - * - * Static function to set the default layer state, prints debug info and clears keys - */ -static void default_layer_state_set(layer_state_t state) { - state = default_layer_state_set_kb(state); - ac_dprintf("default_layer_state: "); - default_layer_debug(); - ac_dprintf(" to "); - default_layer_state = state; - default_layer_debug(); - ac_dprintf("\n"); -#if defined(STRICT_LAYER_RELEASE) - clear_keyboard_but_mods(); // To avoid stuck keys -#elif defined(SEMI_STRICT_LAYER_RELEASE) - clear_keyboard_but_mods_and_keys(); // Don't reset held keys -#endif -} - -/** \brief Default Layer Print - * - * Print out the hex value of the 32-bit default layer state, as well as the value of the highest bit. - */ -void default_layer_debug(void) { - ac_dprintf("%08hX(%u)", default_layer_state, get_highest_layer(default_layer_state)); -} - -/** \brief Default Layer Set - * - * Sets the default layer state. - */ -void default_layer_set(layer_state_t state) { - default_layer_state_set(state); -} - -#ifndef NO_ACTION_LAYER -/** \brief Default Layer Or - * - * Turns on the default layer based on matching bits between specified layer and existing layer state - */ -void default_layer_or(layer_state_t state) { - default_layer_state_set(default_layer_state | state); -} -/** \brief Default Layer And - * - * Turns on default layer based on matching enabled bits between specified layer and existing layer state - */ -void default_layer_and(layer_state_t state) { - default_layer_state_set(default_layer_state & state); -} -/** \brief Default Layer Xor - * - * Turns on default layer based on non-matching bits between specified layer and existing layer state - */ -void default_layer_xor(layer_state_t state) { - default_layer_state_set(default_layer_state ^ state); -} -#endif - -#ifndef NO_ACTION_LAYER -/** \brief Keymap Layer State - */ -layer_state_t layer_state = 0; - -/** \brief Layer state set user - * - * Runs user code on layer state change - */ -__attribute__((weak)) layer_state_t layer_state_set_user(layer_state_t state) { - return state; -} - -/** \brief Layer state set keyboard - * - * Runs keyboard code on layer state change - */ -__attribute__((weak)) layer_state_t layer_state_set_kb(layer_state_t state) { - return layer_state_set_user(state); -} - -/** \brief Layer state set - * - * Sets the layer to match the specified state (a bitmask) - */ -void layer_state_set(layer_state_t state) { - state = layer_state_set_kb(state); - ac_dprintf("layer_state: "); - layer_debug(); - ac_dprintf(" to "); - layer_state = state; - layer_debug(); - ac_dprintf("\n"); -# if defined(STRICT_LAYER_RELEASE) - clear_keyboard_but_mods(); // To avoid stuck keys -# elif defined(SEMI_STRICT_LAYER_RELEASE) - clear_keyboard_but_mods_and_keys(); // Don't reset held keys -# endif -} - -/** \brief Layer clear - * - * Turn off all layers - */ -void layer_clear(void) { - layer_state_set(0); -} - -/** \brief Layer state is - * - * Return whether the given state is on (it might still be shadowed by a higher state, though) - */ -bool layer_state_is(uint8_t layer) { - return layer_state_cmp(layer_state, layer); -} - -/** \brief Layer state compare - * - * Used for comparing layers {mostly used for unit testing} - */ -bool layer_state_cmp(layer_state_t cmp_layer_state, uint8_t layer) { - if (!cmp_layer_state) { - return layer == 0; - } - return (cmp_layer_state & ((layer_state_t)1 << layer)) != 0; -} - -/** \brief Layer move - * - * Turns on the given layer and turn off all other layers - */ -void layer_move(uint8_t layer) { - layer_state_set((layer_state_t)1 << layer); -} - -/** \brief Layer on - * - * Turns on given layer - */ -void layer_on(uint8_t layer) { - layer_state_set(layer_state | ((layer_state_t)1 << layer)); -} - -/** \brief Layer off - * - * Turns off given layer - */ -void layer_off(uint8_t layer) { - layer_state_set(layer_state & ~((layer_state_t)1 << layer)); -} - -/** \brief Layer invert - * - * Toggle the given layer (set it if it's unset, or unset it if it's set) - */ -void layer_invert(uint8_t layer) { - layer_state_set(layer_state ^ ((layer_state_t)1 << layer)); -} - -/** \brief Layer or - * - * Turns on layers based on matching bits between specified layer and existing layer state - */ -void layer_or(layer_state_t state) { - layer_state_set(layer_state | state); -} -/** \brief Layer and - * - * Turns on layers based on matching enabled bits between specified layer and existing layer state - */ -void layer_and(layer_state_t state) { - layer_state_set(layer_state & state); -} -/** \brief Layer xor - * - * Turns on layers based on non-matching bits between specified layer and existing layer state - */ -void layer_xor(layer_state_t state) { - layer_state_set(layer_state ^ state); -} - -/** \brief Layer debug printing - * - * Print out the hex value of the 32-bit layer state, as well as the value of the highest bit. - */ -void layer_debug(void) { - ac_dprintf("%08hX(%u)", layer_state, get_highest_layer(layer_state)); -} -#endif - -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) -/** \brief source layer cache - */ - -uint8_t source_layers_cache[((MATRIX_ROWS * MATRIX_COLS) + (CHAR_BIT)-1) / (CHAR_BIT)][MAX_LAYER_BITS] = {{0}}; -# ifdef ENCODER_MAP_ENABLE -uint8_t encoder_source_layers_cache[(NUM_ENCODERS + (CHAR_BIT)-1) / (CHAR_BIT)][MAX_LAYER_BITS] = {{0}}; -# endif // ENCODER_MAP_ENABLE - -/** \brief update source layers cache impl - * - * Updates the supplied cache when changing layers - */ -void update_source_layers_cache_impl(uint8_t layer, uint16_t entry_number, uint8_t cache[][MAX_LAYER_BITS]) { - const uint16_t storage_idx = entry_number / (CHAR_BIT); - const uint8_t storage_bit = entry_number % (CHAR_BIT); - for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { - cache[storage_idx][bit_number] ^= (-((layer & (1U << bit_number)) != 0) ^ cache[storage_idx][bit_number]) & (1U << storage_bit); - } -} - -/** \brief read source layers cache - * - * reads the cached keys stored when the layer was changed - */ -uint8_t read_source_layers_cache_impl(uint16_t entry_number, uint8_t cache[][MAX_LAYER_BITS]) { - const uint16_t storage_idx = entry_number / (CHAR_BIT); - const uint8_t storage_bit = entry_number % (CHAR_BIT); - uint8_t layer = 0; - - for (uint8_t bit_number = 0; bit_number < MAX_LAYER_BITS; bit_number++) { - layer |= ((cache[storage_idx][bit_number] & (1U << storage_bit)) != 0) << bit_number; - } - - return layer; -} - -/** \brief update encoder source layers cache - * - * Updates the cached encoders when changing layers - */ -void update_source_layers_cache(keypos_t key, uint8_t layer) { - if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { - const uint16_t entry_number = (uint16_t)(key.row * MATRIX_COLS) + key.col; - update_source_layers_cache_impl(layer, entry_number, source_layers_cache); - } -# ifdef ENCODER_MAP_ENABLE - else if (key.row == KEYLOC_ENCODER_CW || key.row == KEYLOC_ENCODER_CCW) { - const uint16_t entry_number = key.col; - update_source_layers_cache_impl(layer, entry_number, encoder_source_layers_cache); - } -# endif // ENCODER_MAP_ENABLE -} - -/** \brief read source layers cache - * - * reads the cached keys stored when the layer was changed - */ -uint8_t read_source_layers_cache(keypos_t key) { - if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { - const uint16_t entry_number = (uint16_t)(key.row * MATRIX_COLS) + key.col; - return read_source_layers_cache_impl(entry_number, source_layers_cache); - } -# ifdef ENCODER_MAP_ENABLE - else if (key.row == KEYLOC_ENCODER_CW || key.row == KEYLOC_ENCODER_CCW) { - const uint16_t entry_number = key.col; - return read_source_layers_cache_impl(entry_number, encoder_source_layers_cache); - } -# endif // ENCODER_MAP_ENABLE - return 0; -} -#endif - -/** \brief Store or get action (FIXME: Needs better summary) - * - * Make sure the action triggered when the key is released is the same - * one as the one triggered on press. It's important for the mod keys - * when the layer is switched after the down event but before the up - * event as they may get stuck otherwise. - */ -action_t store_or_get_action(bool pressed, keypos_t key) { -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) - if (disable_action_cache) { - return layer_switch_get_action(key); - } - - uint8_t layer; - - if (pressed) { - layer = layer_switch_get_layer(key); - update_source_layers_cache(key, layer); - } else { - layer = read_source_layers_cache(key); - } - return action_for_key(layer, key); -#else - return layer_switch_get_action(key); -#endif -} - -/** \brief Layer switch get layer - * - * Gets the layer based on key info - */ -uint8_t layer_switch_get_layer(keypos_t key) { -#ifndef NO_ACTION_LAYER - action_t action; - action.code = ACTION_TRANSPARENT; - - layer_state_t layers = layer_state | default_layer_state; - /* check top layer first */ - for (int8_t i = MAX_LAYER - 1; i >= 0; i--) { - if (layers & ((layer_state_t)1 << i)) { - action = action_for_key(i, key); - if (action.code != ACTION_TRANSPARENT) { - return i; - } - } - } - /* fall back to layer 0 */ - return 0; -#else - return get_highest_layer(default_layer_state); -#endif -} - -/** \brief Layer switch get layer - * - * Gets action code based on key position - */ -action_t layer_switch_get_action(keypos_t key) { - return action_for_key(layer_switch_get_layer(key), key); -} - -#ifndef NO_ACTION_LAYER -layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3) { - layer_state_t mask12 = ((layer_state_t)1 << layer1) | ((layer_state_t)1 << layer2); - layer_state_t mask3 = (layer_state_t)1 << layer3; - return (state & mask12) == mask12 ? (state | mask3) : (state & ~mask3); -} - -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3) { - layer_state_set(update_tri_layer_state(layer_state, layer1, layer2, layer3)); -} -#endif diff --git a/quantum/action_layer.h b/quantum/action_layer.h deleted file mode 100644 index ff783bb3e7fc..000000000000 --- a/quantum/action_layer.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include "keyboard.h" -#include "action.h" - -#ifdef DYNAMIC_KEYMAP_ENABLE -# ifndef DYNAMIC_KEYMAP_LAYER_COUNT -# define DYNAMIC_KEYMAP_LAYER_COUNT 4 -# endif -# define MAX_LAYER DYNAMIC_KEYMAP_LAYER_COUNT -# if DYNAMIC_KEYMAP_LAYER_COUNT <= 8 -# ifndef LAYER_STATE_8BIT -# define LAYER_STATE_8BIT -# endif -# elif DYNAMIC_KEYMAP_LAYER_COUNT <= 16 -# ifndef LAYER_STATE_16BIT -# define LAYER_STATE_16BIT -# endif -# else -# ifndef LAYER_STATE_32BIT -# define LAYER_STATE_32BIT -# endif -# endif -#endif - -#if !defined(LAYER_STATE_8BIT) && !defined(LAYER_STATE_16BIT) && !defined(LAYER_STATE_32BIT) -# define LAYER_STATE_16BIT -#endif - -#if defined(LAYER_STATE_8BIT) -typedef uint8_t layer_state_t; -# define MAX_LAYER_BITS 3 -# ifndef MAX_LAYER -# define MAX_LAYER 8 -# endif -# define get_highest_layer(state) biton(state) -#elif defined(LAYER_STATE_16BIT) -typedef uint16_t layer_state_t; -# define MAX_LAYER_BITS 4 -# ifndef MAX_LAYER -# define MAX_LAYER 16 -# endif -# define get_highest_layer(state) biton16(state) -#elif defined(LAYER_STATE_32BIT) -typedef uint32_t layer_state_t; -# define MAX_LAYER_BITS 5 -# ifndef MAX_LAYER -# define MAX_LAYER 32 -# endif -# define get_highest_layer(state) biton32(state) -#else -# error Layer Mask size not specified. HOW?! -#endif - -/* - * Default Layer - */ -extern layer_state_t default_layer_state; -void default_layer_debug(void); -void default_layer_set(layer_state_t state); - -__attribute__((weak)) layer_state_t default_layer_state_set_kb(layer_state_t state); -__attribute__((weak)) layer_state_t default_layer_state_set_user(layer_state_t state); - -#ifndef NO_ACTION_LAYER -/* bitwise operation */ -void default_layer_or(layer_state_t state); -void default_layer_and(layer_state_t state); -void default_layer_xor(layer_state_t state); -#else -# define default_layer_or(state) -# define default_layer_and(state) -# define default_layer_xor(state) -#endif - -/* - * Keymap Layer - */ -#ifndef NO_ACTION_LAYER -extern layer_state_t layer_state; - -void layer_state_set(layer_state_t state); -bool layer_state_is(uint8_t layer); -bool layer_state_cmp(layer_state_t layer1, uint8_t layer2); - -void layer_debug(void); -void layer_clear(void); -void layer_move(uint8_t layer); -void layer_on(uint8_t layer); -void layer_off(uint8_t layer); -void layer_invert(uint8_t layer); -/* bitwise operation */ -void layer_or(layer_state_t state); -void layer_and(layer_state_t state); -void layer_xor(layer_state_t state); -layer_state_t layer_state_set_user(layer_state_t state); -layer_state_t layer_state_set_kb(layer_state_t state); - -/** - * @brief Applies the tri layer to global layer state. Not be used in layer_state_set_(kb|user) functions. - * - * @param layer1 First layer to check for tri layer - * @param layer2 Second layer to check for tri layer - * @param layer3 Layer to activate if both other layers are enabled - */ -void update_tri_layer(uint8_t layer1, uint8_t layer2, uint8_t layer3); -/** - * @brief Applies the tri layer behavior to supplied layer bitmask, without using layer functions. - * - * @param state Original layer bitmask to check and modify - * @param layer1 First layer to check for tri layer - * @param layer2 Second layer to check for tri layer - * @param layer3 Layer to activate if both other layers are enabled - * @return layer_state_t returns a modified layer bitmask with tri layer modifications applied - */ -layer_state_t update_tri_layer_state(layer_state_t state, uint8_t layer1, uint8_t layer2, uint8_t layer3); -#else -# define layer_state 0 - -# define layer_state_set(layer) -# define layer_state_is(layer) (layer == 0) -# define layer_state_cmp(state, layer) (state == 0 ? layer == 0 : (state & (layer_state_t)1 << layer) != 0) - -# define layer_debug() -# define layer_clear() -# define layer_move(layer) (void)layer -# define layer_on(layer) (void)layer -# define layer_off(layer) (void)layer -# define layer_invert(layer) (void)layer -# define layer_or(state) (void)state -# define layer_and(state) (void)state -# define layer_xor(state) (void)state -# define layer_state_set_kb(state) (void)state -# define layer_state_set_user(state) (void)state -# define update_tri_layer(layer1, layer2, layer3) -# define update_tri_layer_state(state, layer1, layer2, layer3) (void)state -#endif - -/* pressed actions cache */ -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) - -void update_source_layers_cache(keypos_t key, uint8_t layer); -uint8_t read_source_layers_cache(keypos_t key); -#endif -action_t store_or_get_action(bool pressed, keypos_t key); - -/* return the topmost non-transparent layer currently associated with key */ -uint8_t layer_switch_get_layer(keypos_t key); - -/* return action depending on current layer status */ -action_t layer_switch_get_action(keypos_t key); diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c deleted file mode 100644 index f94e5e6f693c..000000000000 --- a/quantum/action_tapping.c +++ /dev/null @@ -1,547 +0,0 @@ -#include -#include - -#include "action.h" -#include "action_layer.h" -#include "action_tapping.h" -#include "keycode.h" -#include "timer.h" - -#ifndef NO_ACTION_TAPPING - -# if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) -# error "IGNORE_MOD_TAP_INTERRUPT_PER_KEY has been removed; the code needs to be ported to use HOLD_ON_OTHER_KEY_PRESS_PER_KEY instead." -# elif defined(IGNORE_MOD_TAP_INTERRUPT) -# error "IGNORE_MOD_TAP_INTERRUPT is no longer necessary as it is now the default behavior of mod-tap keys. Please remove it from your config." -# endif - -# ifndef COMBO_ENABLE -# define IS_TAPPING_RECORD(r) (KEYEQ(tapping_key.event.key, (r->event.key))) -# else -# define IS_TAPPING_RECORD(r) (KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) -# endif -# define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_TAPPING_TERM(get_record_keycode(&tapping_key, false), &tapping_key)) -# define WITHIN_QUICK_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_QUICK_TAP_TERM(get_record_keycode(&tapping_key, false), &tapping_key)) - -# ifdef DYNAMIC_TAPPING_TERM_ENABLE -uint16_t g_tapping_term = TAPPING_TERM; -# endif - -# ifdef TAPPING_TERM_PER_KEY -__attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record) { -# ifdef DYNAMIC_TAPPING_TERM_ENABLE - return g_tapping_term; -# else - return TAPPING_TERM; -# endif -} -# endif - -# ifdef QUICK_TAP_TERM_PER_KEY -__attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { - return QUICK_TAP_TERM; -} -# endif - -# ifdef PERMISSIVE_HOLD_PER_KEY -__attribute__((weak)) bool get_permissive_hold(uint16_t keycode, keyrecord_t *record) { - return false; -} -# endif - -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY -__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { - return false; -} -# endif - -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) -# include "process_auto_shift.h" -# endif - -static keyrecord_t tapping_key = {}; -static keyrecord_t waiting_buffer[WAITING_BUFFER_SIZE] = {}; -static uint8_t waiting_buffer_head = 0; -static uint8_t waiting_buffer_tail = 0; - -static bool process_tapping(keyrecord_t *record); -static bool waiting_buffer_enq(keyrecord_t record); -static void waiting_buffer_clear(void); -static bool waiting_buffer_typed(keyevent_t event); -static bool waiting_buffer_has_anykey_pressed(void); -static void waiting_buffer_scan_tap(void); -static void debug_tapping_key(void); -static void debug_waiting_buffer(void); - -/** \brief Action Tapping Process - * - * FIXME: Needs doc - */ -void action_tapping_process(keyrecord_t record) { - if (process_tapping(&record)) { - if (IS_EVENT(record.event)) { - ac_dprintf("processed: "); - debug_record(record); - ac_dprintf("\n"); - } - } else { - if (!waiting_buffer_enq(record)) { - // clear all in case of overflow. - ac_dprintf("OVERFLOW: CLEAR ALL STATES\n"); - clear_keyboard(); - waiting_buffer_clear(); - tapping_key = (keyrecord_t){0}; - } - } - - // process waiting_buffer - if (IS_EVENT(record.event) && waiting_buffer_head != waiting_buffer_tail) { - ac_dprintf("---- action_exec: process waiting_buffer -----\n"); - } - for (; waiting_buffer_tail != waiting_buffer_head; waiting_buffer_tail = (waiting_buffer_tail + 1) % WAITING_BUFFER_SIZE) { - if (process_tapping(&waiting_buffer[waiting_buffer_tail])) { - ac_dprintf("processed: waiting_buffer[%u] =", waiting_buffer_tail); - debug_record(waiting_buffer[waiting_buffer_tail]); - ac_dprintf("\n\n"); - } else { - break; - } - } - if (IS_EVENT(record.event)) { - ac_dprintf("\n"); - } -} - -/* Some conditionally defined helper macros to keep process_tapping more - * readable. The conditional definition of tapping_keycode and all the - * conditional uses of it are hidden inside macros named TAP_... - */ -# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) -# define TAP_DEFINE_KEYCODE const uint16_t tapping_keycode = get_record_keycode(&tapping_key, false) -# else -# define TAP_DEFINE_KEYCODE -# endif - -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) -# ifdef RETRO_TAPPING_PER_KEY -# define TAP_GET_RETRO_TAPPING get_retro_tapping(tapping_keycode, &tapping_key) -# else -# define TAP_GET_RETRO_TAPPING true -# endif -# define MAYBE_RETRO_SHIFTING(ev) (TAP_GET_RETRO_TAPPING && (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0)) -# define TAP_IS_LT IS_QK_LAYER_TAP(tapping_keycode) -# define TAP_IS_MT IS_QK_MOD_TAP(tapping_keycode) -# define TAP_IS_RETRO IS_RETRO(tapping_keycode) -# else -# define TAP_GET_RETRO_TAPPING false -# define MAYBE_RETRO_SHIFTING(ev) false -# define TAP_IS_LT false -# define TAP_IS_MT false -# define TAP_IS_RETRO false -# endif - -# ifdef PERMISSIVE_HOLD_PER_KEY -# define TAP_GET_PERMISSIVE_HOLD get_permissive_hold(tapping_keycode, &tapping_key) -# elif defined(PERMISSIVE_HOLD) -# define TAP_GET_PERMISSIVE_HOLD true -# else -# define TAP_GET_PERMISSIVE_HOLD false -# endif - -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY -# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS get_hold_on_other_key_press(tapping_keycode, &tapping_key) -# elif defined(HOLD_ON_OTHER_KEY_PRESS) -# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS true -# else -# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false -# endif - -/** \brief Tapping - * - * Rule: Tap key is typed(pressed and released) within TAPPING_TERM. - * (without interfering by typing other key) - */ -/* return true when key event is processed or consumed. */ -bool process_tapping(keyrecord_t *keyp) { - const keyevent_t event = keyp->event; - - // state machine is in the "reset" state, no tapping key is to be - // processed - if (IS_NOEVENT(tapping_key.event)) { - if (!IS_EVENT(event)) { - // early return for tick events - } else if (event.pressed && is_tap_record(keyp)) { - // the currently pressed key is a tapping key, therefore transition - // into the "pressed" tapping key state - ac_dprintf("Tapping: Start(Press tap key).\n"); - tapping_key = *keyp; - process_record_tap_hint(&tapping_key); - waiting_buffer_scan_tap(); - debug_tapping_key(); - } else { - // the current key is just a regular key, pass it on for regular - // processing - process_record(keyp); - } - - return true; - } - - TAP_DEFINE_KEYCODE; - - // process "pressed" tapping key state - if (tapping_key.event.pressed) { - if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) { - if (IS_NOEVENT(event)) { - // early return for tick events - return true; - } - if (tapping_key.tap.count == 0) { - if (IS_TAPPING_RECORD(keyp) && !event.pressed) { -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - retroshift_swap_times(); -# endif - // first tap! - ac_dprintf("Tapping: First tap(0->1).\n"); - tapping_key.tap.count = 1; - debug_tapping_key(); - process_record(&tapping_key); - - // copy tapping state - keyp->tap = tapping_key.tap; - // enqueue - return false; - } - /* Process a key typed within TAPPING_TERM - * This can register the key before settlement of tapping, - * useful for long TAPPING_TERM but may prevent fast typing. - */ - // clang-format off - else if ( - ( - !event.pressed && waiting_buffer_typed(event) && - TAP_GET_PERMISSIVE_HOLD - ) - // Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT - // unnecessarily and fixes them for Layer Taps. - || (TAP_GET_RETRO_TAPPING && - ( - // Rolled over the two keys. - (tapping_key.tap.interrupted == true && ( - (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) || - (TAP_IS_MT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) - ) - ) - // Makes Retro Shift ignore the default behavior of - // MTs and LTs on nested taps below TAPPING_TERM or RETRO_SHIFT - || ( - TAP_IS_RETRO - && (event.key.col != tapping_key.event.key.col || event.key.row != tapping_key.event.key.row) - && !event.pressed && waiting_buffer_typed(event) - ) - ) - ) - ) { - // clang-format on - ac_dprintf("Tapping: End. No tap. Interfered by typing key\n"); - process_record(&tapping_key); - tapping_key = (keyrecord_t){0}; - debug_tapping_key(); - // enqueue - return false; - } - /* Process release event of a key pressed before tapping starts - * Without this unexpected repeating will occur with having fast repeating setting - * https://github.com/tmk/tmk_keyboard/issues/60 - */ - else if (!event.pressed && !waiting_buffer_typed(event)) { - // Modifier/Layer should be retained till end of this tapping. - action_t action = layer_switch_get_action(event.key); - switch (action.kind.id) { - case ACT_LMODS: - case ACT_RMODS: - if (action.key.mods && !action.key.code) return false; - if (IS_MODIFIER_KEYCODE(action.key.code)) return false; - break; - case ACT_LMODS_TAP: - case ACT_RMODS_TAP: - if (action.key.mods && keyp->tap.count == 0) return false; - if (IS_MODIFIER_KEYCODE(action.key.code)) return false; - break; - case ACT_LAYER_TAP: - case ACT_LAYER_TAP_EXT: - switch (action.layer_tap.code) { - case 0 ...(OP_TAP_TOGGLE - 1): - case OP_ON_OFF: - case OP_OFF_ON: - case OP_SET_CLEAR: - return false; - } - break; - } - // Release of key should be process immediately. - ac_dprintf("Tapping: release event of a key pressed before tapping\n"); - process_record(keyp); - return true; - } else { - // set interrupted flag when other key preesed during tapping - if (event.pressed) { - tapping_key.tap.interrupted = true; - if (TAP_GET_HOLD_ON_OTHER_KEY_PRESS) { - ac_dprintf("Tapping: End. No tap. Interfered by pressed key\n"); - process_record(&tapping_key); - tapping_key = (keyrecord_t){0}; - debug_tapping_key(); - // enqueue - return false; - } - } - // enqueue - return false; - } - } - // tap_count > 0 - else { - if (IS_TAPPING_RECORD(keyp) && !event.pressed) { - ac_dprintf("Tapping: Tap release(%u)\n", tapping_key.tap.count); - keyp->tap = tapping_key.tap; - process_record(keyp); - tapping_key = *keyp; - debug_tapping_key(); - return true; - } else if (is_tap_record(keyp) && event.pressed) { - if (tapping_key.tap.count > 1) { - ac_dprintf("Tapping: Start new tap with releasing last tap(>1).\n"); - // unregister key - process_record(&(keyrecord_t){ - .tap = tapping_key.tap, - .event.key = tapping_key.event.key, - .event.time = event.time, - .event.pressed = false, - .event.type = tapping_key.event.type, -# ifdef COMBO_ENABLE - .keycode = tapping_key.keycode, -# endif - }); - } else { - ac_dprintf("Tapping: Start while last tap(1).\n"); - } - tapping_key = *keyp; - waiting_buffer_scan_tap(); - debug_tapping_key(); - return true; - } else { - ac_dprintf("Tapping: key event while last tap(>0).\n"); - process_record(keyp); - return true; - } - } - } - // after TAPPING_TERM - else { - if (tapping_key.tap.count == 0) { - ac_dprintf("Tapping: End. Timeout. Not tap(0): "); - debug_event(event); - ac_dprintf("\n"); - process_record(&tapping_key); - tapping_key = (keyrecord_t){0}; - debug_tapping_key(); - return false; - } else { - if (IS_NOEVENT(event)) { - return true; - } - if (IS_TAPPING_RECORD(keyp) && !event.pressed) { - ac_dprintf("Tapping: End. last timeout tap release(>0)."); - keyp->tap = tapping_key.tap; - process_record(keyp); - tapping_key = (keyrecord_t){0}; - return true; - } else if (is_tap_record(keyp) && event.pressed) { - if (tapping_key.tap.count > 1) { - ac_dprintf("Tapping: Start new tap with releasing last timeout tap(>1).\n"); - // unregister key - process_record(&(keyrecord_t){ - .tap = tapping_key.tap, - .event.key = tapping_key.event.key, - .event.time = event.time, - .event.pressed = false, - .event.type = tapping_key.event.type, -# ifdef COMBO_ENABLE - .keycode = tapping_key.keycode, -# endif - }); - } else { - ac_dprintf("Tapping: Start while last timeout tap(1).\n"); - } - tapping_key = *keyp; - waiting_buffer_scan_tap(); - debug_tapping_key(); - return true; - } else { - ac_dprintf("Tapping: key event while last timeout tap(>0).\n"); - process_record(keyp); - return true; - } - } - } - } - // process "released" tapping key state - else { - if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) { - if (IS_NOEVENT(event)) { - // early return for tick events - return true; - } - if (event.pressed) { - if (IS_TAPPING_RECORD(keyp)) { - if (WITHIN_QUICK_TAP_TERM(event) && !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { - // sequential tap. - keyp->tap = tapping_key.tap; - if (keyp->tap.count < 15) keyp->tap.count += 1; - ac_dprintf("Tapping: Tap press(%u)\n", keyp->tap.count); - process_record(keyp); - tapping_key = *keyp; - debug_tapping_key(); - return true; - } - // FIX: start new tap again - tapping_key = *keyp; - return true; - } else if (is_tap_record(keyp)) { - // Sequential tap can be interfered with other tap key. - ac_dprintf("Tapping: Start with interfering other tap.\n"); - tapping_key = *keyp; - waiting_buffer_scan_tap(); - debug_tapping_key(); - return true; - } else { - // should none in buffer - // FIX: interrupted when other key is pressed - tapping_key.tap.interrupted = true; - process_record(keyp); - return true; - } - } else { - ac_dprintf("Tapping: other key just after tap.\n"); - process_record(keyp); - return true; - } - } else { - // Timeout - reset state machine. - ac_dprintf("Tapping: End(Timeout after releasing last tap): "); - debug_event(event); - ac_dprintf("\n"); - tapping_key = (keyrecord_t){0}; - debug_tapping_key(); - return false; - } - } -} - -/** \brief Waiting buffer enq - * - * FIXME: Needs docs - */ -bool waiting_buffer_enq(keyrecord_t record) { - if (IS_NOEVENT(record.event)) { - return true; - } - - if ((waiting_buffer_head + 1) % WAITING_BUFFER_SIZE == waiting_buffer_tail) { - ac_dprintf("waiting_buffer_enq: Over flow.\n"); - return false; - } - - waiting_buffer[waiting_buffer_head] = record; - waiting_buffer_head = (waiting_buffer_head + 1) % WAITING_BUFFER_SIZE; - - ac_dprintf("waiting_buffer_enq: "); - debug_waiting_buffer(); - return true; -} - -/** \brief Waiting buffer clear - * - * FIXME: Needs docs - */ -void waiting_buffer_clear(void) { - waiting_buffer_head = 0; - waiting_buffer_tail = 0; -} - -/** \brief Waiting buffer typed - * - * FIXME: Needs docs - */ -bool waiting_buffer_typed(keyevent_t event) { - for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { - if (KEYEQ(event.key, waiting_buffer[i].event.key) && event.pressed != waiting_buffer[i].event.pressed) { - return true; - } - } - return false; -} - -/** \brief Waiting buffer has anykey pressed - * - * FIXME: Needs docs - */ -__attribute__((unused)) bool waiting_buffer_has_anykey_pressed(void) { - for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { - if (waiting_buffer[i].event.pressed) return true; - } - return false; -} - -/** \brief Scan buffer for tapping - * - * FIXME: Needs docs - */ -void waiting_buffer_scan_tap(void) { - // early return if: - // - tapping already is settled - // - invalid state: tapping_key released && tap.count == 0 - if ((tapping_key.tap.count > 0) || !tapping_key.event.pressed) { - return; - } - - for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { - keyrecord_t *candidate = &waiting_buffer[i]; - if (IS_EVENT(candidate->event) && KEYEQ(candidate->event.key, tapping_key.event.key) && !candidate->event.pressed && WITHIN_TAPPING_TERM(candidate->event)) { - tapping_key.tap.count = 1; - candidate->tap.count = 1; - process_record(&tapping_key); - - ac_dprintf("waiting_buffer_scan_tap: found at [%u]\n", i); - debug_waiting_buffer(); - return; - } - } -} - -/** \brief Tapping key debug print - * - * FIXME: Needs docs - */ -static void debug_tapping_key(void) { - ac_dprintf("TAPPING_KEY="); - debug_record(tapping_key); - ac_dprintf("\n"); -} - -/** \brief Waiting buffer debug print - * - * FIXME: Needs docs - */ -static void debug_waiting_buffer(void) { - ac_dprintf("{ "); - for (uint8_t i = waiting_buffer_tail; i != waiting_buffer_head; i = (i + 1) % WAITING_BUFFER_SIZE) { - ac_dprintf("[%u]=", i); - debug_record(waiting_buffer[i]); - ac_dprintf(" "); - } - ac_dprintf("}\n"); -} - -#endif diff --git a/quantum/action_tapping.h b/quantum/action_tapping.h deleted file mode 100644 index 6b518b829880..000000000000 --- a/quantum/action_tapping.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ - -#pragma once - -/* period of tapping(ms) */ -#ifndef TAPPING_TERM -# define TAPPING_TERM 200 -#endif - -/* period of quick tap(ms) */ -#if !defined(QUICK_TAP_TERM) || QUICK_TAP_TERM > TAPPING_TERM -# define QUICK_TAP_TERM TAPPING_TERM -#endif - -/* tap count needed for toggling a feature */ -#ifndef TAPPING_TOGGLE -# define TAPPING_TOGGLE 5 -#endif - -#define WAITING_BUFFER_SIZE 8 - -#ifndef NO_ACTION_TAPPING -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); -void action_tapping_process(keyrecord_t record); -#endif - -uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record); -uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record); -bool get_permissive_hold(uint16_t keycode, keyrecord_t *record); -bool get_retro_tapping(uint16_t keycode, keyrecord_t *record); -bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record); - -#ifdef DYNAMIC_TAPPING_TERM_ENABLE -extern uint16_t g_tapping_term; -#endif - -#if defined(TAPPING_TERM_PER_KEY) && !defined(NO_ACTION_TAPPING) -# define GET_TAPPING_TERM(keycode, record) get_tapping_term(keycode, record) -#elif defined(DYNAMIC_TAPPING_TERM_ENABLE) && !defined(NO_ACTION_TAPPING) -# define GET_TAPPING_TERM(keycode, record) g_tapping_term -#else -# define GET_TAPPING_TERM(keycode, record) (TAPPING_TERM) -#endif - -#ifdef QUICK_TAP_TERM_PER_KEY -# define GET_QUICK_TAP_TERM(keycode, record) get_quick_tap_term(keycode, record) -#else -# define GET_QUICK_TAP_TERM(keycode, record) (QUICK_TAP_TERM) -#endif diff --git a/quantum/action_util.c b/quantum/action_util.c deleted file mode 100644 index 361f410d2ddf..000000000000 --- a/quantum/action_util.c +++ /dev/null @@ -1,502 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ -#include "host.h" -#include "report.h" -#include "debug.h" -#include "action_util.h" -#include "action_layer.h" -#include "timer.h" -#include "keycode_config.h" -#include - -extern keymap_config_t keymap_config; - -static uint8_t real_mods = 0; -static uint8_t weak_mods = 0; -#ifdef KEY_OVERRIDE_ENABLE -static uint8_t weak_override_mods = 0; -static uint8_t suppressed_mods = 0; -#endif - -// TODO: pointer variable is not needed -// report_keyboard_t keyboard_report = {}; -report_keyboard_t *keyboard_report = &(report_keyboard_t){}; - -extern inline void add_key(uint8_t key); -extern inline void del_key(uint8_t key); -extern inline void clear_keys(void); - -#ifndef NO_ACTION_ONESHOT -static uint8_t oneshot_mods = 0; -static uint8_t oneshot_locked_mods = 0; -uint8_t get_oneshot_locked_mods(void) { - return oneshot_locked_mods; -} -void add_oneshot_locked_mods(uint8_t mods) { - if ((oneshot_locked_mods & mods) != mods) { - oneshot_locked_mods |= mods; - oneshot_locked_mods_changed_kb(oneshot_locked_mods); - } -} -void set_oneshot_locked_mods(uint8_t mods) { - if (mods != oneshot_locked_mods) { - oneshot_locked_mods = mods; - oneshot_locked_mods_changed_kb(oneshot_locked_mods); - } -} -void clear_oneshot_locked_mods(void) { - if (oneshot_locked_mods) { - oneshot_locked_mods = 0; - oneshot_locked_mods_changed_kb(oneshot_locked_mods); - } -} -void del_oneshot_locked_mods(uint8_t mods) { - if (oneshot_locked_mods & mods) { - oneshot_locked_mods &= ~mods; - oneshot_locked_mods_changed_kb(oneshot_locked_mods); - } -} -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) -static uint16_t oneshot_time = 0; -bool has_oneshot_mods_timed_out(void) { - return TIMER_DIFF_16(timer_read(), oneshot_time) >= ONESHOT_TIMEOUT; -} -# else -bool has_oneshot_mods_timed_out(void) { - return false; -} -# endif -#endif - -/* oneshot layer */ -#ifndef NO_ACTION_ONESHOT -/** \brief oneshot_layer_data bits - * LLLL LSSS - * where: - * L => are layer bits - * S => oneshot state bits - */ -static uint8_t oneshot_layer_data = 0; - -inline uint8_t get_oneshot_layer(void) { - return oneshot_layer_data >> 3; -} -inline uint8_t get_oneshot_layer_state(void) { - return oneshot_layer_data & 0b111; -} - -# ifdef SWAP_HANDS_ENABLE -enum { - SHO_OFF, - SHO_ACTIVE, // Swap hands button was pressed, and we didn't send any swapped keys yet - SHO_PRESSED, // Swap hands button is currently pressed - SHO_USED, // Swap hands button is still pressed, and we already sent swapped keys -} swap_hands_oneshot = SHO_OFF; -# endif - -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) -static uint16_t oneshot_layer_time = 0; -inline bool has_oneshot_layer_timed_out(void) { - return TIMER_DIFF_16(timer_read(), oneshot_layer_time) >= ONESHOT_TIMEOUT && !(get_oneshot_layer_state() & ONESHOT_TOGGLED); -} -# ifdef SWAP_HANDS_ENABLE -static uint16_t oneshot_swaphands_time = 0; -inline bool has_oneshot_swaphands_timed_out(void) { - return TIMER_DIFF_16(timer_read(), oneshot_swaphands_time) >= ONESHOT_TIMEOUT && (swap_hands_oneshot == SHO_ACTIVE); -} -# endif -# endif - -# ifdef SWAP_HANDS_ENABLE - -void set_oneshot_swaphands(void) { - swap_hands_oneshot = SHO_PRESSED; - swap_hands = true; -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_swaphands_time = timer_read(); - if (oneshot_layer_time != 0) { - oneshot_layer_time = oneshot_swaphands_time; - } -# endif -} - -void release_oneshot_swaphands(void) { - if (swap_hands_oneshot == SHO_PRESSED) { - swap_hands_oneshot = SHO_ACTIVE; - } - if (swap_hands_oneshot == SHO_USED) { - clear_oneshot_swaphands(); - } -} - -void use_oneshot_swaphands(void) { - if (swap_hands_oneshot == SHO_PRESSED) { - swap_hands_oneshot = SHO_USED; - } - if (swap_hands_oneshot == SHO_ACTIVE) { - clear_oneshot_swaphands(); - } -} - -void clear_oneshot_swaphands(void) { - swap_hands_oneshot = SHO_OFF; - swap_hands = false; -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_swaphands_time = 0; -# endif -} - -# endif - -/** \brief Set oneshot layer - * - * FIXME: needs doc - */ -void set_oneshot_layer(uint8_t layer, uint8_t state) { - if (keymap_config.oneshot_enable) { - oneshot_layer_data = layer << 3 | state; - layer_on(layer); -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_layer_time = timer_read(); -# endif - oneshot_layer_changed_kb(get_oneshot_layer()); - } else { - layer_on(layer); - } -} -/** \brief Reset oneshot layer - * - * FIXME: needs doc - */ -void reset_oneshot_layer(void) { - oneshot_layer_data = 0; -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_layer_time = 0; -# endif - oneshot_layer_changed_kb(get_oneshot_layer()); -} -/** \brief Clear oneshot layer - * - * FIXME: needs doc - */ -void clear_oneshot_layer_state(oneshot_fullfillment_t state) { - uint8_t start_state = oneshot_layer_data; - oneshot_layer_data &= ~state; - if ((!get_oneshot_layer_state() && start_state != oneshot_layer_data) && keymap_config.oneshot_enable) { - layer_off(get_oneshot_layer()); - reset_oneshot_layer(); - } -} -/** \brief Is oneshot layer active - * - * FIXME: needs doc - */ -bool is_oneshot_layer_active(void) { - return get_oneshot_layer_state(); -} - -/** \brief set oneshot - * - * FIXME: needs doc - */ -void oneshot_set(bool active) { - if (keymap_config.oneshot_enable != active) { - keymap_config.oneshot_enable = active; - eeconfig_update_keymap(keymap_config.raw); - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); - dprintf("Oneshot: active: %d\n", active); - } -} - -/** \brief toggle oneshot - * - * FIXME: needs doc - */ -void oneshot_toggle(void) { - oneshot_set(!keymap_config.oneshot_enable); -} - -/** \brief enable oneshot - * - * FIXME: needs doc - */ -void oneshot_enable(void) { - oneshot_set(true); -} - -/** \brief disable oneshot - * - * FIXME: needs doc - */ -void oneshot_disable(void) { - oneshot_set(false); -} - -bool is_oneshot_enabled(void) { - return keymap_config.oneshot_enable; -} - -#endif - -/** \brief Send keyboard report - * - * FIXME: needs doc - */ -void send_keyboard_report(void) { - keyboard_report->mods = real_mods; - keyboard_report->mods |= weak_mods; - -#ifndef NO_ACTION_ONESHOT - if (oneshot_mods) { -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - if (has_oneshot_mods_timed_out()) { - dprintf("Oneshot: timeout\n"); - clear_oneshot_mods(); - } -# endif - keyboard_report->mods |= oneshot_mods; - if (has_anykey(keyboard_report)) { - clear_oneshot_mods(); - } - } - -#endif - -#ifdef KEY_OVERRIDE_ENABLE - // These need to be last to be able to properly control key overrides - keyboard_report->mods &= ~suppressed_mods; - keyboard_report->mods |= weak_override_mods; -#endif - -#ifdef PROTOCOL_VUSB - host_keyboard_send(keyboard_report); -#else - static report_keyboard_t last_report; - - /* Only send the report if there are changes to propagate to the host. */ - if (memcmp(keyboard_report, &last_report, sizeof(report_keyboard_t)) != 0) { - memcpy(&last_report, keyboard_report, sizeof(report_keyboard_t)); - host_keyboard_send(keyboard_report); - } -#endif -} - -/** \brief Get mods - * - * FIXME: needs doc - */ -uint8_t get_mods(void) { - return real_mods; -} -/** \brief add mods - * - * FIXME: needs doc - */ -void add_mods(uint8_t mods) { - real_mods |= mods; -} -/** \brief del mods - * - * FIXME: needs doc - */ -void del_mods(uint8_t mods) { - real_mods &= ~mods; -} -/** \brief set mods - * - * FIXME: needs doc - */ -void set_mods(uint8_t mods) { - real_mods = mods; -} -/** \brief clear mods - * - * FIXME: needs doc - */ -void clear_mods(void) { - real_mods = 0; -} - -/** \brief get weak mods - * - * FIXME: needs doc - */ -uint8_t get_weak_mods(void) { - return weak_mods; -} -/** \brief add weak mods - * - * FIXME: needs doc - */ -void add_weak_mods(uint8_t mods) { - weak_mods |= mods; -} -/** \brief del weak mods - * - * FIXME: needs doc - */ -void del_weak_mods(uint8_t mods) { - weak_mods &= ~mods; -} -/** \brief set weak mods - * - * FIXME: needs doc - */ -void set_weak_mods(uint8_t mods) { - weak_mods = mods; -} -/** \brief clear weak mods - * - * FIXME: needs doc - */ -void clear_weak_mods(void) { - weak_mods = 0; -} - -#ifdef KEY_OVERRIDE_ENABLE -/** \brief set weak mods used by key overrides. DO not call this manually - */ -void set_weak_override_mods(uint8_t mods) { - weak_override_mods = mods; -} -/** \brief clear weak mods used by key overrides. DO not call this manually - */ -void clear_weak_override_mods(void) { - weak_override_mods = 0; -} - -/** \brief set suppressed mods used by key overrides. DO not call this manually - */ -void set_suppressed_override_mods(uint8_t mods) { - suppressed_mods = mods; -} -/** \brief clear suppressed mods used by key overrides. DO not call this manually - */ -void clear_suppressed_override_mods(void) { - suppressed_mods = 0; -} -#endif - -#ifndef NO_ACTION_ONESHOT -/** \brief get oneshot mods - * - * FIXME: needs doc - */ -uint8_t get_oneshot_mods(void) { - return oneshot_mods; -} - -void add_oneshot_mods(uint8_t mods) { - if ((oneshot_mods & mods) != mods) { -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_time = timer_read(); -# endif - oneshot_mods |= mods; - oneshot_mods_changed_kb(mods); - } -} - -void del_oneshot_mods(uint8_t mods) { - if (oneshot_mods & mods) { - oneshot_mods &= ~mods; -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_time = oneshot_mods ? timer_read() : 0; -# endif - oneshot_mods_changed_kb(oneshot_mods); - } -} - -/** \brief set oneshot mods - * - * FIXME: needs doc - */ -void set_oneshot_mods(uint8_t mods) { - if (keymap_config.oneshot_enable) { - if (oneshot_mods != mods) { -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_time = timer_read(); -# endif - oneshot_mods = mods; - oneshot_mods_changed_kb(mods); - } - } -} - -/** \brief clear oneshot mods - * - * FIXME: needs doc - */ -void clear_oneshot_mods(void) { - if (oneshot_mods) { - oneshot_mods = 0; -# if (defined(ONESHOT_TIMEOUT) && (ONESHOT_TIMEOUT > 0)) - oneshot_time = 0; -# endif - oneshot_mods_changed_kb(oneshot_mods); - } -} -#endif - -/** \brief Called when the one shot modifiers have been changed. - * - * \param mods Contains the active modifiers active after the change. - */ -__attribute__((weak)) void oneshot_locked_mods_changed_user(uint8_t mods) {} - -/** \brief Called when the locked one shot modifiers have been changed. - * - * \param mods Contains the active modifiers active after the change. - */ -__attribute__((weak)) void oneshot_locked_mods_changed_kb(uint8_t mods) { - oneshot_locked_mods_changed_user(mods); -} - -/** \brief Called when the one shot modifiers have been changed. - * - * \param mods Contains the active modifiers active after the change. - */ -__attribute__((weak)) void oneshot_mods_changed_user(uint8_t mods) {} - -/** \brief Called when the one shot modifiers have been changed. - * - * \param mods Contains the active modifiers active after the change. - */ -__attribute__((weak)) void oneshot_mods_changed_kb(uint8_t mods) { - oneshot_mods_changed_user(mods); -} - -/** \brief Called when the one shot layers have been changed. - * - * \param layer Contains the layer that is toggled on, or zero when toggled off. - */ -__attribute__((weak)) void oneshot_layer_changed_user(uint8_t layer) {} - -/** \brief Called when the one shot layers have been changed. - * - * \param layer Contains the layer that is toggled on, or zero when toggled off. - */ -__attribute__((weak)) void oneshot_layer_changed_kb(uint8_t layer) { - oneshot_layer_changed_user(layer); -} - -/** \brief inspect keyboard state - * - * FIXME: needs doc - */ -uint8_t has_anymod(void) { - return bitpop(real_mods); -} diff --git a/quantum/action_util.h b/quantum/action_util.h deleted file mode 100644 index 02f6e9e6df2e..000000000000 --- a/quantum/action_util.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include "report.h" -#include "modifiers.h" - -#ifdef __cplusplus -extern "C" { -#endif - -extern report_keyboard_t *keyboard_report; - -void send_keyboard_report(void); - -/* key */ -inline void add_key(uint8_t key) { - add_key_to_report(keyboard_report, key); -} - -inline void del_key(uint8_t key) { - del_key_from_report(keyboard_report, key); -} - -inline void clear_keys(void) { - clear_keys_from_report(keyboard_report); -} - -/* modifier */ -uint8_t get_mods(void); -void add_mods(uint8_t mods); -void del_mods(uint8_t mods); -void set_mods(uint8_t mods); -void clear_mods(void); - -/* weak modifier */ -uint8_t get_weak_mods(void); -void add_weak_mods(uint8_t mods); -void del_weak_mods(uint8_t mods); -void set_weak_mods(uint8_t mods); -void clear_weak_mods(void); - -/* oneshot modifier */ -uint8_t get_oneshot_mods(void); -void add_oneshot_mods(uint8_t mods); -void del_oneshot_mods(uint8_t mods); -void set_oneshot_mods(uint8_t mods); -void clear_oneshot_mods(void); -bool has_oneshot_mods_timed_out(void); - -uint8_t get_oneshot_locked_mods(void); -void add_oneshot_locked_mods(uint8_t mods); -void set_oneshot_locked_mods(uint8_t mods); -void clear_oneshot_locked_mods(void); -void del_oneshot_locked_mods(uint8_t mods); - -typedef enum { ONESHOT_PRESSED = 0b01, ONESHOT_OTHER_KEY_PRESSED = 0b10, ONESHOT_START = 0b11, ONESHOT_TOGGLED = 0b100 } oneshot_fullfillment_t; -void set_oneshot_layer(uint8_t layer, uint8_t state); -uint8_t get_oneshot_layer(void); -void clear_oneshot_layer_state(oneshot_fullfillment_t state); -void reset_oneshot_layer(void); -bool is_oneshot_layer_active(void); -uint8_t get_oneshot_layer_state(void); -bool has_oneshot_layer_timed_out(void); -bool has_oneshot_swaphands_timed_out(void); - -void oneshot_locked_mods_changed_user(uint8_t mods); -void oneshot_locked_mods_changed_kb(uint8_t mods); -void oneshot_mods_changed_user(uint8_t mods); -void oneshot_mods_changed_kb(uint8_t mods); -void oneshot_layer_changed_user(uint8_t layer); -void oneshot_layer_changed_kb(uint8_t layer); - -void oneshot_toggle(void); -void oneshot_enable(void); -void oneshot_disable(void); -bool is_oneshot_enabled(void); - -/* inspect */ -uint8_t has_anymod(void); - -#ifdef SWAP_HANDS_ENABLE -void set_oneshot_swaphands(void); -void release_oneshot_swaphands(void); -void use_oneshot_swaphands(void); -void clear_oneshot_swaphands(void); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/quantum/audio/audio.c b/quantum/audio/audio.c deleted file mode 100644 index 2570ad9cd1ec..000000000000 --- a/quantum/audio/audio.c +++ /dev/null @@ -1,566 +0,0 @@ -/* Copyright 2016-2020 Jack Humbert - * Copyright 2020 JohSchneider - - * 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 . - */ -#include "audio.h" -#include "eeconfig.h" -#include "timer.h" -#include "wait.h" -#include "util.h" - -/* audio system: - * - * audio.[ch] takes care of all overall state, tracking the actively playing - * notes/tones; the notes a SONG consists of; - * ... - * = everything audio-related that is platform agnostic - * - * driver_[avr|chibios]_[dac|pwm] take care of the lower hardware dependent parts, - * specific to each platform and the used subsystem/driver to drive - * the output pins/channels with the calculated frequencies for each - * active tone - * as part of this, the driver has to trigger regular state updates by - * calling 'audio_update_state' through some sort of timer - be it a - * dedicated one or piggybacking on for example the timer used to - * generate a pwm signal/clock. - * - * - * A Note on terminology: - * tone, pitch and frequency are used somewhat interchangeably, in a strict Wikipedia-sense: - * "(Musical) tone, a sound characterized by its duration, pitch (=frequency), - * intensity (=volume), and timbre" - * - intensity/volume is currently not handled at all, although the 'dac_additive' driver could do so - * - timbre is handled globally (TODO: only used with the pwm drivers at the moment) - * - * in musical_note.h a 'note' is the combination of a pitch and a duration - * these are used to create SONG arrays; during playback their frequencies - * are handled as single successive tones, while the durations are - * kept track of in 'audio_update_state' - * - * 'voice' as it is used here, equates to a sort of instrument with its own - * characteristics sound and effects - * the audio system as-is deals only with (possibly multiple) tones of one - * instrument/voice at a time (think: chords). since the number of tones that - * can be reproduced depends on the hardware/driver in use: pwm can only - * reproduce one tone per output/speaker; DACs can reproduce/mix multiple - * when doing additive synthesis. - * - * 'duration' can either be in the beats-per-minute related unit found in - * musical_notes.h, OR in ms; keyboards create SONGs with the former, while - * the internal state of the audio system does its calculations with the later - ms - */ - -#ifndef AUDIO_TONE_STACKSIZE -# define AUDIO_TONE_STACKSIZE 8 -#endif -uint8_t active_tones = 0; // number of tones pushed onto the stack by audio_play_tone - might be more than the hardware is able to reproduce at any single time -musical_tone_t tones[AUDIO_TONE_STACKSIZE]; // stack of currently active tones - -bool playing_melody = false; // playing a SONG? -bool playing_note = false; // or (possibly multiple simultaneous) tones -bool state_changed = false; // global flag, which is set if anything changes with the active_tones - -// melody/SONG related state variables -float (*notes_pointer)[][2]; // SONG, an array of MUSICAL_NOTEs -uint16_t notes_count; // length of the notes_pointer array -bool notes_repeat; // PLAY_SONG or PLAY_LOOP? -uint16_t melody_current_note_duration = 0; // duration of the currently playing note from the active melody, in ms -uint8_t note_tempo = TEMPO_DEFAULT; // beats-per-minute -uint16_t current_note = 0; // index into the array at notes_pointer -bool note_resting = false; // if a short pause was introduced between two notes with the same frequency while playing a melody -uint16_t last_timestamp = 0; - -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -# ifndef AUDIO_MAX_SIMULTANEOUS_TONES -# define AUDIO_MAX_SIMULTANEOUS_TONES 3 -# endif -uint16_t tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -uint8_t tone_multiplexing_index_shift = 0; // offset used on active-tone array access -#endif - -// provided and used by voices.c -extern uint8_t note_timbre; -extern bool glissando; -extern bool vibrato; -extern uint16_t voices_timer; - -#ifndef STARTUP_SONG -# define STARTUP_SONG SONG(STARTUP_SOUND) -#endif -#ifndef AUDIO_ON_SONG -# define AUDIO_ON_SONG SONG(AUDIO_ON_SOUND) -#endif -#ifndef AUDIO_OFF_SONG -# define AUDIO_OFF_SONG SONG(AUDIO_OFF_SOUND) -#endif -float startup_song[][2] = STARTUP_SONG; -float audio_on_song[][2] = AUDIO_ON_SONG; -float audio_off_song[][2] = AUDIO_OFF_SONG; - -static bool audio_initialized = false; -static bool audio_driver_stopped = true; -audio_config_t audio_config; - -void eeconfig_update_audio_current(void) { - eeconfig_update_audio(audio_config.raw); -} - -void audio_init(void) { - if (audio_initialized) { - return; - } - - // Check EEPROM -#ifdef EEPROM_ENABLE - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - audio_config.raw = eeconfig_read_audio(); -#else // EEPROM settings - audio_config.enable = true; -# ifdef AUDIO_CLICKY_ON - audio_config.clicky_enable = true; -# endif -#endif // EEPROM settings - - for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; - } - - if (!audio_initialized) { - audio_driver_initialize(); - audio_initialized = true; - } - stop_all_notes(); -#ifndef AUDIO_INIT_DELAY - audio_startup(); -#endif -} - -void audio_startup(void) { - if (audio_config.enable) { - PLAY_SONG(startup_song); - } - - last_timestamp = timer_read(); -} - -void audio_toggle(void) { - if (audio_config.enable) { - stop_all_notes(); - } - audio_config.enable ^= 1; - eeconfig_update_audio(audio_config.raw); - if (audio_config.enable) { - audio_on_user(); - } else { - audio_off_user(); - } -} - -void audio_on(void) { - audio_config.enable = 1; - eeconfig_update_audio(audio_config.raw); - audio_on_user(); - PLAY_SONG(audio_on_song); -} - -void audio_off(void) { - PLAY_SONG(audio_off_song); - audio_off_user(); - wait_ms(100); - audio_stop_all(); - audio_config.enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -bool audio_is_on(void) { - return (audio_config.enable != 0); -} - -void audio_stop_all(void) { - if (audio_driver_stopped) { - return; - } - - active_tones = 0; - - audio_driver_stop(); - - playing_melody = false; - playing_note = false; - - melody_current_note_duration = 0; - - for (uint8_t i = 0; i < AUDIO_TONE_STACKSIZE; i++) { - tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; - } - - audio_driver_stopped = true; -} - -void audio_stop_tone(float pitch) { - if (pitch < 0.0f) { - pitch = -1 * pitch; - } - - if (playing_note) { - if (!audio_initialized) { - audio_init(); - } - bool found = false; - for (int i = AUDIO_TONE_STACKSIZE - 1; i >= 0; i--) { - found = (tones[i].pitch == pitch); - if (found) { - tones[i] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; - for (int j = i; (j < AUDIO_TONE_STACKSIZE - 1); j++) { - tones[j] = tones[j + 1]; - tones[j + 1] = (musical_tone_t){.time_started = 0, .pitch = -1.0f, .duration = 0}; - } - break; - } - } - if (!found) { - return; - } - - state_changed = true; - active_tones--; - if (active_tones < 0) active_tones = 0; -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - if (tone_multiplexing_index_shift >= active_tones) { - tone_multiplexing_index_shift = 0; - } -#endif - if (active_tones == 0) { - audio_driver_stop(); - audio_driver_stopped = true; - playing_note = false; - } - } -} - -void audio_play_note(float pitch, uint16_t duration) { - if (!audio_config.enable) { - return; - } - - if (!audio_initialized) { - audio_init(); - } - - if (pitch < 0.0f) { - pitch = -1 * pitch; - } - - // round-robin: shifting out old tones, keeping only unique ones - // if the new frequency is already amongst the active tones, shift it to the top of the stack - bool found = false; - for (int i = active_tones - 1; i >= 0; i--) { - found = (tones[i].pitch == pitch); - if (found) { - for (int j = i; (j < active_tones - 1); j++) { - tones[j] = tones[j + 1]; - tones[j + 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration}; - } - return; // since this frequency played already, the hardware was already started - } - } - - // frequency/tone is actually new, so we put it on the top of the stack - active_tones++; - if (active_tones > AUDIO_TONE_STACKSIZE) { - active_tones = AUDIO_TONE_STACKSIZE; - // shift out the oldest tone to make room - for (int i = 0; i < active_tones - 1; i++) { - tones[i] = tones[i + 1]; - } - } - state_changed = true; - playing_note = true; - tones[active_tones - 1] = (musical_tone_t){.time_started = timer_read(), .pitch = pitch, .duration = duration}; - - // TODO: needs to be handled per note/tone -> use its timestamp instead? - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c - - if (audio_driver_stopped) { - audio_driver_start(); - audio_driver_stopped = false; - } -} - -void audio_play_tone(float pitch) { - audio_play_note(pitch, 0xffff); -} - -void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat) { - if (!audio_config.enable) { - audio_stop_all(); - return; - } - - if (!audio_initialized) { - audio_init(); - } - - // Cancel note if a note is playing - if (playing_note) audio_stop_all(); - - playing_melody = true; - note_resting = false; - - notes_pointer = np; - notes_count = n_count; - notes_repeat = n_repeat; - - current_note = 0; // note in the melody-array/list at note_pointer - - // start first note manually, which also starts the audio_driver - // all following/remaining notes are played by 'audio_update_state' - audio_play_note((*notes_pointer)[current_note][0], audio_duration_to_ms((*notes_pointer)[current_note][1])); - last_timestamp = timer_read(); - melody_current_note_duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); -} - -float click[2][2]; -void audio_play_click(uint16_t delay, float pitch, uint16_t duration) { - uint16_t duration_tone = audio_ms_to_duration(duration); - uint16_t duration_delay = audio_ms_to_duration(delay); - - if (delay <= 0.0f) { - click[0][0] = pitch; - click[0][1] = duration_tone; - click[1][0] = 0.0f; - click[1][1] = 0.0f; - audio_play_melody(&click, 1, false); - } else { - // first note is a rest/pause - click[0][0] = 0.0f; - click[0][1] = duration_delay; - // second note is the actual click - click[1][0] = pitch; - click[1][1] = duration_tone; - audio_play_melody(&click, 2, false); - } -} - -bool audio_is_playing_note(void) { - return playing_note; -} - -bool audio_is_playing_melody(void) { - return playing_melody; -} - -uint8_t audio_get_number_of_active_tones(void) { - return active_tones; -} - -float audio_get_frequency(uint8_t tone_index) { - if (tone_index >= active_tones) { - return 0.0f; - } - return tones[active_tones - tone_index - 1].pitch; -} - -float audio_get_processed_frequency(uint8_t tone_index) { - if (tone_index >= active_tones) { - return 0.0f; - } - - int8_t index = active_tones - tone_index - 1; - // new tones are stacked on top (= appended at the end), so the most recent/current is MAX-1 - -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - index = index - tone_multiplexing_index_shift; - if (index < 0) // wrap around - index += active_tones; -#endif - - if (tones[index].pitch <= 0.0f) { - return 0.0f; - } - - return voice_envelope(tones[index].pitch); -} - -bool audio_update_state(void) { - if (!playing_note && !playing_melody) { - return false; - } - - bool goto_next_note = false; - uint16_t current_time = timer_read(); - - if (playing_melody) { - goto_next_note = timer_elapsed(last_timestamp) >= melody_current_note_duration; - if (goto_next_note) { - uint16_t delta = timer_elapsed(last_timestamp) - melody_current_note_duration; - last_timestamp = current_time; - uint16_t previous_note = current_note; - current_note++; - voices_timer = timer_read(); // reset to zero, for the effects added by voices.c - - if (current_note >= notes_count) { - if (notes_repeat) { - current_note = 0; - } else { - audio_stop_all(); - return false; - } - } - - if (!note_resting && (*notes_pointer)[previous_note][0] == (*notes_pointer)[current_note][0]) { - note_resting = true; - - // special handling for successive notes of the same frequency: - // insert a short pause to separate them audibly - audio_play_note(0.0f, audio_duration_to_ms(2)); - current_note = previous_note; - melody_current_note_duration = audio_duration_to_ms(2); - - } else { - note_resting = false; - - // TODO: handle glissando here (or remember previous and current tone) - /* there would need to be a freq(here we are) -> freq(next note) - * and do slide/glissando in between problem here is to know which - * frequency on the stack relates to what other? e.g. a melody starts - * tones in a sequence, and stops expiring one, so the most recently - * stopped is the starting point for a glissando to the most recently started? - * how to detect and preserve this relation? - * and what about user input, chords, ...? - */ - - // '- delta': Skip forward in the next note's length if we've over shot - // the last, so the overall length of the song is the same - uint16_t duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); - - // Skip forward past any completely missed notes - while (delta > duration && current_note < notes_count - 1) { - delta -= duration; - current_note++; - duration = audio_duration_to_ms((*notes_pointer)[current_note][1]); - } - - if (delta < duration) { - duration -= delta; - } else { - // Only way to get here is if it is the last note and - // we have completely missed it. Play it for 1ms... - duration = 1; - } - - audio_play_note((*notes_pointer)[current_note][0], duration); - melody_current_note_duration = duration; - } - } - } - - if (playing_note) { -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING - tone_multiplexing_index_shift = (int)(current_time / tone_multiplexing_rate) % MIN(AUDIO_MAX_SIMULTANEOUS_TONES, active_tones); - goto_next_note = true; -#endif - if (vibrato || glissando) { - // force update on each cycle, since vibrato shifts the frequency slightly - goto_next_note = true; - } - - // housekeeping: stop notes that have no playtime left - for (int i = 0; i < active_tones; i++) { - if ((tones[i].duration != 0xffff) // indefinitely playing notes, started by 'audio_play_tone' - && (tones[i].duration != 0) // 'uninitialized' - ) { - if (timer_elapsed(tones[i].time_started) >= tones[i].duration) { - audio_stop_tone(tones[i].pitch); // also sets 'state_changed=true' - } - } - } - } - - // state-changes have a higher priority, always triggering the hardware to update - if (state_changed) { - state_changed = false; - return true; - } - - return goto_next_note; -} - -// Tone-multiplexing functions -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -void audio_set_tone_multiplexing_rate(uint16_t rate) { - tone_multiplexing_rate = rate; -} -void audio_enable_tone_multiplexing(void) { - tone_multiplexing_rate = AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT; -} -void audio_disable_tone_multiplexing(void) { - tone_multiplexing_rate = 0; -} -void audio_increase_tone_multiplexing_rate(uint16_t change) { - if ((0xffff - change) > tone_multiplexing_rate) { - tone_multiplexing_rate += change; - } -} -void audio_decrease_tone_multiplexing_rate(uint16_t change) { - if (change <= tone_multiplexing_rate) { - tone_multiplexing_rate -= change; - } -} -#endif - -// Tempo functions - -void audio_set_tempo(uint8_t tempo) { - if (tempo < 10) note_tempo = 10; - // else if (tempo > 250) - // note_tempo = 250; - else - note_tempo = tempo; -} - -void audio_increase_tempo(uint8_t tempo_change) { - if (tempo_change > 255 - note_tempo) - note_tempo = 255; - else - note_tempo += tempo_change; -} - -void audio_decrease_tempo(uint8_t tempo_change) { - if (tempo_change >= note_tempo - 10) - note_tempo = 10; - else - note_tempo -= tempo_change; -} - -// TODO in the int-math version are some bugs; songs sometimes abruptly end - maybe an issue with the timer/system-tick wrapping around? -uint16_t audio_duration_to_ms(uint16_t duration_bpm) { -#if defined(__AVR__) - // doing int-math saves us some bytes in the overall firmware size, but the intermediate result is less accurate before being cast to/returned as uint - return ((uint32_t)duration_bpm * 60 * 1000) / (64 * note_tempo); - // NOTE: beware of uint16_t overflows when note_tempo is low and/or the duration is long -#else - return ((float)duration_bpm * 60) / (64 * note_tempo) * 1000; -#endif -} -uint16_t audio_ms_to_duration(uint16_t duration_ms) { -#if defined(__AVR__) - return ((uint32_t)duration_ms * 64 * note_tempo) / 60 / 1000; -#else - return ((float)duration_ms * 64 * note_tempo) / 60 / 1000; -#endif -} diff --git a/quantum/audio/audio.h b/quantum/audio/audio.h deleted file mode 100644 index 75016a1100b2..000000000000 --- a/quantum/audio/audio.h +++ /dev/null @@ -1,282 +0,0 @@ -/* Copyright 2016-2020 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 . - */ -#pragma once - -#include -#include -#include "musical_notes.h" -#include "song_list.h" -#include "voices.h" -#include "quantum.h" -#include - -#if defined(__AVR__) -# include -#endif - -#if defined(AUDIO_DRIVER_PWM) -# include "audio_pwm.h" -#elif defined(AUDIO_DRIVER_DAC) -# include "audio_dac.h" -#endif - -typedef union { - uint8_t raw; - struct { - bool enable : 1; - bool clicky_enable : 1; - uint8_t level : 6; - }; -} audio_config_t; - -_Static_assert(sizeof(audio_config_t) == sizeof(uint8_t), "Audio EECONFIG out of spec."); - -/* - * a 'musical note' is represented by pitch and duration; a 'musical tone' adds intensity and timbre - * https://en.wikipedia.org/wiki/Musical_tone - * "A musical tone is characterized by its duration, pitch, intensity (or loudness), and timbre (or quality)" - */ -typedef struct { - uint16_t time_started; // timestamp the tone/note was started, system time runs with 1ms resolution -> 16bit timer overflows every ~64 seconds, long enough under normal circumstances; but might be too soon for long-duration notes when the note_tempo is set to a very low value - float pitch; // aka frequency, in Hz - uint16_t duration; // in ms, converted from the musical_notes.h unit which has 64parts to a beat, factoring in the current tempo in beats-per-minute - // float intensity; // aka volume [0,1] TODO: not used at the moment; pwm drivers can't handle it - // uint8_t timbre; // range: [0,100] TODO: this currently kept track of globally, should we do this per tone instead? -} musical_tone_t; - -// public interface - -/** - * @brief Save the current choices to the eeprom - */ -void eeconfig_update_audio_current(void); - -/** - * @brief one-time initialization called by quantum/quantum.c - * @details usually done lazy, when some tones are to be played - * - * @post audio system (and hardware) initialized and ready to play tones - */ -void audio_init(void); -void audio_startup(void); - -/** - * @brief en-/disable audio output, save this choice to the eeprom - */ -void audio_toggle(void); -/** - * @brief enable audio output, save this choice to the eeprom - */ -void audio_on(void); -/** - * @brief disable audio output, save this choice to the eeprom - */ -void audio_off(void); -/** - * @brief query the if audio output is enabled - */ -bool audio_is_on(void); - -/** - * @brief start playback of a tone with the given frequency and duration - * - * @details starts the playback of a given note, which is automatically stopped - * at the the end of its duration = fire&forget - * - * @param[in] pitch frequency of the tone be played - * @param[in] duration in milliseconds, use 'audio_duration_to_ms' to convert - * from the musical_notes.h unit to ms - */ -void audio_play_note(float pitch, uint16_t duration); -// TODO: audio_play_note(float pitch, uint16_t duration, float intensity, float timbre); -// audio_play_note_with_instrument ifdef AUDIO_ENABLE_VOICES - -/** - * @brief start playback of a tone with the given frequency - * - * @details the 'frequency' is put on-top the internal stack of active tones, - * as a new tone with indefinite duration. this tone is played by - * the hardware until a call to 'audio_stop_tone'. - * should a tone with that frequency already be active, its entry - * is put on the top of said internal stack - so no duplicate - * entries are kept. - * 'hardware_start' is called upon the first note. - * - * @param[in] pitch frequency of the tone be played - */ -void audio_play_tone(float pitch); - -/** - * @brief stop a given tone/frequency - * - * @details removes a tone matching the given frequency from the internal - * playback stack - * the hardware is stopped in case this was the last/only frequency - * being played. - * - * @param[in] pitch tone/frequency to be stopped - */ -void audio_stop_tone(float pitch); - -/** - * @brief play a melody - * - * @details starts playback of a melody passed in from a SONG definition - an - * array of {pitch, duration} float-tuples - * - * @param[in] np note-pointer to the SONG array - * @param[in] n_count number of MUSICAL_NOTES of the SONG - * @param[in] n_repeat false for onetime, true for looped playback - */ -void audio_play_melody(float (*np)[][2], uint16_t n_count, bool n_repeat); - -/** - * @brief play a short tone of a specific frequency to emulate a 'click' - * - * @details constructs a two-note melody (one pause plus a note) and plays it through - * audio_play_melody. very short durations might not quite work due to - * hardware limitations (DAC: added pulses from zero-crossing feature;...) - * - * @param[in] delay in milliseconds, length for the pause before the pulses, can be zero - * @param[in] pitch - * @param[in] duration in milliseconds, length of the 'click' - */ -void audio_play_click(uint16_t delay, float pitch, uint16_t duration); - -/** - * @brief stops all playback - * - * @details stops playback of both a melody as well as single tones, resetting - * the internal state - */ -void audio_stop_all(void); - -/** - * @brief query if one/multiple tones are playing - */ -bool audio_is_playing_note(void); - -/** - * @brief query if a melody/SONG is playing - */ -bool audio_is_playing_melody(void); - -// These macros are used to allow audio_play_melody to play an array of indeterminate -// length. This works around the limitation of C's sizeof operation on pointers. -// The global float array for the song must be used here. -#define NOTE_ARRAY_SIZE(x) ((int16_t)(sizeof(x) / (sizeof(x[0])))) - -/** - * @brief convenience macro, to play a melody/SONG once - */ -#define PLAY_SONG(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), false) -// TODO: a 'song' is a melody plus singing/vocals -> PLAY_MELODY -/** - * @brief convenience macro, to play a melody/SONG in a loop, until stopped by 'audio_stop_all' - */ -#define PLAY_LOOP(note_array) audio_play_melody(¬e_array, NOTE_ARRAY_SIZE((note_array)), true) - -// Tone-Multiplexing functions -// this feature only makes sense for hardware setups which can't do proper -// audio-wave synthesis = have no DAC and need to use PWM for tone generation -#ifdef AUDIO_ENABLE_TONE_MULTIPLEXING -# ifndef AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT -# define AUDIO_TONE_MULTIPLEXING_RATE_DEFAULT 0 -// 0=off, good starting value is 4; the lower the value the higher the cpu-load -# endif -void audio_set_tone_multiplexing_rate(uint16_t rate); -void audio_enable_tone_multiplexing(void); -void audio_disable_tone_multiplexing(void); -void audio_increase_tone_multiplexing_rate(uint16_t change); -void audio_decrease_tone_multiplexing_rate(uint16_t change); -#endif - -// Tempo functions - -void audio_set_tempo(uint8_t tempo); -void audio_increase_tempo(uint8_t tempo_change); -void audio_decrease_tempo(uint8_t tempo_change); - -// conversion macros, from 64parts-to-a-beat to milliseconds and back -uint16_t audio_duration_to_ms(uint16_t duration_bpm); -uint16_t audio_ms_to_duration(uint16_t duration_ms); - -void audio_startup(void); - -// hardware interface - -// implementation in the driver_avr/arm_* respective parts -void audio_driver_initialize(void); -void audio_driver_start(void); -void audio_driver_stop(void); - -/** - * @brief get the number of currently active tones - * @return number, 0=none active - */ -uint8_t audio_get_number_of_active_tones(void); - -/** - * @brief access to the raw/unprocessed frequency for a specific tone - * @details each active tone has a frequency associated with it, which - * the internal state keeps track of, and is usually influenced - * by various effects - * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the - * first being the most recent and each increment yielding the next - * older one - * @return a positive frequency, in Hz; or zero if the tone is a pause - */ -float audio_get_frequency(uint8_t tone_index); - -/** - * @brief calculate and return the frequency for the requested tone - * @details effects like glissando, vibrato, ... are post-processed onto the - * each active tones 'base'-frequency; this function returns the - * post-processed result. - * @param[in] tone_index, ranging from 0 to number_of_active_tones-1, with the - * first being the most recent and each increment yielding the next - * older one - * @return a positive frequency, in Hz; or zero if the tone is a pause - */ -float audio_get_processed_frequency(uint8_t tone_index); - -/** - * @brief update audio internal state: currently playing and active tones,... - * @details This function is intended to be called by the audio-hardware - * specific implementation on a somewhat regular basis while a SONG - * or notes (pitch+duration) are playing to 'advance' the internal - * state (current playing notes, position in the melody, ...) - * - * @return true if something changed in the currently active tones, which the - * hardware might need to react to - */ -bool audio_update_state(void); - -// legacy and back-warts compatibility stuff - -#define is_audio_on() audio_is_on() -#define is_playing_notes() audio_is_playing_melody() -#define is_playing_note() audio_is_playing_note() -#define stop_all_notes() audio_stop_all() -#define stop_note(f) audio_stop_tone(f) -#define play_note(f, v) audio_play_tone(f) - -#define set_timbre(t) voice_set_timbre(t) -#define set_tempo(t) audio_set_tempo(t) -#define increase_tempo(t) audio_increase_tempo(t) -#define decrease_tempo(t) audio_decrease_tempo(t) -// vibrato functions are not used in any keyboards diff --git a/quantum/audio/luts.c b/quantum/audio/luts.c deleted file mode 100644 index e8f77a0f331e..000000000000 --- a/quantum/audio/luts.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2016 IBNobody - * - * 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 . - */ - -#include "luts.h" - -const float vibrato_lut[VIBRATO_LUT_LENGTH] = { - 1.0022336811487, 1.0042529943610, 1.0058584256028, 1.0068905285205, 1.0072464122237, 1.0068905285205, 1.0058584256028, 1.0042529943610, 1.0022336811487, 1.0000000000000, 0.9977712970630, 0.9957650169978, 0.9941756956510, 0.9931566259436, 0.9928057204913, 0.9931566259436, 0.9941756956510, 0.9957650169978, 0.9977712970630, 1.0000000000000, -}; - -const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH] = { - 0x8E0B, 0x8C02, 0x8A00, 0x8805, 0x8612, 0x8426, 0x8241, 0x8063, 0x7E8C, 0x7CBB, 0x7AF2, 0x792E, 0x7772, 0x75BB, 0x740B, 0x7261, 0x70BD, 0x6F20, 0x6D88, 0x6BF6, 0x6A69, 0x68E3, 0x6762, 0x65E6, 0x6470, 0x6300, 0x6194, 0x602E, 0x5ECD, 0x5D71, 0x5C1A, 0x5AC8, 0x597B, 0x5833, 0x56EF, 0x55B0, 0x5475, 0x533F, 0x520E, 0x50E1, 0x4FB8, 0x4E93, 0x4D73, 0x4C57, 0x4B3E, 0x4A2A, 0x491A, 0x480E, 0x4705, 0x4601, 0x4500, 0x4402, 0x4309, 0x4213, 0x4120, 0x4031, 0x3F46, 0x3E5D, 0x3D79, 0x3C97, 0x3BB9, 0x3ADD, 0x3A05, 0x3930, 0x385E, 0x3790, 0x36C4, 0x35FB, 0x3534, 0x3471, 0x33B1, 0x32F3, 0x3238, 0x3180, 0x30CA, 0x3017, 0x2F66, 0x2EB8, 0x2E0D, 0x2D64, 0x2CBD, 0x2C19, 0x2B77, 0x2AD8, 0x2A3A, 0x299F, 0x2907, 0x2870, 0x27DC, 0x2749, 0x26B9, 0x262B, 0x259F, 0x2515, 0x248D, 0x2407, 0x2382, 0x2300, 0x2280, 0x2201, 0x2184, 0x2109, 0x2090, 0x2018, 0x1FA3, 0x1F2E, 0x1EBC, 0x1E4B, 0x1DDC, 0x1D6E, 0x1D02, 0x1C98, 0x1C2F, 0x1BC8, 0x1B62, 0x1AFD, 0x1A9A, - 0x1A38, 0x19D8, 0x1979, 0x191C, 0x18C0, 0x1865, 0x180B, 0x17B3, 0x175C, 0x1706, 0x16B2, 0x165E, 0x160C, 0x15BB, 0x156C, 0x151D, 0x14CF, 0x1483, 0x1438, 0x13EE, 0x13A4, 0x135C, 0x1315, 0x12CF, 0x128A, 0x1246, 0x1203, 0x11C1, 0x1180, 0x1140, 0x1100, 0x10C2, 0x1084, 0x1048, 0x100C, 0xFD1, 0xF97, 0xF5E, 0xF25, 0xEEE, 0xEB7, 0xE81, 0xE4C, 0xE17, 0xDE4, 0xDB1, 0xD7E, 0xD4D, 0xD1C, 0xCEC, 0xCBC, 0xC8E, 0xC60, 0xC32, 0xC05, 0xBD9, 0xBAE, 0xB83, 0xB59, 0xB2F, 0xB06, 0xADD, 0xAB6, 0xA8E, 0xA67, 0xA41, 0xA1C, 0x9F7, 0x9D2, 0x9AE, 0x98A, 0x967, 0x945, 0x923, 0x901, 0x8E0, 0x8C0, 0x8A0, 0x880, 0x861, 0x842, 0x824, 0x806, 0x7E8, 0x7CB, 0x7AF, 0x792, 0x777, 0x75B, 0x740, 0x726, 0x70B, 0x6F2, 0x6D8, 0x6BF, 0x6A6, 0x68E, 0x676, 0x65E, 0x647, 0x630, 0x619, 0x602, 0x5EC, 0x5D7, 0x5C1, 0x5AC, 0x597, 0x583, 0x56E, 0x55B, 0x547, 0x533, 0x520, 0x50E, 0x4FB, 0x4E9, - 0x4D7, 0x4C5, 0x4B3, 0x4A2, 0x491, 0x480, 0x470, 0x460, 0x450, 0x440, 0x430, 0x421, 0x412, 0x403, 0x3F4, 0x3E5, 0x3D7, 0x3C9, 0x3BB, 0x3AD, 0x3A0, 0x393, 0x385, 0x379, 0x36C, 0x35F, 0x353, 0x347, 0x33B, 0x32F, 0x323, 0x318, 0x30C, 0x301, 0x2F6, 0x2EB, 0x2E0, 0x2D6, 0x2CB, 0x2C1, 0x2B7, 0x2AD, 0x2A3, 0x299, 0x290, 0x287, 0x27D, 0x274, 0x26B, 0x262, 0x259, 0x251, 0x248, 0x240, 0x238, 0x230, 0x228, 0x220, 0x218, 0x210, 0x209, 0x201, 0x1FA, 0x1F2, 0x1EB, 0x1E4, 0x1DD, 0x1D6, 0x1D0, 0x1C9, 0x1C2, 0x1BC, 0x1B6, 0x1AF, 0x1A9, 0x1A3, 0x19D, 0x197, 0x191, 0x18C, 0x186, 0x180, 0x17B, 0x175, 0x170, 0x16B, 0x165, 0x160, 0x15B, 0x156, 0x151, 0x14C, 0x148, 0x143, 0x13E, 0x13A, 0x135, 0x131, 0x12C, 0x128, 0x124, 0x120, 0x11C, 0x118, 0x114, 0x110, 0x10C, 0x108, 0x104, 0x100, 0xFD, 0xF9, 0xF5, 0xF2, 0xEE, -}; diff --git a/quantum/audio/luts.h b/quantum/audio/luts.h deleted file mode 100644 index 8bb04544933a..000000000000 --- a/quantum/audio/luts.h +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright 2016 IBNobody - * - * 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 . - */ - -#pragma once - -#include -#include - -#define VIBRATO_LUT_LENGTH 20 - -#define FREQUENCY_LUT_LENGTH 349 - -extern const float vibrato_lut[VIBRATO_LUT_LENGTH]; -extern const uint16_t frequency_lut[FREQUENCY_LUT_LENGTH]; diff --git a/quantum/audio/muse.c b/quantum/audio/muse.c deleted file mode 100644 index 01b95671fdca..000000000000 --- a/quantum/audio/muse.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "muse.h" - -enum { MUSE_OFF, MUSE_ON, MUSE_C_1_2, MUSE_C1, MUSE_C2, MUSE_C4, MUSE_C8, MUSE_C3, MUSE_C6, MUSE_B1, MUSE_B2, MUSE_B3, MUSE_B4, MUSE_B5, MUSE_B6, MUSE_B7, MUSE_B8, MUSE_B9, MUSE_B10, MUSE_B11, MUSE_B12, MUSE_B13, MUSE_B14, MUSE_B15, MUSE_B16, MUSE_B17, MUSE_B18, MUSE_B19, MUSE_B20, MUSE_B21, MUSE_B22, MUSE_B23, MUSE_B24, MUSE_B25, MUSE_B26, MUSE_B27, MUSE_B28, MUSE_B29, MUSE_B30, MUSE_B31 }; - -bool number_of_ones_to_bool[16] = {1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1}; - -uint8_t muse_interval[4] = {MUSE_B7, MUSE_B19, MUSE_B3, MUSE_B28}; -uint8_t muse_theme[4] = {MUSE_B8, MUSE_B23, MUSE_B18, MUSE_B17}; - -bool muse_timer_1bit = 0; -uint8_t muse_timer_2bit = 0; -uint8_t muse_timer_2bit_counter = 0; -uint8_t muse_timer_4bit = 0; -uint32_t muse_timer_31bit = 0; - -bool bit_for_value(uint8_t value) { - switch (value) { - case MUSE_OFF: - return 0; - case MUSE_ON: - return 1; - case MUSE_C_1_2: - return muse_timer_1bit; - case MUSE_C1: - return (muse_timer_4bit & 1); - case MUSE_C2: - return (muse_timer_4bit & 2); - case MUSE_C4: - return (muse_timer_4bit & 4); - case MUSE_C8: - return (muse_timer_4bit & 8); - case MUSE_C3: - return (muse_timer_2bit & 1); - case MUSE_C6: - return (muse_timer_2bit & 2); - default: - return muse_timer_31bit & (1UL << (value - MUSE_B1)); - } -} - -uint8_t muse_clock_pulse(void) { - bool top = number_of_ones_to_bool[bit_for_value(muse_theme[0]) + (bit_for_value(muse_theme[1]) << 1) + (bit_for_value(muse_theme[2]) << 2) + (bit_for_value(muse_theme[3]) << 3)]; - - if (muse_timer_1bit == 0) { - if (muse_timer_2bit_counter == 0) { - muse_timer_2bit = (muse_timer_2bit + 1) % 4; - } - muse_timer_2bit_counter = (muse_timer_2bit_counter + 1) % 3; - muse_timer_4bit = (muse_timer_4bit + 1) % 16; - muse_timer_31bit = (muse_timer_31bit << 1) + top; - } - - muse_timer_1bit = (muse_timer_1bit + 1) % 2; - - return bit_for_value(muse_interval[0]) + (bit_for_value(muse_interval[1]) << 1) + (bit_for_value(muse_interval[2]) << 2) + (bit_for_value(muse_interval[3]) << 3); -} diff --git a/quantum/audio/muse.h b/quantum/audio/muse.h deleted file mode 100644 index ad2f96e43af6..000000000000 --- a/quantum/audio/muse.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include "quantum.h" -#include "process_audio.h" - -uint8_t muse_clock_pulse(void); diff --git a/quantum/audio/musical_notes.h b/quantum/audio/musical_notes.h deleted file mode 100644 index ddd7d374f576..000000000000 --- a/quantum/audio/musical_notes.h +++ /dev/null @@ -1,234 +0,0 @@ -/* Copyright 2016 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 . - */ -#pragma once - -#ifndef TEMPO_DEFAULT -# define TEMPO_DEFAULT 120 -// in beats-per-minute -#endif - -#define SONG(notes...) \ - { notes } - -// Note Types -#define MUSICAL_NOTE(note, duration) \ - { (NOTE##note), duration } - -#define BREVE_NOTE(note) MUSICAL_NOTE(note, 128) -#define WHOLE_NOTE(note) MUSICAL_NOTE(note, 64) -#define HALF_NOTE(note) MUSICAL_NOTE(note, 32) -#define QUARTER_NOTE(note) MUSICAL_NOTE(note, 16) -#define EIGHTH_NOTE(note) MUSICAL_NOTE(note, 8) -#define SIXTEENTH_NOTE(note) MUSICAL_NOTE(note, 4) -#define THIRTYSECOND_NOTE(note) MUSICAL_NOTE(note, 2) - -#define BREVE_DOT_NOTE(note) MUSICAL_NOTE(note, 128 + 64) -#define WHOLE_DOT_NOTE(note) MUSICAL_NOTE(note, 64 + 32) -#define HALF_DOT_NOTE(note) MUSICAL_NOTE(note, 32 + 16) -#define QUARTER_DOT_NOTE(note) MUSICAL_NOTE(note, 16 + 8) -#define EIGHTH_DOT_NOTE(note) MUSICAL_NOTE(note, 8 + 4) -#define SIXTEENTH_DOT_NOTE(note) MUSICAL_NOTE(note, 4 + 2) -#define THIRTYSECOND_DOT_NOTE(note) MUSICAL_NOTE(note, 2 + 1) -// duration of 64 units == one beat == one whole note -// with a tempo of 60bpm this comes to a length of one second - -// Note Type Shortcuts -#define M__NOTE(note, duration) MUSICAL_NOTE(note, duration) -#define B__NOTE(n) BREVE_NOTE(n) -#define W__NOTE(n) WHOLE_NOTE(n) -#define H__NOTE(n) HALF_NOTE(n) -#define Q__NOTE(n) QUARTER_NOTE(n) -#define E__NOTE(n) EIGHTH_NOTE(n) -#define S__NOTE(n) SIXTEENTH_NOTE(n) -#define T__NOTE(n) THIRTYSECOND_NOTE(n) -#define BD_NOTE(n) BREVE_DOT_NOTE(n) -#define WD_NOTE(n) WHOLE_DOT_NOTE(n) -#define HD_NOTE(n) HALF_DOT_NOTE(n) -#define QD_NOTE(n) QUARTER_DOT_NOTE(n) -#define ED_NOTE(n) EIGHTH_DOT_NOTE(n) -#define SD_NOTE(n) SIXTEENTH_DOT_NOTE(n) -#define TD_NOTE(n) THIRTYSECOND_DOT_NOTE(n) - -// Note Timbre -// Changes how the notes sound -#define TIMBRE_12 12 -#define TIMBRE_25 25 -#define TIMBRE_50 50 -#define TIMBRE_75 75 -#ifndef TIMBRE_DEFAULT -# define TIMBRE_DEFAULT TIMBRE_50 -#endif - -// Notes - # = Octave - -#define NOTE_REST 0.00f - -#define NOTE_C0 16.35f -#define NOTE_CS0 17.32f -#define NOTE_D0 18.35f -#define NOTE_DS0 19.45f -#define NOTE_E0 20.60f -#define NOTE_F0 21.83f -#define NOTE_FS0 23.12f -#define NOTE_G0 24.50f -#define NOTE_GS0 25.96f -#define NOTE_A0 27.50f -#define NOTE_AS0 29.14f -#define NOTE_B0 30.87f -#define NOTE_C1 32.70f -#define NOTE_CS1 34.65f -#define NOTE_D1 36.71f -#define NOTE_DS1 38.89f -#define NOTE_E1 41.20f -#define NOTE_F1 43.65f -#define NOTE_FS1 46.25f -#define NOTE_G1 49.00f -#define NOTE_GS1 51.91f -#define NOTE_A1 55.00f -#define NOTE_AS1 58.27f -#define NOTE_B1 61.74f -#define NOTE_C2 65.41f -#define NOTE_CS2 69.30f -#define NOTE_D2 73.42f -#define NOTE_DS2 77.78f -#define NOTE_E2 82.41f -#define NOTE_F2 87.31f -#define NOTE_FS2 92.50f -#define NOTE_G2 98.00f -#define NOTE_GS2 103.83f -#define NOTE_A2 110.00f -#define NOTE_AS2 116.54f -#define NOTE_B2 123.47f -#define NOTE_C3 130.81f -#define NOTE_CS3 138.59f -#define NOTE_D3 146.83f -#define NOTE_DS3 155.56f -#define NOTE_E3 164.81f -#define NOTE_F3 174.61f -#define NOTE_FS3 185.00f -#define NOTE_G3 196.00f -#define NOTE_GS3 207.65f -#define NOTE_A3 220.00f -#define NOTE_AS3 233.08f -#define NOTE_B3 246.94f -#define NOTE_C4 261.63f -#define NOTE_CS4 277.18f -#define NOTE_D4 293.66f -#define NOTE_DS4 311.13f -#define NOTE_E4 329.63f -#define NOTE_F4 349.23f -#define NOTE_FS4 369.99f -#define NOTE_G4 392.00f -#define NOTE_GS4 415.30f -#define NOTE_A4 440.00f -#define NOTE_AS4 466.16f -#define NOTE_B4 493.88f -#define NOTE_C5 523.25f -#define NOTE_CS5 554.37f -#define NOTE_D5 587.33f -#define NOTE_DS5 622.25f -#define NOTE_E5 659.26f -#define NOTE_F5 698.46f -#define NOTE_FS5 739.99f -#define NOTE_G5 783.99f -#define NOTE_GS5 830.61f -#define NOTE_A5 880.00f -#define NOTE_AS5 932.33f -#define NOTE_B5 987.77f -#define NOTE_C6 1046.50f -#define NOTE_CS6 1108.73f -#define NOTE_D6 1174.66f -#define NOTE_DS6 1244.51f -#define NOTE_E6 1318.51f -#define NOTE_F6 1396.91f -#define NOTE_FS6 1479.98f -#define NOTE_G6 1567.98f -#define NOTE_GS6 1661.22f -#define NOTE_A6 1760.00f -#define NOTE_AS6 1864.66f -#define NOTE_B6 1975.53f -#define NOTE_C7 2093.00f -#define NOTE_CS7 2217.46f -#define NOTE_D7 2349.32f -#define NOTE_DS7 2489.02f -#define NOTE_E7 2637.02f -#define NOTE_F7 2793.83f -#define NOTE_FS7 2959.96f -#define NOTE_G7 3135.96f -#define NOTE_GS7 3322.44f -#define NOTE_A7 3520.00f -#define NOTE_AS7 3729.31f -#define NOTE_B7 3951.07f -#define NOTE_C8 4186.01f -#define NOTE_CS8 4434.92f -#define NOTE_D8 4698.64f -#define NOTE_DS8 4978.03f -#define NOTE_E8 5274.04f -#define NOTE_F8 5587.65f -#define NOTE_FS8 5919.91f -#define NOTE_G8 6271.93f -#define NOTE_GS8 6644.88f -#define NOTE_A8 7040.00f -#define NOTE_AS8 7458.62f -#define NOTE_B8 7902.13f - -// Flat Aliases -#define NOTE_DF0 NOTE_CS0 -#define NOTE_EF0 NOTE_DS0 -#define NOTE_GF0 NOTE_FS0 -#define NOTE_AF0 NOTE_GS0 -#define NOTE_BF0 NOTE_AS0 -#define NOTE_DF1 NOTE_CS1 -#define NOTE_EF1 NOTE_DS1 -#define NOTE_GF1 NOTE_FS1 -#define NOTE_AF1 NOTE_GS1 -#define NOTE_BF1 NOTE_AS1 -#define NOTE_DF2 NOTE_CS2 -#define NOTE_EF2 NOTE_DS2 -#define NOTE_GF2 NOTE_FS2 -#define NOTE_AF2 NOTE_GS2 -#define NOTE_BF2 NOTE_AS2 -#define NOTE_DF3 NOTE_CS3 -#define NOTE_EF3 NOTE_DS3 -#define NOTE_GF3 NOTE_FS3 -#define NOTE_AF3 NOTE_GS3 -#define NOTE_BF3 NOTE_AS3 -#define NOTE_DF4 NOTE_CS4 -#define NOTE_EF4 NOTE_DS4 -#define NOTE_GF4 NOTE_FS4 -#define NOTE_AF4 NOTE_GS4 -#define NOTE_BF4 NOTE_AS4 -#define NOTE_DF5 NOTE_CS5 -#define NOTE_EF5 NOTE_DS5 -#define NOTE_GF5 NOTE_FS5 -#define NOTE_AF5 NOTE_GS5 -#define NOTE_BF5 NOTE_AS5 -#define NOTE_DF6 NOTE_CS6 -#define NOTE_EF6 NOTE_DS6 -#define NOTE_GF6 NOTE_FS6 -#define NOTE_AF6 NOTE_GS6 -#define NOTE_BF6 NOTE_AS6 -#define NOTE_DF7 NOTE_CS7 -#define NOTE_EF7 NOTE_DS7 -#define NOTE_GF7 NOTE_FS7 -#define NOTE_AF7 NOTE_GS7 -#define NOTE_BF7 NOTE_AS7 -#define NOTE_DF8 NOTE_CS8 -#define NOTE_EF8 NOTE_DS8 -#define NOTE_GF8 NOTE_FS8 -#define NOTE_AF8 NOTE_GS8 -#define NOTE_BF8 NOTE_AS8 diff --git a/quantum/audio/song_list.h b/quantum/audio/song_list.h deleted file mode 100644 index ff22e6fe952a..000000000000 --- a/quantum/audio/song_list.h +++ /dev/null @@ -1,281 +0,0 @@ -/* Any song or sound without a license explicitly stated is: - * - * Copyright 2016 Jack Humbert - * Copyright 2017 Zach White - * - * 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 . - */ -#pragma once - -#include "musical_notes.h" - -#if __has_include("user_song_list.h") -# include "user_song_list.h" -#endif // if file exists - -#define NO_SOUND - -/* Ode to Joy - * Author: Friedrich Schiller - + License: Public Domain - */ -#define ODE_TO_JOY Q__NOTE(_E4), Q__NOTE(_E4), Q__NOTE(_F4), Q__NOTE(_G4), Q__NOTE(_G4), Q__NOTE(_F4), Q__NOTE(_E4), Q__NOTE(_D4), Q__NOTE(_C4), Q__NOTE(_C4), Q__NOTE(_D4), Q__NOTE(_E4), QD_NOTE(_E4), E__NOTE(_D4), H__NOTE(_D4), - -/* Rock-a-bye Baby - * Author: Unknown - + License: Public Domain - */ -#define ROCK_A_BYE_BABY QD_NOTE(_B4), E__NOTE(_D4), Q__NOTE(_B5), H__NOTE(_A5), Q__NOTE(_G5), QD_NOTE(_B4), E__NOTE(_D5), Q__NOTE(_G5), H__NOTE(_FS5), - -#define CLUEBOARD_SOUND HD_NOTE(_C3), HD_NOTE(_D3), HD_NOTE(_E3), HD_NOTE(_F3), HD_NOTE(_G3), HD_NOTE(_A4), HD_NOTE(_B4), HD_NOTE(_C4) -/* - HD_NOTE(_G3), HD_NOTE(_E3), HD_NOTE(_C3), \ - Q__NOTE(_E3), Q__NOTE(_C3), Q__NOTE(_G3), \ - Q__NOTE(_E3) -*/ -/* - HD_NOTE(_C3), HD_NOTE(_G3), HD_NOTE(_E3), \ - Q__NOTE(_G3), Q__NOTE(_E3), Q__NOTE(_G3), \ - Q__NOTE(_F3) -*/ - -#define STARTUP_SOUND E__NOTE(_E6), E__NOTE(_A6), ED_NOTE(_E7), - -#define GOODBYE_SOUND E__NOTE(_E7), E__NOTE(_A6), ED_NOTE(_E6), - -#define PLANCK_SOUND ED_NOTE(_E7), E__NOTE(_CS7), E__NOTE(_E6), E__NOTE(_A6), M__NOTE(_CS7, 20), - -#define PREONIC_SOUND M__NOTE(_B5, 20), E__NOTE(_B6), M__NOTE(_DS6, 20), E__NOTE(_B6), - -#define QWERTY_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), Q__NOTE(_E7), - -#define COLEMAK_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_E7), S__NOTE(_REST), ED_NOTE(_GS7), - -#define DVORAK_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), E__NOTE(_E7), S__NOTE(_REST), E__NOTE(_FS7), S__NOTE(_REST), E__NOTE(_E7), - -#define WORKMAN_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_FS7), S__NOTE(_REST), ED_NOTE(_A7), - -#define PLOVER_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_E7), S__NOTE(_REST), ED_NOTE(_A7), - -#define PLOVER_GOODBYE_SOUND E__NOTE(_GS6), E__NOTE(_A6), S__NOTE(_REST), ED_NOTE(_A7), S__NOTE(_REST), ED_NOTE(_E7), - -#define MUSIC_ON_SOUND E__NOTE(_A5), E__NOTE(_B5), E__NOTE(_CS6), E__NOTE(_D6), E__NOTE(_E6), E__NOTE(_FS6), E__NOTE(_GS6), E__NOTE(_A6), - -#define AUDIO_ON_SOUND E__NOTE(_A5), E__NOTE(_A6), - -#define AUDIO_OFF_SOUND E__NOTE(_A6), E__NOTE(_A5), - -#define MUSIC_SCALE_SOUND MUSIC_ON_SOUND - -#define MUSIC_OFF_SOUND E__NOTE(_A6), E__NOTE(_GS6), E__NOTE(_FS6), E__NOTE(_E6), E__NOTE(_D6), E__NOTE(_CS6), E__NOTE(_B5), E__NOTE(_A5), - -#define VOICE_CHANGE_SOUND Q__NOTE(_A5), Q__NOTE(_CS6), Q__NOTE(_E6), Q__NOTE(_A6), - -#define CHROMATIC_SOUND Q__NOTE(_A5), Q__NOTE(_AS5), Q__NOTE(_B5), Q__NOTE(_C6), Q__NOTE(_CS6), - -#define MAJOR_SOUND Q__NOTE(_A5), Q__NOTE(_B5), Q__NOTE(_CS6), Q__NOTE(_D6), Q__NOTE(_E6), - -#define MINOR_SOUND Q__NOTE(_A5), Q__NOTE(_B5), Q__NOTE(_C6), Q__NOTE(_D6), Q__NOTE(_E6), - -#define GUITAR_SOUND Q__NOTE(_E5), Q__NOTE(_A5), Q__NOTE(_D6), Q__NOTE(_G6), - -#define VIOLIN_SOUND Q__NOTE(_G5), Q__NOTE(_D6), Q__NOTE(_A6), Q__NOTE(_E7), - -#define CAPS_LOCK_ON_SOUND E__NOTE(_A3), E__NOTE(_B3), - -#define CAPS_LOCK_OFF_SOUND E__NOTE(_B3), E__NOTE(_A3), - -#define SCROLL_LOCK_ON_SOUND E__NOTE(_D4), E__NOTE(_E4), - -#define SCROLL_LOCK_OFF_SOUND E__NOTE(_E4), E__NOTE(_D4), - -#define NUM_LOCK_ON_SOUND E__NOTE(_D5), E__NOTE(_E5), - -#define NUM_LOCK_OFF_SOUND E__NOTE(_E5), E__NOTE(_D5), - -#define AG_NORM_SOUND E__NOTE(_A5), E__NOTE(_A5), - -#define AG_SWAP_SOUND SD_NOTE(_B5), SD_NOTE(_A5), SD_NOTE(_B5), SD_NOTE(_A5), - -#define UNICODE_WINDOWS E__NOTE(_B5), S__NOTE(_E6), - -#define UNICODE_LINUX E__NOTE(_E6), S__NOTE(_B5), - -#define TERMINAL_SOUND E__NOTE(_C5) - -/* Title: La Campanella - * Author/Composer: Frank Lizst - * License: Public Domain - */ -#define CAMPANELLA \ - Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_E5), E__NOTE(_E5), E__NOTE(_DS6), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_CS5), E__NOTE(_CS5), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_B4), E__NOTE(_B4), E__NOTE(_DS6), Q__NOTE(_AS4), E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_G4), E__NOTE(_G4), E__NOTE(_DS6), Q__NOTE(_GS4), E__NOTE(_GS4), E__NOTE(_DS6), Q__NOTE(_AS4), \ - E__NOTE(_AS4), E__NOTE(_DS6), Q__NOTE(_DS4), E__NOTE(_DS4), E__NOTE(_DS5), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS6), Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), Q__NOTE(_DS6), E__NOTE(_DS6), E__NOTE(_DS7), Q__NOTE(_CS6), E__NOTE(_CS6), E__NOTE(_DS7), Q__NOTE(_B5), E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_B5), E__NOTE(_B5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), E__NOTE(_DS7), Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_G5), E__NOTE(_G5), E__NOTE(_DS7), Q__NOTE(_GS5), E__NOTE(_GS5), E__NOTE(_DS7), Q__NOTE(_AS5), E__NOTE(_AS5), E__NOTE(_DS7), Q__NOTE(_DS5), E__NOTE(_DS5), E__NOTE(_DS7), W__NOTE(_DS6), W__NOTE(_GS5), - -/* Title: Fantaisie-Impromptu - * Author/Composer: Chopin - * License: Public Domain - */ -#define FANTASIE_IMPROMPTU \ - E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_A4), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_CS6), E__NOTE(_DS6), E__NOTE(_B6), E__NOTE(_A6), E__NOTE(_GS6), E__NOTE(_FS6), E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_FS6), E__NOTE(_CS6), E__NOTE(_C5), E__NOTE(_DS6), E__NOTE(_A5), E__NOTE(_GS5), E__NOTE(_FS5), E__NOTE(_A5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_FS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_DS5), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_B4), E__NOTE(_A4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_A4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), \ - E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_GS4), E__NOTE(_AS4), E__NOTE(_GS4), E__NOTE(_REST), E__NOTE(_GS4), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_DS5), E__NOTE(_CS5), E__NOTE(_C5), E__NOTE(_CS5), E__NOTE(_E5), E__NOTE(_GS5), E__NOTE(_DS5), E__NOTE(_E5), E__NOTE(_DS5), E__NOTE(_REST), E__NOTE(_DS5), E__NOTE(_B5), E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_E6), E__NOTE(_DS6), E__NOTE(_CS6), E__NOTE(_B5), E__NOTE(_AS5), E__NOTE(_GS5), E__NOTE(_REST), E__NOTE(_AS5), WD_NOTE(_GS5), - -/* Title: Nocturne Op. 9 No. 1 in B flat minor - * Author/Composer: Chopin - * License: Public Domain - */ -#define NOCTURNE_OP_9_NO_1 \ - H__NOTE(_BF5), H__NOTE(_C6), H__NOTE(_DF6), H__NOTE(_A5), H__NOTE(_BF5), H__NOTE(_GF5), W__NOTE(_F5), W__NOTE(_F5), W__NOTE(_F5), W__NOTE(_F5), H__NOTE(_GF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_C5), B__NOTE(_DF5), W__NOTE(_BF4), Q__NOTE(_BF5), Q__NOTE(_C6), Q__NOTE(_DF6), Q__NOTE(_A5), Q__NOTE(_BF5), Q__NOTE(_A5), Q__NOTE(_GS5), Q__NOTE(_A5), Q__NOTE(_C6), Q__NOTE(_BF5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_GF5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_BF5), Q__NOTE(_A5), Q__NOTE(_AF5), Q__NOTE(_G5), Q__NOTE(_GF5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), Q__NOTE(_D5), Q__NOTE(_DF5), Q__NOTE(_C5), Q__NOTE(_DF5), Q__NOTE(_C5), Q__NOTE(_B4), Q__NOTE(_C5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_EF5), B__NOTE(_DF5), W__NOTE(_BF4), W__NOTE(_BF5), W__NOTE(_BF5), W__NOTE(_BF5), BD_NOTE(_AF5), W__NOTE(_DF5), H__NOTE(_BF4), H__NOTE(_C5), H__NOTE(_DF5), H__NOTE(_GF5), H__NOTE(_GF5), BD_NOTE(_F5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_DF5), H__NOTE(_A4), B__NOTE(_AF4), \ - W__NOTE(_DF5), W__NOTE(_EF5), H__NOTE(_F5), H__NOTE(_EF5), H__NOTE(_DF5), H__NOTE(_EF5), BD_NOTE(_F5), - -/* Title: State Anthem of the Soviet Union - * Author/Composer: Alexander Alexandrov - * License: Public Domain - */ -#define USSR_ANTHEM B__NOTE(_G6), B__NOTE(_C7), W__NOTE(_G6), H__NOTE(_A6), B__NOTE(_B6), W__NOTE(_E6), W__NOTE(_E6), B__NOTE(_A6), W__NOTE(_G6), H__NOTE(_F6), B__NOTE(_G6), W__NOTE(_C6), W__NOTE(_C6), B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_E6), B__NOTE(_D6), W__NOTE(_D6), W__NOTE(_G6), B__NOTE(_F6), W__NOTE(_G6), W__NOTE(_A6), B__NOTE(_B6), - -/* Title: Hymn Risen - * Author/Composer: Terrance Andrew Davis - * License: Public Domain - */ -#define TOS_HYMN_RISEN H__NOTE(_D5), H__NOTE(_E5), HD_NOTE(_F5), HD_NOTE(_F5), H__NOTE(_F5), HD_NOTE(_D5), E__NOTE(_E5), E__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_D5), Q__NOTE(_D5), H__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_G5), Q__NOTE(_F5), H__NOTE(_D5), H__NOTE(_E5), HD_NOTE(_F5), HD_NOTE(_F5), H__NOTE(_F5), HD_NOTE(_D5), E__NOTE(_E5), E__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_D5), Q__NOTE(_D5), H__NOTE(_E5), H__NOTE(_C5), Q__NOTE(_G5), Q__NOTE(_F5), H__NOTE(_D5), H__NOTE(_C5), W__NOTE(_D5), W__NOTE(_E5), Q__NOTE(_A4), H__NOTE(_A4), Q__NOTE(_E5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_D5), Q__NOTE(_G5), Q__NOTE(_B4), Q__NOTE(_D5), Q__NOTE(_C5), M__NOTE(_F5, 80), H__NOTE(_D5), H__NOTE(_C5), W__NOTE(_D5), W__NOTE(_E5), Q__NOTE(_A4), H__NOTE(_A4), Q__NOTE(_E5), Q__NOTE(_E5), Q__NOTE(_F5), Q__NOTE(_E5), Q__NOTE(_D5), Q__NOTE(_G5), Q__NOTE(_B4), Q__NOTE(_D5), Q__NOTE(_C5), M__NOTE(_F5, 80) - -/* Removed sounds - + This list is here solely for compatibility, so that removed songs don't just break things - * If you think that any of these songs were wrongfully removed, let us know and provide - * proof of permission to use them, or public domain status. - */ - -#ifndef CLOSE_ENCOUNTERS_5_NOTE -# define CLOSE_ENCOUNTERS_5_NOTE -#endif -#ifndef DOE_A_DEER -# define DOE_A_DEER -#endif -#ifndef IN_LIKE_FLINT -# define IN_LIKE_FLINT -#endif -#ifndef IMPERIAL_MARCH -# define IMPERIAL_MARCH -#endif -#ifndef BASKET_CASE -# define BASKET_CASE -#endif -#ifndef COIN_SOUND -# define COIN_SOUND -#endif -#ifndef ONE_UP_SOUND -# define ONE_UP_SOUND -#endif -#ifndef SONIC_RING -# define SONIC_RING -#endif -#ifndef ZELDA_PUZZLE -# define ZELDA_PUZZLE -#endif -#ifndef ZELDA_TREASURE -# define ZELDA_TREASURE -#endif -#ifndef OVERWATCH_THEME -# define OVERWATCH_THEME -#endif -#ifndef MARIO_THEME -# define MARIO_THEME -#endif -#ifndef MARIO_GAMEOVER -# define MARIO_GAMEOVER -#endif -#ifndef MARIO_MUSHROOM -# define MARIO_MUSHROOM -#endif -#ifndef E1M1_DOOM -# define E1M1_DOOM -#endif -#ifndef DISNEY_SONG -# define DISNEY_SONG -#endif -#ifndef NUMBER_ONE -# define NUMBER_ONE -#endif -#ifndef CABBAGE_SONG -# define CABBAGE_SONG -#endif -#ifndef OLD_SPICE -# define OLD_SPICE -#endif -#ifndef VICTORY_FANFARE_SHORT -# define VICTORY_FANFARE_SHORT -#endif -#ifndef ALL_STAR -# define ALL_STAR -#endif -#ifndef RICK_ROLL -# define RICK_ROLL -#endif -#ifndef FF_PRELUDE -# define FF_PRELUDE -#endif -#ifndef TO_BOLDLY_GO -# define TO_BOLDLY_GO -#endif -#ifndef KATAWARE_DOKI -# define KATAWARE_DOKI -#endif -#ifndef MEGALOVANIA -# define MEGALOVANIA -#endif -#ifndef MICHISHIRUBE -# define MICHISHIRUBE -#endif -#ifndef LIEBESLEID -# define LIEBESLEID -#endif -#ifndef MELODIES_OF_LIFE -# define MELODIES_OF_LIFE -#endif -#ifndef EYES_ON_ME -# define EYES_ON_ME -#endif -#ifndef SONG_OF_THE_ANCIENTS -# define SONG_OF_THE_ANCIENTS -#endif -#ifndef NIER_AMUSEMENT_PARK -# define NIER_AMUSEMENT_PARK -#endif -#ifndef COPIED_CITY -# define COPIED_CITY -#endif -#ifndef VAGUE_HOPE_COLD_RAIN -# define VAGUE_HOPE_COLD_RAIN -#endif -#ifndef KAINE_SALVATION -# define KAINE_SALVATION -#endif -#ifndef WEIGHT_OF_THE_WORLD -# define WEIGHT_OF_THE_WORLD -#endif -#ifndef ISABELLAS_LULLABY -# define ISABELLAS_LULLABY -#endif -#ifndef TERRAS_THEME -# define TERRAS_THEME -#endif -#ifndef RENAI_CIRCULATION -# define RENAI_CIRCULATION -#endif -#ifndef PLATINUM_DISCO -# define PLATINUM_DISCO -#endif -#ifndef LP_NUMB -# define LP_NUMB -#endif diff --git a/quantum/audio/voices.c b/quantum/audio/voices.c deleted file mode 100644 index 01f257f4d4e1..000000000000 --- a/quantum/audio/voices.c +++ /dev/null @@ -1,362 +0,0 @@ -/* Copyright 2016 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 . - */ -#include "voices.h" -#include "audio.h" -#include - -uint8_t note_timbre = TIMBRE_DEFAULT; -bool glissando = false; -bool vibrato = false; -float vibrato_strength = 0.5; -float vibrato_rate = 0.125; - -uint16_t voices_timer = 0; - -#ifdef AUDIO_VOICE_DEFAULT -voice_type voice = AUDIO_VOICE_DEFAULT; -#else -voice_type voice = default_voice; -#endif - -void set_voice(voice_type v) { - voice = v; -} - -void voice_iterate(void) { - voice = (voice + 1) % number_of_voices; -} - -void voice_deiterate(void) { - voice = (voice - 1 + number_of_voices) % number_of_voices; -} - -#ifdef AUDIO_VOICES -float mod(float a, int b) { - float r = fmod(a, b); - return r < 0 ? r + b : r; -} - -// Effect: 'vibrate' a given target frequency slightly above/below its initial value -float voice_add_vibrato(float average_freq) { - float vibrato_counter = mod(timer_read() / (100 * vibrato_rate), VIBRATO_LUT_LENGTH); - - return average_freq * pow(vibrato_lut[(int)vibrato_counter], vibrato_strength); -} - -// Effect: 'slides' the 'frequency' from the starting-point, to the target frequency -float voice_add_glissando(float from_freq, float to_freq) { - if (to_freq != 0 && from_freq < to_freq && from_freq < to_freq * pow(2, -440 / to_freq / 12 / 2)) { - return from_freq * pow(2, 440 / from_freq / 12 / 2); - } else if (to_freq != 0 && from_freq > to_freq && from_freq > to_freq * pow(2, 440 / to_freq / 12 / 2)) { - return from_freq * pow(2, -440 / from_freq / 12 / 2); - } else { - return to_freq; - } -} -#endif - -float voice_envelope(float frequency) { - // envelope_index ranges from 0 to 0xFFFF, which is preserved at 880.0 Hz -// __attribute__((unused)) uint16_t compensated_index = (uint16_t)((float)envelope_index * (880.0 / frequency)); -#ifdef AUDIO_VOICES - uint16_t envelope_index = timer_elapsed(voices_timer); // TODO: multiply in some factor? - uint16_t compensated_index = envelope_index / 100; // TODO: correct factor would be? -#endif - - switch (voice) { - case default_voice: - glissando = false; - // note_timbre = TIMBRE_50; //Note: leave the user the possibility to adjust the timbre with 'audio_set_timbre' - break; - -#ifdef AUDIO_VOICES - - case vibrating: - glissando = false; - vibrato = true; - break; - - case something: - glissando = false; - switch (compensated_index) { - case 0 ... 9: - note_timbre = TIMBRE_12; - break; - - case 10 ... 19: - note_timbre = TIMBRE_25; - break; - - case 20 ... 200: - note_timbre = 12 + 12; - break; - - default: - note_timbre = 12; - break; - } - break; - - case drums: - glissando = false; - // switch (compensated_index) { - // case 0 ... 10: - // note_timbre = 50; - // break; - // case 11 ... 20: - // note_timbre = 50 * (21 - compensated_index) / 10; - // break; - // default: - // note_timbre = 0; - // break; - // } - // frequency = (rand() % (int)(frequency * 1.2 - frequency)) + (frequency * 0.8); - - if (frequency < 80.0) { - } else if (frequency < 160.0) { - // Bass drum: 60 - 100 Hz - frequency = (rand() % (int)(40)) + 60; - switch (envelope_index) { - case 0 ... 10: - note_timbre = 50; - break; - case 11 ... 20: - note_timbre = 50 * (21 - envelope_index) / 10; - break; - default: - note_timbre = 0; - break; - } - - } else if (frequency < 320.0) { - // Snare drum: 1 - 2 KHz - frequency = (rand() % (int)(1000)) + 1000; - switch (envelope_index) { - case 0 ... 5: - note_timbre = 50; - break; - case 6 ... 20: - note_timbre = 50 * (21 - envelope_index) / 15; - break; - default: - note_timbre = 0; - break; - } - - } else if (frequency < 640.0) { - // Closed Hi-hat: 3 - 5 KHz - frequency = (rand() % (int)(2000)) + 3000; - switch (envelope_index) { - case 0 ... 15: - note_timbre = 50; - break; - case 16 ... 20: - note_timbre = 50 * (21 - envelope_index) / 5; - break; - default: - note_timbre = 0; - break; - } - - } else if (frequency < 1280.0) { - // Open Hi-hat: 3 - 5 KHz - frequency = (rand() % (int)(2000)) + 3000; - switch (envelope_index) { - case 0 ... 35: - note_timbre = 50; - break; - case 36 ... 50: - note_timbre = 50 * (51 - envelope_index) / 15; - break; - default: - note_timbre = 0; - break; - } - } - break; - case butts_fader: - glissando = true; - switch (compensated_index) { - case 0 ... 9: - frequency = frequency / 4; - note_timbre = TIMBRE_12; - break; - - case 10 ... 19: - frequency = frequency / 2; - note_timbre = TIMBRE_12; - break; - - case 20 ... 200: - note_timbre = 12 - (uint8_t)(pow(((float)compensated_index - 20) / (200 - 20), 2) * 12.5); - break; - - default: - note_timbre = 0; - break; - } - break; - - // case octave_crunch: - // switch (compensated_index) { - // case 0 ... 9: - // case 20 ... 24: - // case 30 ... 32: - // frequency = frequency / 2; - // note_timbre = TIMBRE_12; - // break; - - // case 10 ... 19: - // case 25 ... 29: - // case 33 ... 35: - // frequency = frequency * 2; - // note_timbre = TIMBRE_12; - // break; - - // default: - // note_timbre = TIMBRE_12; - // break; - // } - // break; - - case duty_osc: - // This slows the loop down a substantial amount, so higher notes may freeze - glissando = true; - switch (compensated_index) { - default: -# define OCS_SPEED 10 -# define OCS_AMP .25 - // sine wave is slow - // note_timbre = (sin((float)compensated_index/10000*OCS_SPEED) * OCS_AMP / 2) + .5; - // triangle wave is a bit faster - note_timbre = (uint8_t)abs((compensated_index * OCS_SPEED % 3000) - 1500) * (OCS_AMP / 1500) + (1 - OCS_AMP) / 2; - break; - } - break; - - case duty_octave_down: - glissando = true; - note_timbre = (uint8_t)(100 * (envelope_index % 2) * .125 + .375 * 2); - if ((envelope_index % 4) == 0) note_timbre = 50; - if ((envelope_index % 8) == 0) note_timbre = 0; - break; - case delayed_vibrato: - glissando = true; - note_timbre = TIMBRE_50; -# define VOICE_VIBRATO_DELAY 150 -# define VOICE_VIBRATO_SPEED 50 - switch (compensated_index) { - case 0 ... VOICE_VIBRATO_DELAY: - break; - default: - // TODO: merge/replace with voice_add_vibrato above - frequency = frequency * vibrato_lut[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1)) / 1000 * VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; - break; - } - break; - // case delayed_vibrato_octave: - // if ((envelope_index % 2) == 1) { - // note_timbre = 55; - // } else { - // note_timbre = 45; - // } - // #define VOICE_VIBRATO_DELAY 150 - // #define VOICE_VIBRATO_SPEED 50 - // switch (compensated_index) { - // case 0 ... VOICE_VIBRATO_DELAY: - // break; - // default: - // frequency = frequency * VIBRATO_LUT[(int)fmod((((float)compensated_index - (VOICE_VIBRATO_DELAY + 1))/1000*VOICE_VIBRATO_SPEED), VIBRATO_LUT_LENGTH)]; - // break; - // } - // break; - // case duty_fifth_down: - // note_timbre = TIMBRE_50; - // if ((envelope_index % 3) == 0) - // note_timbre = TIMBRE_75; - // break; - // case duty_fourth_down: - // note_timbre = 0; - // if ((envelope_index % 12) == 0) - // note_timbre = TIMBRE_75; - // if (((envelope_index % 12) % 4) != 1) - // note_timbre = TIMBRE_75; - // break; - // case duty_third_down: - // note_timbre = TIMBRE_50; - // if ((envelope_index % 5) == 0) - // note_timbre = TIMBRE_75; - // break; - // case duty_fifth_third_down: - // note_timbre = TIMBRE_50; - // if ((envelope_index % 5) == 0) - // note_timbre = TIMBRE_75; - // if ((envelope_index % 3) == 0) - // note_timbre = TIMBRE_25; - // break; - -#endif // AUDIO_VOICES - - default: - break; - } - -#ifdef AUDIO_VOICES - if (vibrato && (vibrato_strength > 0)) { - frequency = voice_add_vibrato(frequency); - } - - if (glissando) { - // TODO: where to keep track of the start-frequency? - // frequency = voice_add_glissando(??, frequency); - } -#endif // AUDIO_VOICES - - return frequency; -} - -// Vibrato functions - -void voice_set_vibrato_rate(float rate) { - vibrato_rate = rate; -} -void voice_increase_vibrato_rate(float change) { - vibrato_rate *= change; -} -void voice_decrease_vibrato_rate(float change) { - vibrato_rate /= change; -} -void voice_set_vibrato_strength(float strength) { - vibrato_strength = strength; -} -void voice_increase_vibrato_strength(float change) { - vibrato_strength *= change; -} -void voice_decrease_vibrato_strength(float change) { - vibrato_strength /= change; -} - -// Timbre functions - -void voice_set_timbre(uint8_t timbre) { - if ((timbre > 0) && (timbre < 100)) { - note_timbre = timbre; - } -} -uint8_t voice_get_timbre(void) { - return note_timbre; -} diff --git a/quantum/audio/voices.h b/quantum/audio/voices.h deleted file mode 100644 index fcab9db55688..000000000000 --- a/quantum/audio/voices.h +++ /dev/null @@ -1,66 +0,0 @@ -/* Copyright 2016 Jack Humbert - * Copyright 2020 JohSchneider - * - * 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 . - */ -#pragma once - -#include -#include -#include "wait.h" -#include "luts.h" - -float voice_envelope(float frequency); - -typedef enum { - default_voice, -#ifdef AUDIO_VOICES - vibrating, - something, - drums, - butts_fader, - octave_crunch, - duty_osc, - duty_octave_down, - delayed_vibrato, -// delayed_vibrato_octave, -// duty_fifth_down, -// duty_fourth_down, -// duty_third_down, -// duty_fifth_third_down, -#endif - number_of_voices // important that this is last -} voice_type; - -void set_voice(voice_type v); -void voice_iterate(void); -void voice_deiterate(void); - -// Vibrato functions -void voice_set_vibrato_rate(float rate); -void voice_increase_vibrato_rate(float change); -void voice_decrease_vibrato_rate(float change); -void voice_set_vibrato_strength(float strength); -void voice_increase_vibrato_strength(float change); -void voice_decrease_vibrato_strength(float change); - -// Timbre functions -/** - * @brief set the global timbre for tones to be played - * @note: only applies to pwm implementations - where it adjusts the duty-cycle - * @note: using any instrument from voices.[ch] other than 'default' may override the set value - * @param[in]: timbre: valid range is (0,100) - */ -void voice_set_timbre(uint8_t timbre); -uint8_t voice_get_timbre(void); diff --git a/quantum/backlight/backlight.c b/quantum/backlight/backlight.c deleted file mode 100644 index 52ec086bb093..000000000000 --- a/quantum/backlight/backlight.c +++ /dev/null @@ -1,277 +0,0 @@ -/* -Copyright 2013 Mathias Andersson - -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 . -*/ - -#include "quantum.h" -#include "backlight.h" -#include "eeprom.h" -#include "eeconfig.h" -#include "debug.h" - -backlight_config_t backlight_config; - -#ifndef BACKLIGHT_DEFAULT_LEVEL -# define BACKLIGHT_DEFAULT_LEVEL BACKLIGHT_LEVELS -#endif - -#ifdef BACKLIGHT_BREATHING -// TODO: migrate to backlight_config_t -static uint8_t breathing_period = BREATHING_PERIOD; -#endif - -/** \brief Backlight initialization - * - * FIXME: needs doc - */ -void backlight_init(void) { - /* check signature */ - if (!eeconfig_is_enabled()) { - eeconfig_init(); - eeconfig_update_backlight_default(); - } - backlight_config.raw = eeconfig_read_backlight(); - if (backlight_config.level > BACKLIGHT_LEVELS) { - backlight_config.level = BACKLIGHT_LEVELS; - } - backlight_set(backlight_config.enable ? backlight_config.level : 0); -} - -/** \brief Backlight increase - * - * FIXME: needs doc - */ -void backlight_increase(void) { - if (backlight_config.level < BACKLIGHT_LEVELS) { - backlight_config.level++; - } - backlight_config.enable = 1; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight increase: %u\n", backlight_config.level); - backlight_set(backlight_config.level); -} - -/** \brief Backlight decrease - * - * FIXME: needs doc - */ -void backlight_decrease(void) { - if (backlight_config.level > 0) { - backlight_config.level--; - backlight_config.enable = !!backlight_config.level; - eeconfig_update_backlight(backlight_config.raw); - } - dprintf("backlight decrease: %u\n", backlight_config.level); - backlight_set(backlight_config.level); -} - -/** \brief Backlight toggle - * - * FIXME: needs doc - */ -void backlight_toggle(void) { - bool enabled = backlight_config.enable; - dprintf("backlight toggle: %u\n", enabled); - if (enabled) - backlight_disable(); - else - backlight_enable(); -} - -/** \brief Enable backlight - * - * FIXME: needs doc - */ -void backlight_enable(void) { - if (backlight_config.enable) return; // do nothing if backlight is already on - - backlight_config.enable = true; - if (backlight_config.raw == 1) // enabled but level == 0 - backlight_config.level = 1; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight enable\n"); - backlight_set(backlight_config.level); -} - -/** \brief Disable backlight - * - * FIXME: needs doc - */ -void backlight_disable(void) { - if (!backlight_config.enable) return; // do nothing if backlight is already off - - backlight_config.enable = false; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight disable\n"); - backlight_set(0); -} - -/** /brief Get the backlight status - * - * FIXME: needs doc - */ -bool is_backlight_enabled(void) { - return backlight_config.enable; -} - -/** \brief Backlight step through levels - * - * FIXME: needs doc - */ -void backlight_step(void) { - backlight_config.level++; - if (backlight_config.level > BACKLIGHT_LEVELS) { - backlight_config.level = 0; - } - backlight_config.enable = !!backlight_config.level; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight step: %u\n", backlight_config.level); - backlight_set(backlight_config.level); -} - -/** \brief Backlight set level without EEPROM update - * - */ -void backlight_level_noeeprom(uint8_t level) { - if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS; - backlight_config.level = level; - backlight_config.enable = !!backlight_config.level; - backlight_set(backlight_config.level); -} - -/** \brief Backlight set level - * - * FIXME: needs doc - */ -void backlight_level(uint8_t level) { - backlight_level_noeeprom(level); - eeconfig_update_backlight(backlight_config.raw); -} - -uint8_t eeconfig_read_backlight(void) { - return eeprom_read_byte(EECONFIG_BACKLIGHT); -} - -void eeconfig_update_backlight(uint8_t val) { - eeprom_update_byte(EECONFIG_BACKLIGHT, val); -} - -void eeconfig_update_backlight_current(void) { - eeconfig_update_backlight(backlight_config.raw); -} - -void eeconfig_update_backlight_default(void) { - backlight_config.enable = 1; -#ifdef BACKLIGHT_DEFAULT_BREATHING - backlight_config.breathing = 1; -#else - backlight_config.breathing = 0; -#endif - backlight_config.level = BACKLIGHT_DEFAULT_LEVEL; - eeconfig_update_backlight(backlight_config.raw); -} - -/** \brief Get backlight level - * - * FIXME: needs doc - */ -uint8_t get_backlight_level(void) { - return backlight_config.level; -} - -#ifdef BACKLIGHT_BREATHING -/** \brief Backlight breathing toggle - * - * FIXME: needs doc - */ -void backlight_toggle_breathing(void) { - bool breathing = backlight_config.breathing; - dprintf("backlight breathing toggle: %u\n", breathing); - if (breathing) - backlight_disable_breathing(); - else - backlight_enable_breathing(); -} - -/** \brief Enable backlight breathing - * - * FIXME: needs doc - */ -void backlight_enable_breathing(void) { - if (backlight_config.breathing) return; // do nothing if breathing is already on - - backlight_config.breathing = true; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight breathing enable\n"); - breathing_enable(); -} - -/** \brief Disable backlight breathing - * - * FIXME: needs doc - */ -void backlight_disable_breathing(void) { - if (!backlight_config.breathing) return; // do nothing if breathing is already off - - backlight_config.breathing = false; - eeconfig_update_backlight(backlight_config.raw); - dprintf("backlight breathing disable\n"); - breathing_disable(); -} - -/** \brief Get the backlight breathing status - * - * FIXME: needs doc - */ -bool is_backlight_breathing(void) { - return backlight_config.breathing; -} - -// following are marked as weak purely for backwards compatibility -__attribute__((weak)) void breathing_period_set(uint8_t value) { - breathing_period = value ? value : 1; -} - -__attribute__((weak)) uint8_t get_breathing_period(void) { - return breathing_period; -} - -__attribute__((weak)) void breathing_period_default(void) { - breathing_period_set(BREATHING_PERIOD); -} - -__attribute__((weak)) void breathing_period_inc(void) { - breathing_period_set(breathing_period + 1); -} - -__attribute__((weak)) void breathing_period_dec(void) { - breathing_period_set(breathing_period - 1); -} - -__attribute__((weak)) void breathing_toggle(void) { - if (is_breathing()) - breathing_disable(); - else - breathing_enable(); -} - -#endif - -// defaults for backlight api -__attribute__((weak)) void backlight_init_ports(void) {} - -__attribute__((weak)) void backlight_set(uint8_t level) {} - -__attribute__((weak)) void backlight_task(void) {} diff --git a/quantum/backlight/backlight.h b/quantum/backlight/backlight.h deleted file mode 100644 index 85812bff3a5e..000000000000 --- a/quantum/backlight/backlight.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 2013 Mathias Andersson - -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 . -*/ - -#pragma once - -#include -#include - -#ifndef BACKLIGHT_LEVELS -# define BACKLIGHT_LEVELS 3 -#elif BACKLIGHT_LEVELS > 31 -# error "Maximum value of BACKLIGHT_LEVELS is 31" -#endif - -#ifndef BACKLIGHT_ON_STATE -# define BACKLIGHT_ON_STATE 1 -#endif - -#ifndef BREATHING_PERIOD -# define BREATHING_PERIOD 6 -#endif - -typedef union { - uint8_t raw; - struct { - bool enable : 1; - bool breathing : 1; - uint8_t reserved : 1; // Reserved for possible future backlight modes - uint8_t level : 5; - }; -} backlight_config_t; - -_Static_assert(sizeof(backlight_config_t) == sizeof(uint8_t), "Backlight EECONFIG out of spec."); - -void backlight_init(void); -void backlight_toggle(void); -void backlight_enable(void); -void backlight_disable(void); -bool is_backlight_enabled(void); -void backlight_step(void); -void backlight_increase(void); -void backlight_decrease(void); -void backlight_level_noeeprom(uint8_t level); -void backlight_level(uint8_t level); -uint8_t get_backlight_level(void); - -uint8_t eeconfig_read_backlight(void); -void eeconfig_update_backlight(uint8_t val); -void eeconfig_update_backlight_current(void); -void eeconfig_update_backlight_default(void); - -// implementation specific -void backlight_init_ports(void); -void backlight_set(uint8_t level); -void backlight_task(void); - -#ifdef BACKLIGHT_BREATHING - -void backlight_toggle_breathing(void); -void backlight_enable_breathing(void); -void backlight_disable_breathing(void); -bool is_backlight_breathing(void); - -void breathing_period_set(uint8_t value); -uint8_t get_breathing_period(void); -void breathing_period_default(void); -void breathing_period_inc(void); -void breathing_period_dec(void); - -void breathing_toggle(void); - -// implementation specific -void breathing_enable(void); -void breathing_disable(void); -bool is_breathing(void); -void breathing_pulse(void); -#endif diff --git a/quantum/backlight/backlight_avr.c b/quantum/backlight/backlight_avr.c deleted file mode 100644 index 474e0a86f5e0..000000000000 --- a/quantum/backlight/backlight_avr.c +++ /dev/null @@ -1,473 +0,0 @@ -#include "quantum.h" -#include "backlight.h" -#include "backlight_driver_common.h" -#include "debug.h" - -// Maximum duty cycle limit -#ifndef BACKLIGHT_LIMIT_VAL -# define BACKLIGHT_LIMIT_VAL 255 -#endif - -// This logic is a bit complex, we support 3 setups: -// -// 1. Hardware PWM when backlight is wired to a PWM pin. -// Depending on this pin, we use a different output compare unit. -// 2. Software PWM with hardware timers, but the used timer -// depends on the Audio setup (Audio wins over Backlight). -// 3. Full software PWM, driven by the matrix scan, if both timers are used by Audio. - -#if (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) && (BACKLIGHT_PIN == B5 || BACKLIGHT_PIN == B6 || BACKLIGHT_PIN == B7) -# define HARDWARE_PWM -# define ICRx ICR1 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TIMSKx TIMSK1 -# define TOIEx TOIE1 - -# if BACKLIGHT_PIN == B5 -# define COMxx0 COM1A0 -# define COMxx1 COM1A1 -# define OCRxx OCR1A -# elif BACKLIGHT_PIN == B6 -# define COMxx0 COM1B0 -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# elif BACKLIGHT_PIN == B7 -# define COMxx0 COM1C0 -# define COMxx1 COM1C1 -# define OCRxx OCR1C -# endif -#elif (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB647__) || defined(__AVR_AT90USB1286__) || defined(__AVR_AT90USB1287__) || defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) && (BACKLIGHT_PIN == C4 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) -# define HARDWARE_PWM -# define ICRx ICR3 -# define TCCRxA TCCR3A -# define TCCRxB TCCR3B -# define TIMERx_OVF_vect TIMER3_OVF_vect -# define TIMSKx TIMSK3 -# define TOIEx TOIE3 - -# if BACKLIGHT_PIN == C4 -# if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) -# error This MCU has no C4 pin! -# else -# define COMxx0 COM3C0 -# define COMxx1 COM3C1 -# define OCRxx OCR3C -# endif -# elif BACKLIGHT_PIN == C5 -# if (defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)) -# error This MCU has no C5 pin! -# else -# define COMxx0 COM3B0 -# define COMxx1 COM3B1 -# define OCRxx OCR3B -# endif -# elif BACKLIGHT_PIN == C6 -# define COMxx0 COM3A0 -# define COMxx1 COM3A1 -# define OCRxx OCR3A -# endif -#elif (defined(__AVR_AT90USB162__) || defined(__AVR_ATmega16U2__) || defined(__AVR_ATmega32U2__)) && (BACKLIGHT_PIN == B7 || BACKLIGHT_PIN == C5 || BACKLIGHT_PIN == C6) -# define HARDWARE_PWM -# define ICRx ICR1 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TIMSKx TIMSK1 -# define TOIEx TOIE1 - -# if BACKLIGHT_PIN == B7 -# define COMxx0 COM1C0 -# define COMxx1 COM1C1 -# define OCRxx OCR1C -# elif BACKLIGHT_PIN == C5 -# define COMxx0 COM1B0 -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# elif BACKLIGHT_PIN == C6 -# define COMxx0 COM1A0 -# define COMxx1 COM1A1 -# define OCRxx OCR1A -# endif -#elif defined(__AVR_ATmega32A__) && (BACKLIGHT_PIN == D4 || BACKLIGHT_PIN == D5) -# define HARDWARE_PWM -# define ICRx ICR1 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TIMSKx TIMSK -# define TOIEx TOIE1 - -# if BACKLIGHT_PIN == D4 -# define COMxx0 COM1B0 -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# elif BACKLIGHT_PIN == D5 -# define COMxx0 COM1A0 -# define COMxx1 COM1A1 -# define OCRxx OCR1A -# endif -#elif (defined(__AVR_ATmega328P__) || defined(__AVR_ATmega328__)) && (BACKLIGHT_PIN == B1 || BACKLIGHT_PIN == B2) -# define HARDWARE_PWM -# define ICRx ICR1 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define TIMERx_OVF_vect TIMER1_OVF_vect -# define TIMSKx TIMSK1 -# define TOIEx TOIE1 - -# if BACKLIGHT_PIN == B1 -# define COMxx0 COM1A0 -# define COMxx1 COM1A1 -# define OCRxx OCR1A -# elif BACKLIGHT_PIN == B2 -# define COMxx0 COM1B0 -# define COMxx1 COM1B1 -# define OCRxx OCR1B -# endif -#elif (AUDIO_PIN != B5) && (AUDIO_PIN != B6) && (AUDIO_PIN != B7) && (AUDIO_PIN_ALT != B5) && (AUDIO_PIN_ALT != B6) && (AUDIO_PIN_ALT != B7) -// Timer 1 is not in use by Audio feature, Backlight can use it -# pragma message "Using hardware timer 1 with software PWM" -# define HARDWARE_PWM -# define BACKLIGHT_PWM_TIMER -# define ICRx ICR1 -# define TCCRxA TCCR1A -# define TCCRxB TCCR1B -# define TIMERx_COMPA_vect TIMER1_COMPA_vect -# define TIMERx_OVF_vect TIMER1_OVF_vect -# if defined(__AVR_ATmega32A__) // This MCU has only one TIMSK register -# define TIMSKx TIMSK -# else -# define TIMSKx TIMSK1 -# endif -# define TOIEx TOIE1 - -# define OCIExA OCIE1A -# define OCRxx OCR1A -#elif (AUDIO_PIN != C4) && (AUDIO_PIN != C5) && (AUDIO_PIN != C6) -# pragma message "Using hardware timer 3 with software PWM" -// Timer 3 is not in use by Audio feature, Backlight can use it -# define HARDWARE_PWM -# define BACKLIGHT_PWM_TIMER -# define ICRx ICR1 -# define TCCRxA TCCR3A -# define TCCRxB TCCR3B -# define TIMERx_COMPA_vect TIMER3_COMPA_vect -# define TIMERx_OVF_vect TIMER3_OVF_vect -# define TIMSKx TIMSK3 -# define TOIEx TOIE3 - -# define OCIExA OCIE3A -# define OCRxx OCR3A -#elif defined(BACKLIGHT_CUSTOM_DRIVER) -error("Please set 'BACKLIGHT_DRIVER = custom' within rules.mk") -#else -error("Please set 'BACKLIGHT_DRIVER = software' within rules.mk") -#endif - -#ifndef BACKLIGHT_PWM_TIMER // pwm through software - -static inline void enable_pwm(void) { -# if BACKLIGHT_ON_STATE == 1 - TCCRxA |= _BV(COMxx1); -# else - TCCRxA |= _BV(COMxx1) | _BV(COMxx0); -# endif -} - -static inline void disable_pwm(void) { -# if BACKLIGHT_ON_STATE == 1 - TCCRxA &= ~(_BV(COMxx1)); -# else - TCCRxA &= ~(_BV(COMxx1) | _BV(COMxx0)); -# endif -} - -#endif - -#ifdef BACKLIGHT_PWM_TIMER - -// The idea of software PWM assisted by hardware timers is the following -// we use the hardware timer in fast PWM mode like for hardware PWM, but -// instead of letting the Output Match Comparator control the led pin -// (which is not possible since the backlight is not wired to PWM pins on the -// CPU), we do the LED on/off by oursleves. -// The timer is setup to count up to 0xFFFF, and we set the Output Compare -// register to the current 16bits backlight level (after CIE correction). -// This means the CPU will trigger a compare match interrupt when the counter -// reaches the backlight level, where we turn off the LEDs, -// but also an overflow interrupt when the counter rolls back to 0, -// in which we're going to turn on the LEDs. -// The LED will then be on for OCRxx/0xFFFF time, adjusted every 244Hz, -// or F_CPU/BACKLIGHT_CUSTOM_RESOLUTION if used. - -// Triggered when the counter reaches the OCRx value -ISR(TIMERx_COMPA_vect) { - backlight_pins_off(); -} - -// Triggered when the counter reaches the TOP value -// this one triggers at F_CPU/ICRx = 16MHz/65536 =~ 244 Hz -ISR(TIMERx_OVF_vect) { -# ifdef BACKLIGHT_BREATHING - if (is_breathing()) { - breathing_task(); - } -# endif - // for very small values of OCRxx (or backlight level) - // we can't guarantee this whole code won't execute - // at the same time as the compare match interrupt - // which means that we might turn on the leds while - // trying to turn them off, leading to flickering - // artifacts (especially while breathing, because breathing_task - // takes many computation cycles). - // so better not turn them on while the counter TOP is very low. - if (OCRxx > ICRx / 250 + 5) { - backlight_pins_on(); - } -} - -#endif - -#define TIMER_TOP 0xFFFFU - -// See http://jared.geek.nz/2013/feb/linear-led-pwm -static uint16_t cie_lightness(uint16_t v) { - if (v <= (uint32_t)ICRx / 12) // If the value is less than or equal to ~8% of max - { - return v / 9; // Same as dividing by 900% - } else { - // In the next two lines values are bit-shifted. This is to avoid loosing decimals in integer math. - uint32_t y = (((uint32_t)v + (uint32_t)ICRx / 6) << 5) / ((uint32_t)ICRx / 6 + ICRx); // If above 8%, add ~16% of max, and normalize with (max + ~16% max) - uint32_t out = (y * y * y * ICRx) >> 15; // Cube it and undo the bit-shifting. (which is now three times as much due to the cubing) - - if (out > ICRx) // Avoid overflows - { - out = ICRx; - } - return (uint16_t)out; - } -} - -// rescale the supplied backlight value to be in terms of the value limit // range for val is [0..ICRx]. PWM pin is high while the timer count is below val. -static uint32_t rescale_limit_val(uint32_t val) { - return (val * (BACKLIGHT_LIMIT_VAL + 1)) / 256; -} - -// range for val is [0..ICRx]. PWM pin is high while the timer count is below val. -static inline void set_pwm(uint16_t val) { - OCRxx = val; -} - -void backlight_set(uint8_t level) { - if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS; - - if (level == 0) { -#ifdef BACKLIGHT_PWM_TIMER - if (OCRxx) { - TIMSKx &= ~(_BV(OCIExA)); - TIMSKx &= ~(_BV(TOIEx)); - } -#else - // Turn off PWM control on backlight pin - disable_pwm(); -#endif - backlight_pins_off(); - } else { -#ifdef BACKLIGHT_PWM_TIMER - if (!OCRxx) { - TIMSKx |= _BV(OCIExA); - TIMSKx |= _BV(TOIEx); - } -#else - // Turn on PWM control of backlight pin - enable_pwm(); -#endif - } - // Set the brightness - set_pwm(cie_lightness(rescale_limit_val(ICRx * (uint32_t)level / BACKLIGHT_LEVELS))); -} - -void backlight_task(void) {} - -#ifdef BACKLIGHT_BREATHING - -# define BREATHING_NO_HALT 0 -# define BREATHING_HALT_OFF 1 -# define BREATHING_HALT_ON 2 -# define BREATHING_STEPS 128 - -static uint8_t breathing_halt = BREATHING_NO_HALT; -static uint16_t breathing_counter = 0; - -static uint8_t breath_scale_counter = 1; -/* Run the breathing loop at ~120Hz*/ -const uint8_t breathing_ISR_frequency = 120; -static uint16_t breathing_freq_scale_factor = 2; - -# ifdef BACKLIGHT_PWM_TIMER -static bool breathing = false; - -bool is_breathing(void) { - return breathing; -} - -# define breathing_interrupt_enable() \ - do { \ - breathing = true; \ - } while (0) -# define breathing_interrupt_disable() \ - do { \ - breathing = false; \ - } while (0) -# else - -bool is_breathing(void) { - return !!(TIMSKx & _BV(TOIEx)); -} - -# define breathing_interrupt_enable() \ - do { \ - TIMSKx |= _BV(TOIEx); \ - } while (0) -# define breathing_interrupt_disable() \ - do { \ - TIMSKx &= ~_BV(TOIEx); \ - } while (0) -# endif - -# define breathing_min() \ - do { \ - breathing_counter = 0; \ - } while (0) -# define breathing_max() \ - do { \ - breathing_counter = get_breathing_period() * breathing_ISR_frequency / 2; \ - } while (0) - -void breathing_enable(void) { - breathing_counter = 0; - breathing_halt = BREATHING_NO_HALT; - breathing_interrupt_enable(); -} - -void breathing_pulse(void) { - if (get_backlight_level() == 0) - breathing_min(); - else - breathing_max(); - breathing_halt = BREATHING_HALT_ON; - breathing_interrupt_enable(); -} - -void breathing_disable(void) { - breathing_interrupt_disable(); - // Restore backlight level - backlight_set(get_backlight_level()); -} - -void breathing_self_disable(void) { - if (get_backlight_level() == 0) - breathing_halt = BREATHING_HALT_OFF; - else - breathing_halt = BREATHING_HALT_ON; -} - -/* To generate breathing curve in python: - * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] - */ -static const uint8_t breathing_table[BREATHING_STEPS] PROGMEM = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -// Use this before the cie_lightness function. -static inline uint16_t scale_backlight(uint16_t v) { - return v / BACKLIGHT_LEVELS * get_backlight_level(); -} - -# ifdef BACKLIGHT_PWM_TIMER -void breathing_task(void) -# else -/* Assuming a 16MHz CPU clock and a timer that resets at 64k (ICR1), the following interrupt handler will run - * about 244 times per second. - * - * The following ISR runs at F_CPU/ISRx. With a 16MHz clock and default pwm resolution, that means 244Hz - */ -ISR(TIMERx_OVF_vect) -# endif -{ - - // Only run this ISR at ~120 Hz - if (breath_scale_counter++ == breathing_freq_scale_factor) { - breath_scale_counter = 1; - } else { - return; - } - uint16_t interval = (uint16_t)get_breathing_period() * breathing_ISR_frequency / BREATHING_STEPS; - // resetting after one period to prevent ugly reset at overflow. - breathing_counter = (breathing_counter + 1) % (get_breathing_period() * breathing_ISR_frequency); - uint8_t index = breathing_counter / interval; - // limit index to max step value - if (index >= BREATHING_STEPS) { - index = BREATHING_STEPS - 1; - } - - if (((breathing_halt == BREATHING_HALT_ON) && (index == BREATHING_STEPS / 2)) || ((breathing_halt == BREATHING_HALT_OFF) && (index == BREATHING_STEPS - 1))) { - breathing_interrupt_disable(); - } - - // Set PWM to a brightnessvalue scaled to the configured resolution - set_pwm(cie_lightness(rescale_limit_val(scale_backlight((uint32_t)pgm_read_byte(&breathing_table[index]) * ICRx / 255)))); -} - -#endif // BACKLIGHT_BREATHING - -void backlight_init_ports(void) { - // Setup backlight pin as output and output to on state. - backlight_pins_init(); - - // I could write a wall of text here to explain... but TL;DW - // Go read the ATmega32u4 datasheet. - // And this: http://blog.saikoled.com/post/43165849837/secret-konami-cheat-code-to-high-resolution-pwm-on - -#ifdef BACKLIGHT_PWM_TIMER - // TimerX setup, Fast PWM mode count to TOP set in ICRx - TCCRxA = _BV(WGM11); // = 0b00000010; - // clock select clk/1 - TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; -#else // hardware PWM - // Pin PB7 = OCR1C (Timer 1, Channel C) - // Compare Output Mode = Clear on compare match, Channel C = COM1C1=1 COM1C0=0 - // (i.e. start high, go low when counter matches.) - // WGM Mode 14 (Fast PWM) = WGM13=1 WGM12=1 WGM11=1 WGM10=0 - // Clock Select = clk/1 (no prescaling) = CS12=0 CS11=0 CS10=1 - - /* - 14.8.3: - "In fast PWM mode, the compare units allow generation of PWM waveforms on the OCnx pins. Setting the COMnx1:0 bits to two will produce a non-inverted PWM [..]." - "In fast PWM mode the counter is incremented until the counter value matches either one of the fixed values 0x00FF, 0x01FF, or 0x03FF (WGMn3:0 = 5, 6, or 7), the value in ICRn (WGMn3:0 = 14), or the value in OCRnA (WGMn3:0 = 15)." - */ - TCCRxA = _BV(COMxx1) | _BV(WGM11); // = 0b00001010; - TCCRxB = _BV(WGM13) | _BV(WGM12) | _BV(CS10); // = 0b00011001; -#endif - -#ifdef BACKLIGHT_CUSTOM_RESOLUTION -# if (BACKLIGHT_CUSTOM_RESOLUTION > 0xFFFF || BACKLIGHT_CUSTOM_RESOLUTION < 1) -# error "This out of range of the timer capabilities" -# elif (BACKLIGHT_CUSTOM_RESOLUTION < 0xFF) -# warning "Resolution lower than 0xFF isn't recommended" -# endif -# ifdef BACKLIGHT_BREATHING - breathing_freq_scale_factor = F_CPU / BACKLIGHT_CUSTOM_RESOLUTION / 120; -# endif - ICRx = BACKLIGHT_CUSTOM_RESOLUTION; -#else - ICRx = TIMER_TOP; -#endif - - backlight_init(); -#ifdef BACKLIGHT_BREATHING - if (is_backlight_breathing()) { - breathing_enable(); - } -#endif -} diff --git a/quantum/backlight/backlight_chibios.c b/quantum/backlight/backlight_chibios.c deleted file mode 100644 index 30e95bd5c80d..000000000000 --- a/quantum/backlight/backlight_chibios.c +++ /dev/null @@ -1,173 +0,0 @@ -#include "quantum.h" -#include "backlight.h" -#include -#include "debug.h" - -// Maximum duty cycle limit -#ifndef BACKLIGHT_LIMIT_VAL -# define BACKLIGHT_LIMIT_VAL 255 -#endif - -#ifndef BACKLIGHT_PAL_MODE -# if defined(USE_GPIOV1) -# define BACKLIGHT_PAL_MODE PAL_MODE_ALTERNATE_PUSHPULL -# else -// GPIOV2 && GPIOV3 -# define BACKLIGHT_PAL_MODE 5 -# endif -#endif - -// GENERIC -#ifndef BACKLIGHT_PWM_DRIVER -# define BACKLIGHT_PWM_DRIVER PWMD4 -#endif -#ifndef BACKLIGHT_PWM_CHANNEL -# define BACKLIGHT_PWM_CHANNEL 3 -#endif - -// Support for pins which are on TIM1_CH1N - requires STM32_PWM_USE_ADVANCED -#ifdef BACKLIGHT_PWM_COMPLEMENTARY_OUTPUT -# if BACKLIGHT_ON_STATE == 1 -# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_LOW; -# else -# define PWM_OUTPUT_MODE PWM_COMPLEMENTARY_OUTPUT_ACTIVE_HIGH; -# endif -#else -# if BACKLIGHT_ON_STATE == 1 -# define PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_HIGH; -# else -# define PWM_OUTPUT_MODE PWM_OUTPUT_ACTIVE_LOW; -# endif -#endif - -#ifndef BACKLIGHT_PWM_COUNTER_FREQUENCY -# define BACKLIGHT_PWM_COUNTER_FREQUENCY 0xFFFF -#endif - -#ifndef BACKLIGHT_PWM_PERIOD -# define BACKLIGHT_PWM_PERIOD 256 -#endif - -static PWMConfig pwmCFG = { - .frequency = BACKLIGHT_PWM_COUNTER_FREQUENCY, /* PWM clock frequency */ - .period = BACKLIGHT_PWM_PERIOD, /* PWM period in counter ticks. e.g. clock frequency is 10KHz, period is 256 ticks then t_period is 25.6ms */ -}; - -#ifdef BACKLIGHT_BREATHING -static virtual_timer_t breathing_vt; -#endif - -// See http://jared.geek.nz/2013/feb/linear-led-pwm -static uint16_t cie_lightness(uint16_t v) { - if (v <= 5243) // if below 8% of max - return v / 9; // same as dividing by 900% - else { - uint32_t y = (((uint32_t)v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare - // to get a useful result with integer division, we shift left in the expression above - // and revert what we've done again after squaring. - y = y * y * y >> 8; - if (y > 0xFFFFUL) { // prevent overflow - return 0xFFFFU; - } else { - return (uint16_t)y; - } - } -} - -static uint32_t rescale_limit_val(uint32_t val) { - // rescale the supplied backlight value to be in terms of the value limit - return (val * (BACKLIGHT_LIMIT_VAL + 1)) / 256; -} - -void backlight_init_ports(void) { -#ifdef USE_GPIOV1 - palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), BACKLIGHT_PAL_MODE); -#else - palSetPadMode(PAL_PORT(BACKLIGHT_PIN), PAL_PAD(BACKLIGHT_PIN), PAL_MODE_ALTERNATE(BACKLIGHT_PAL_MODE)); -#endif - - pwmCFG.channels[BACKLIGHT_PWM_CHANNEL - 1].mode = PWM_OUTPUT_MODE; - pwmStart(&BACKLIGHT_PWM_DRIVER, &pwmCFG); - - backlight_set(get_backlight_level()); - -#ifdef BACKLIGHT_BREATHING - chVTObjectInit(&breathing_vt); - if (is_backlight_breathing()) { - breathing_enable(); - } -#endif -} - -void backlight_set(uint8_t level) { - if (level > BACKLIGHT_LEVELS) { - level = BACKLIGHT_LEVELS; - } - - if (level == 0) { - // Turn backlight off - pwmDisableChannel(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1); - } else { - // Turn backlight on - uint32_t duty = (uint32_t)(cie_lightness(rescale_limit_val(0xFFFF * (uint32_t)level / BACKLIGHT_LEVELS))); - pwmEnableChannel(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty)); - } -} - -void backlight_task(void) {} - -#ifdef BACKLIGHT_BREATHING - -# define BREATHING_STEPS 128 - -/* To generate breathing curve in python: - * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] - */ -static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -static void breathing_callback(virtual_timer_t *vtp, void *p); - -bool is_breathing(void) { - return chVTIsArmed(&breathing_vt); -} - -void breathing_enable(void) { - /* Update frequency is 256Hz -> 3906us intervals */ - chVTSetContinuous(&breathing_vt, TIME_US2I(3906), breathing_callback, NULL); -} - -void breathing_disable(void) { - chVTReset(&breathing_vt); - - // Restore backlight level - backlight_set(get_backlight_level()); -} - -// Use this before the cie_lightness function. -static inline uint16_t scale_backlight(uint16_t v) { - return v / BACKLIGHT_LEVELS * get_backlight_level(); -} - -static void breathing_callback(virtual_timer_t *vtp, void *p) { - uint8_t breathing_period = get_breathing_period(); - uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS; - - // resetting after one period to prevent ugly reset at overflow. - static uint16_t breathing_counter = 0; - breathing_counter = (breathing_counter + 1) % (breathing_period * 256); - uint8_t index = breathing_counter / interval % BREATHING_STEPS; - uint32_t duty = cie_lightness(rescale_limit_val(scale_backlight(breathing_table[index] * 256))); - - chSysLockFromISR(); - pwmEnableChannelI(&BACKLIGHT_PWM_DRIVER, BACKLIGHT_PWM_CHANNEL - 1, PWM_FRACTION_TO_WIDTH(&BACKLIGHT_PWM_DRIVER, 0xFFFF, duty)); - chSysUnlockFromISR(); -} - -// TODO: integrate generic pulse solution -void breathing_pulse(void) { - backlight_set(is_backlight_enabled() ? 0 : BACKLIGHT_LEVELS); - wait_ms(10); - backlight_set(is_backlight_enabled() ? get_backlight_level() : 0); -} - -#endif diff --git a/quantum/backlight/backlight_driver_common.c b/quantum/backlight/backlight_driver_common.c deleted file mode 100644 index 1eb8969084e8..000000000000 --- a/quantum/backlight/backlight_driver_common.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "quantum.h" -#include "backlight.h" -#include "backlight_driver_common.h" - -#if !defined(BACKLIGHT_PIN) && !defined(BACKLIGHT_PINS) -# error "Backlight pin/pins not defined. Please configure." -#endif - -#if defined(BACKLIGHT_PINS) -static const pin_t backlight_pins[] = BACKLIGHT_PINS; -# ifndef BACKLIGHT_LED_COUNT -# define BACKLIGHT_LED_COUNT ARRAY_SIZE(backlight_pins) -# endif - -# define FOR_EACH_LED(x) \ - for (uint8_t i = 0; i < BACKLIGHT_LED_COUNT; i++) { \ - pin_t backlight_pin = backlight_pins[i]; \ - { x } \ - } -#else -// we support only one backlight pin -static const pin_t backlight_pin = BACKLIGHT_PIN; -# define FOR_EACH_LED(x) x -#endif - -static inline void backlight_on(pin_t backlight_pin) { -#if BACKLIGHT_ON_STATE == 0 - writePinLow(backlight_pin); -#else - writePinHigh(backlight_pin); -#endif -} - -static inline void backlight_off(pin_t backlight_pin) { -#if BACKLIGHT_ON_STATE == 0 - writePinHigh(backlight_pin); -#else - writePinLow(backlight_pin); -#endif -} - -void backlight_pins_init(void) { - // Setup backlight pin as output and output to off state. - FOR_EACH_LED(setPinOutput(backlight_pin); backlight_off(backlight_pin);) -} - -void backlight_pins_on(void) { - FOR_EACH_LED(backlight_on(backlight_pin);) -} - -void backlight_pins_off(void) { - FOR_EACH_LED(backlight_off(backlight_pin);) -} diff --git a/quantum/backlight/backlight_driver_common.h b/quantum/backlight/backlight_driver_common.h deleted file mode 100644 index 36e8a5fa6bb7..000000000000 --- a/quantum/backlight/backlight_driver_common.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -void backlight_pins_init(void); -void backlight_pins_on(void); -void backlight_pins_off(void); - -void breathing_task(void); diff --git a/quantum/backlight/backlight_software.c b/quantum/backlight/backlight_software.c deleted file mode 100644 index 27ccbd2c9ff9..000000000000 --- a/quantum/backlight/backlight_software.c +++ /dev/null @@ -1,54 +0,0 @@ -#include "quantum.h" -#include "backlight.h" -#include "backlight_driver_common.h" - -#ifdef BACKLIGHT_BREATHING -# error "Backlight breathing is not available for software PWM. Please disable." -#endif - -static uint16_t s_duty_pattern = 0; - -// clang-format off - -/** \brief PWM duty patterns - * - * We scale the current backlight level to an index within this array. This allows - * backlight_task to focus on just switching LEDs on/off, and we can predict the duty pattern - */ -static const uint16_t backlight_duty_table[] = { - 0b0000000000000000, - 0b1000000000000000, - 0b1000000010000000, - 0b1000001000010000, - 0b1000100010001000, - 0b1001001001001000, - 0b1010101010101010, - 0b1110111011101110, - 0b1111111111111111, -}; -#define backlight_duty_table_size ARRAY_SIZE(backlight_duty_table) - -// clang-format on - -static uint8_t scale_backlight(uint8_t v) { - return v * (backlight_duty_table_size - 1) / BACKLIGHT_LEVELS; -} - -void backlight_init_ports(void) { - backlight_pins_init(); -} - -void backlight_set(uint8_t level) { - s_duty_pattern = backlight_duty_table[scale_backlight(level)]; -} - -void backlight_task(void) { - static uint8_t backlight_tick = 0; - - if (s_duty_pattern & ((uint16_t)1 << backlight_tick)) { - backlight_pins_on(); - } else { - backlight_pins_off(); - } - backlight_tick = (backlight_tick + 1) % 16; -} diff --git a/quantum/backlight/backlight_timer.c b/quantum/backlight/backlight_timer.c deleted file mode 100644 index 82fb6a6a83e7..000000000000 --- a/quantum/backlight/backlight_timer.c +++ /dev/null @@ -1,179 +0,0 @@ -#include "quantum.h" -#include "backlight.h" -#include "backlight_driver_common.h" -#include "debug.h" - -#ifndef BACKLIGHT_GPT_DRIVER -# define BACKLIGHT_GPT_DRIVER GPTD15 -#endif - -// Platform specific implementations -static void backlight_timer_configure(bool enable); -static void backlight_timer_set_duty(uint16_t duty); -static uint16_t backlight_timer_get_duty(void); - -// See http://jared.geek.nz/2013/feb/linear-led-pwm -static uint16_t cie_lightness(uint16_t v) { - if (v <= 5243) // if below 8% of max - return v / 9; // same as dividing by 900% - else { - uint32_t y = (((uint32_t)v + 10486) << 8) / (10486 + 0xFFFFUL); // add 16% of max and compare - // to get a useful result with integer division, we shift left in the expression above - // and revert what we've done again after squaring. - y = y * y * y >> 8; - if (y > 0xFFFFUL) // prevent overflow - return 0xFFFFU; - else - return (uint16_t)y; - } -} - -void backlight_init_ports(void) { - backlight_pins_init(); - - backlight_set(get_backlight_level()); - -#ifdef BACKLIGHT_BREATHING - if (is_backlight_breathing()) { - breathing_enable(); - } -#endif -} - -void backlight_set(uint8_t level) { - if (level > BACKLIGHT_LEVELS) level = BACKLIGHT_LEVELS; - - backlight_pins_off(); - - backlight_timer_set_duty(cie_lightness(0xFFFFU / BACKLIGHT_LEVELS * level)); - backlight_timer_configure(level != 0); -} - -static void backlight_timer_top(void) { -#ifdef BACKLIGHT_BREATHING - if (is_breathing()) { - breathing_task(); - } -#endif - - if (backlight_timer_get_duty() > 256) { - backlight_pins_on(); - } -} - -static void backlight_timer_cmp(void) { - backlight_pins_off(); -} - -void backlight_task(void) {} - -#ifdef BACKLIGHT_BREATHING -# define BREATHING_STEPS 128 - -static bool breathing = false; -static uint16_t breathing_counter = 0; - -/* To generate breathing curve in python: - * from math import sin, pi; [int(sin(x/128.0*pi)**4*255) for x in range(128)] - */ -static const uint8_t breathing_table[BREATHING_STEPS] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 3, 4, 5, 6, 8, 10, 12, 15, 17, 20, 24, 28, 32, 36, 41, 46, 51, 57, 63, 70, 76, 83, 91, 98, 106, 113, 121, 129, 138, 146, 154, 162, 170, 178, 185, 193, 200, 207, 213, 220, 225, 231, 235, 240, 244, 247, 250, 252, 253, 254, 255, 254, 253, 252, 250, 247, 244, 240, 235, 231, 225, 220, 213, 207, 200, 193, 185, 178, 170, 162, 154, 146, 138, 129, 121, 113, 106, 98, 91, 83, 76, 70, 63, 57, 51, 46, 41, 36, 32, 28, 24, 20, 17, 15, 12, 10, 8, 6, 5, 4, 3, 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - -// Use this before the cie_lightness function. -static inline uint16_t scale_backlight(uint16_t v) { - return v / BACKLIGHT_LEVELS * get_backlight_level(); -} - -void breathing_task(void) { - uint8_t breathing_period = get_breathing_period(); - uint16_t interval = (uint16_t)breathing_period * 256 / BREATHING_STEPS; - // resetting after one period to prevent ugly reset at overflow. - breathing_counter = (breathing_counter + 1) % (breathing_period * 256); - uint8_t index = breathing_counter / interval % BREATHING_STEPS; - - // printf("index:%u\n", index); - - backlight_timer_set_duty(cie_lightness(scale_backlight((uint16_t)breathing_table[index] * 256))); -} - -bool is_breathing(void) { - return breathing; -} - -void breathing_enable(void) { - breathing_counter = 0; - breathing = true; -} -void breathing_disable(void) { - breathing = false; -} - -void breathing_pulse(void) { - backlight_set(is_backlight_enabled() ? 0 : BACKLIGHT_LEVELS); - wait_ms(10); - backlight_set(is_backlight_enabled() ? get_backlight_level() : 0); -} -#endif - -#ifdef PROTOCOL_CHIBIOS -// On Platforms where timers fire every tick and have no capture/top events -// - fake event in the normal timer callback -uint16_t s_duty = 0; - -static void timerCallback(void) { - /* Software PWM - * timer:1111 1111 1111 1111 - * \______/| \_______/____ count(0-255) - * \ \______________ unused(1) - * \__________________ index of step table(0-127) - */ - - // this works for cca 65536 irqs/sec - static union { - uint16_t raw; - struct { - uint16_t count : 8; - uint8_t dummy : 1; - uint8_t index : 7; - } pwm; - } timer = {.raw = 0}; - - timer.raw++; - - if (timer.pwm.count == 0) { - // LED on - backlight_timer_top(); - } else if (timer.pwm.count == (s_duty / 256)) { - // LED off - backlight_timer_cmp(); - } -} - -static void backlight_timer_set_duty(uint16_t duty) { - s_duty = duty; -} -static uint16_t backlight_timer_get_duty(void) { - return s_duty; -} - -// ChibiOS - Map GPT timer onto Software PWM -static void gptTimerCallback(GPTDriver *gptp) { - (void)gptp; - timerCallback(); -} - -static void backlight_timer_configure(bool enable) { - static const GPTConfig gptcfg = {1000000, gptTimerCallback, 0, 0}; - - static bool s_init = false; - if (!s_init) { - gptStart(&BACKLIGHT_GPT_DRIVER, &gptcfg); - s_init = true; - } - - if (enable) { - gptStartContinuous(&BACKLIGHT_GPT_DRIVER, gptcfg.frequency / 0xFFFF); - } else { - gptStopTimer(&BACKLIGHT_GPT_DRIVER); - } -} -#endif diff --git a/quantum/basic_profiling.h b/quantum/basic_profiling.h deleted file mode 100644 index d371acd6f002..000000000000 --- a/quantum/basic_profiling.h +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright 2023 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -/* - This API allows for basic profiling information to be printed out over console. - - Usage example: - - #include "basic_profiling.h" - - // Original code: - matrix_task(); - - // Delete the original, replace with the following (variant 1, automatic naming): - PROFILE_CALL(1000, matrix_task()); - - // Delete the original, replace with the following (variant 2, explicit naming): - PROFILE_CALL_NAMED(1000, "matrix_task", { - matrix_task(); - }); -*/ - -#if defined(PROTOCOL_LUFA) || defined(PROTOCOL_VUSB) -# define TIMESTAMP_GETTER TCNT0 -#elif defined(PROTOCOL_CHIBIOS) -# define TIMESTAMP_GETTER chSysGetRealtimeCounterX() -#elif defined(PROTOCOL_ARM_ATSAM) -# error arm_atsam not currently supported -#else -# error Unknown protocol in use -#endif - -#ifndef CONSOLE_ENABLE -// Can't do anything if we don't have console output enabled. -# define PROFILE_CALL_NAMED(count, name, call) \ - do { \ - } while (0) -#else -# define PROFILE_CALL_NAMED(count, name, call) \ - do { \ - static uint64_t inner_sum = 0; \ - static uint64_t outer_sum = 0; \ - uint32_t start_ts; \ - static uint32_t end_ts; \ - static uint32_t write_location = 0; \ - start_ts = TIMESTAMP_GETTER; \ - if (write_location > 0) { \ - outer_sum += start_ts - end_ts; \ - } \ - do { \ - call; \ - } while (0); \ - end_ts = TIMESTAMP_GETTER; \ - inner_sum += end_ts - start_ts; \ - ++write_location; \ - if (write_location >= ((uint32_t)count)) { \ - uint32_t inner_avg = inner_sum / (((uint32_t)count) - 1); \ - uint32_t outer_avg = outer_sum / (((uint32_t)count) - 1); \ - dprintf("%s -- Percentage time spent: %d%%\n", (name), (int)(inner_avg * 100 / (inner_avg + outer_avg))); \ - inner_sum = 0; \ - outer_sum = 0; \ - write_location = 0; \ - } \ - } while (0) - -#endif // CONSOLE_ENABLE - -#define PROFILE_CALL(count, call) PROFILE_CALL_NAMED(count, #call, call) diff --git a/quantum/bitwise.c b/quantum/bitwise.c deleted file mode 100644 index 1868e1493232..000000000000 --- a/quantum/bitwise.c +++ /dev/null @@ -1,126 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#include "util.h" - -// bit population - return number of on-bit -__attribute__((noinline)) uint8_t bitpop(uint8_t bits) { - uint8_t c; - for (c = 0; bits; c++) - bits &= bits - 1; - return c; - /* - const uint8_t bit_count[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 }; - return bit_count[bits>>4] + bit_count[bits&0x0F] - */ -} - -uint8_t bitpop16(uint16_t bits) { - uint8_t c; - for (c = 0; bits; c++) - bits &= bits - 1; - return c; -} - -uint8_t bitpop32(uint32_t bits) { - uint8_t c; - for (c = 0; bits; c++) - bits &= bits - 1; - return c; -} - -// most significant on-bit - return highest location of on-bit -// NOTE: return 0 when bit0 is on or all bits are off -__attribute__((noinline)) uint8_t biton(uint8_t bits) { - uint8_t n = 0; - if (bits >> 4) { - bits >>= 4; - n += 4; - } - if (bits >> 2) { - bits >>= 2; - n += 2; - } - if (bits >> 1) { - bits >>= 1; - n += 1; - } - return n; -} - -uint8_t biton16(uint16_t bits) { - uint8_t n = 0; - if (bits >> 8) { - bits >>= 8; - n += 8; - } - if (bits >> 4) { - bits >>= 4; - n += 4; - } - if (bits >> 2) { - bits >>= 2; - n += 2; - } - if (bits >> 1) { - bits >>= 1; - n += 1; - } - return n; -} - -uint8_t biton32(uint32_t bits) { - uint8_t n = 0; - if (bits >> 16) { - bits >>= 16; - n += 16; - } - if (bits >> 8) { - bits >>= 8; - n += 8; - } - if (bits >> 4) { - bits >>= 4; - n += 4; - } - if (bits >> 2) { - bits >>= 2; - n += 2; - } - if (bits >> 1) { - bits >>= 1; - n += 1; - } - return n; -} - -__attribute__((noinline)) uint8_t bitrev(uint8_t bits) { - bits = (bits & 0x0f) << 4 | (bits & 0xf0) >> 4; - bits = (bits & 0b00110011) << 2 | (bits & 0b11001100) >> 2; - bits = (bits & 0b01010101) << 1 | (bits & 0b10101010) >> 1; - return bits; -} - -uint16_t bitrev16(uint16_t bits) { - bits = bitrev(bits & 0x00ff) << 8 | bitrev((bits & 0xff00) >> 8); - return bits; -} - -uint32_t bitrev32(uint32_t bits) { - bits = (uint32_t)bitrev16(bits & 0x0000ffff) << 16 | bitrev16((bits & 0xffff0000) >> 16); - return bits; -} diff --git a/quantum/bitwise.h b/quantum/bitwise.h deleted file mode 100644 index 276bc7437b3f..000000000000 --- a/quantum/bitwise.h +++ /dev/null @@ -1,40 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -uint8_t bitpop(uint8_t bits); -uint8_t bitpop16(uint16_t bits); -uint8_t bitpop32(uint32_t bits); - -uint8_t biton(uint8_t bits); -uint8_t biton16(uint16_t bits); -uint8_t biton32(uint32_t bits); - -uint8_t bitrev(uint8_t bits); -uint16_t bitrev16(uint16_t bits); -uint32_t bitrev32(uint32_t bits); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/bootmagic/bootmagic.h b/quantum/bootmagic/bootmagic.h deleted file mode 100644 index db826025ce58..000000000000 --- a/quantum/bootmagic/bootmagic.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#pragma once - -#if defined(BOOTMAGIC_LITE) -# include "bootmagic_lite.h" -#endif - -void bootmagic(void); diff --git a/quantum/bootmagic/bootmagic_lite.c b/quantum/bootmagic/bootmagic_lite.c deleted file mode 100644 index f63c71fc6b16..000000000000 --- a/quantum/bootmagic/bootmagic_lite.c +++ /dev/null @@ -1,64 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#include "quantum.h" - -/** \brief Reset eeprom - * - * ...just incase someone wants to only change the eeprom behaviour - */ -__attribute__((weak)) void bootmagic_lite_reset_eeprom(void) { - eeconfig_disable(); -} - -/** \brief The lite version of TMK's bootmagic based on Wilba. - * - * 100% less potential for accidentally making the keyboard do stupid things. - */ -__attribute__((weak)) void bootmagic_lite(void) { - // We need multiple scans because debouncing can't be turned off. - matrix_scan(); -#if defined(DEBOUNCE) && DEBOUNCE > 0 - wait_ms(DEBOUNCE * 2); -#else - wait_ms(30); -#endif - matrix_scan(); - - // If the configured key (commonly Esc) is held down on power up, - // reset the EEPROM valid state and jump to bootloader. - // This isn't very generalized, but we need something that doesn't - // rely on user's keymaps in firmware or EEPROM. - uint8_t row = BOOTMAGIC_LITE_ROW; - uint8_t col = BOOTMAGIC_LITE_COLUMN; - -#if defined(SPLIT_KEYBOARD) && defined(BOOTMAGIC_LITE_ROW_RIGHT) && defined(BOOTMAGIC_LITE_COLUMN_RIGHT) - if (!is_keyboard_left()) { - row = BOOTMAGIC_LITE_ROW_RIGHT; - col = BOOTMAGIC_LITE_COLUMN_RIGHT; - } -#endif - - if (matrix_get_row(row) & (1 << col)) { - bootmagic_lite_reset_eeprom(); - - // Jump to bootloader. - bootloader_jump(); - } -} - -void bootmagic(void) { - bootmagic_lite(); -} diff --git a/quantum/bootmagic/bootmagic_lite.h b/quantum/bootmagic/bootmagic_lite.h deleted file mode 100644 index 17777e6b4a53..000000000000 --- a/quantum/bootmagic/bootmagic_lite.h +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#pragma once - -#ifndef BOOTMAGIC_LITE_COLUMN -# define BOOTMAGIC_LITE_COLUMN 0 -#endif -#ifndef BOOTMAGIC_LITE_ROW -# define BOOTMAGIC_LITE_ROW 0 -#endif - -void bootmagic_lite(void); diff --git a/quantum/bootmagic/magic.c b/quantum/bootmagic/magic.c deleted file mode 100644 index d68df3fa5884..000000000000 --- a/quantum/bootmagic/magic.c +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#include -#include -#include "wait.h" -#include "matrix.h" -#include "bootloader.h" -#include "debug.h" -#include "keycode_config.h" -#include "host.h" -#include "action_layer.h" -#include "eeconfig.h" -#include "bootmagic.h" - -keymap_config_t keymap_config; - -__attribute__((weak)) void bootmagic(void) {} - -/** \brief Magic - * - * FIXME: Needs doc - */ -void magic(void) { - /* check signature */ - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - - /* init globals */ - debug_config.raw = eeconfig_read_debug(); - keymap_config.raw = eeconfig_read_keymap(); - - bootmagic(); - - /* read here just incase bootmagic process changed its value */ - layer_state_t default_layer = (layer_state_t)eeconfig_read_default_layer(); - default_layer_set(default_layer); - - /* Also initialize layer state to trigger callback functions for layer_state */ - layer_state_set_kb((layer_state_t)layer_state); -} diff --git a/quantum/bootmagic/magic.h b/quantum/bootmagic/magic.h deleted file mode 100644 index 2c3969b85ca5..000000000000 --- a/quantum/bootmagic/magic.h +++ /dev/null @@ -1,18 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#pragma once - -void magic(void); diff --git a/quantum/caps_word.c b/quantum/caps_word.c deleted file mode 100644 index 66fd0e8afbd4..000000000000 --- a/quantum/caps_word.c +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2021-2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include "caps_word.h" -#include "timer.h" -#include "action.h" -#include "action_util.h" - -/** @brief True when Caps Word is active. */ -static bool caps_word_active = false; - -#if CAPS_WORD_IDLE_TIMEOUT > 0 -// Constrain timeout to a sensible range. With 16-bit timers, the longest -// timeout possible is 32768 ms, rounded here to 30000 ms = half a minute. -# if CAPS_WORD_IDLE_TIMEOUT < 100 || CAPS_WORD_IDLE_TIMEOUT > 30000 -# error "CAPS_WORD_IDLE_TIMEOUT must be between 100 and 30000 ms" -# endif - -/** @brief Deadline for idle timeout. */ -static uint16_t idle_timer = 0; - -void caps_word_task(void) { - if (caps_word_active && timer_expired(timer_read(), idle_timer)) { - caps_word_off(); - } -} - -void caps_word_reset_idle_timer(void) { - idle_timer = timer_read() + CAPS_WORD_IDLE_TIMEOUT; -} -#else -void caps_word_task(void) {} -#endif // CAPS_WORD_IDLE_TIMEOUT > 0 - -void caps_word_on(void) { - if (caps_word_active) { - return; - } - - clear_mods(); -#ifndef NO_ACTION_ONESHOT - clear_oneshot_mods(); -#endif // NO_ACTION_ONESHOT -#if CAPS_WORD_IDLE_TIMEOUT > 0 - caps_word_reset_idle_timer(); -#endif // CAPS_WORD_IDLE_TIMEOUT > 0 - - caps_word_active = true; - caps_word_set_user(true); -} - -void caps_word_off(void) { - if (!caps_word_active) { - return; - } - - unregister_weak_mods(MOD_MASK_SHIFT); // Make sure weak shift is off. - caps_word_active = false; - caps_word_set_user(false); -} - -void caps_word_toggle(void) { - if (caps_word_active) { - caps_word_off(); - } else { - caps_word_on(); - } -} - -bool is_caps_word_on(void) { - return caps_word_active; -} - -__attribute__((weak)) void caps_word_set_user(bool active) {} diff --git a/quantum/caps_word.h b/quantum/caps_word.h deleted file mode 100644 index 078d29ead0a2..000000000000 --- a/quantum/caps_word.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2021-2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include - -#ifndef CAPS_WORD_IDLE_TIMEOUT -# define CAPS_WORD_IDLE_TIMEOUT 5000 // Default timeout of 5 seconds. -#endif - -/** @brief Matrix scan task for Caps Word feature */ -void caps_word_task(void); - -#if CAPS_WORD_IDLE_TIMEOUT > 0 -/** @brief Resets timer for Caps Word idle timeout. */ -void caps_word_reset_idle_timer(void); -#endif - -/** @brief Activates Caps Word. */ -void caps_word_on(void); - -/** @brief Deactivates Caps Word. */ -void caps_word_off(void); - -/** @brief Toggles Caps Word. */ -void caps_word_toggle(void); - -/** @brief Gets whether currently active. */ -bool is_caps_word_on(void); - -/** - * @brief Caps Word set callback. - * - * @param active True if Caps Word is active, false otherwise - */ -void caps_word_set_user(bool active); diff --git a/quantum/color.c b/quantum/color.c deleted file mode 100644 index 767155c9db9b..000000000000 --- a/quantum/color.c +++ /dev/null @@ -1,121 +0,0 @@ -/* Copyright 2017 Jason Williams - * - * 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 . - */ - -#include "color.h" -#include "led_tables.h" -#include "progmem.h" -#include "util.h" - -RGB hsv_to_rgb_impl(HSV hsv, bool use_cie) { - RGB rgb; - uint8_t region, remainder, p, q, t; - uint16_t h, s, v; - - if (hsv.s == 0) { -#ifdef USE_CIE1931_CURVE - if (use_cie) { - rgb.r = rgb.g = rgb.b = pgm_read_byte(&CIE1931_CURVE[hsv.v]); - } else { - rgb.r = hsv.v; - rgb.g = hsv.v; - rgb.b = hsv.v; - } -#else - rgb.r = hsv.v; - rgb.g = hsv.v; - rgb.b = hsv.v; -#endif - return rgb; - } - - h = hsv.h; - s = hsv.s; -#ifdef USE_CIE1931_CURVE - if (use_cie) { - v = pgm_read_byte(&CIE1931_CURVE[hsv.v]); - } else { - v = hsv.v; - } -#else - v = hsv.v; -#endif - - region = h * 6 / 255; - remainder = (h * 2 - region * 85) * 3; - - p = (v * (255 - s)) >> 8; - q = (v * (255 - ((s * remainder) >> 8))) >> 8; - t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8; - - switch (region) { - case 6: - case 0: - rgb.r = v; - rgb.g = t; - rgb.b = p; - break; - case 1: - rgb.r = q; - rgb.g = v; - rgb.b = p; - break; - case 2: - rgb.r = p; - rgb.g = v; - rgb.b = t; - break; - case 3: - rgb.r = p; - rgb.g = q; - rgb.b = v; - break; - case 4: - rgb.r = t; - rgb.g = p; - rgb.b = v; - break; - default: - rgb.r = v; - rgb.g = p; - rgb.b = q; - break; - } - - return rgb; -} - -RGB hsv_to_rgb(HSV hsv) { -#ifdef USE_CIE1931_CURVE - return hsv_to_rgb_impl(hsv, true); -#else - return hsv_to_rgb_impl(hsv, false); -#endif -} - -RGB hsv_to_rgb_nocie(HSV hsv) { - return hsv_to_rgb_impl(hsv, false); -} - -#ifdef RGBW -void convert_rgb_to_rgbw(LED_TYPE *led) { - // Determine lowest value in all three colors, put that into - // the white channel and then shift all colors by that amount - led->w = MIN(led->r, MIN(led->g, led->b)); - led->r -= led->w; - led->g -= led->w; - led->b -= led->w; -} -#endif diff --git a/quantum/color.h b/quantum/color.h deleted file mode 100644 index 135ad623b552..000000000000 --- a/quantum/color.h +++ /dev/null @@ -1,150 +0,0 @@ -/* Copyright 2017 Jason Williams - * - * 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 . - */ - -#pragma once - -#include -#include - -// clang-format off - -/* - * RGB Colors - */ -#define RGB_AZURE 0x99, 0xF5, 0xFF -#define RGB_BLACK 0x00, 0x00, 0x00 -#define RGB_BLUE 0x00, 0x00, 0xFF -#define RGB_CHARTREUSE 0x80, 0xFF, 0x00 -#define RGB_CORAL 0xFF, 0x7C, 0x4D -#define RGB_CYAN 0x00, 0xFF, 0xFF -#define RGB_GOLD 0xFF, 0xD9, 0x00 -#define RGB_GOLDENROD 0xD9, 0xA5, 0x21 -#define RGB_GREEN 0x00, 0xFF, 0x00 -#define RGB_MAGENTA 0xFF, 0x00, 0xFF -#define RGB_ORANGE 0xFF, 0x80, 0x00 -#define RGB_PINK 0xFF, 0x80, 0xBF -#define RGB_PURPLE 0x7A, 0x00, 0xFF -#define RGB_RED 0xFF, 0x00, 0x00 -#define RGB_SPRINGGREEN 0x00, 0xFF, 0x80 -#define RGB_TEAL 0x00, 0x80, 0x80 -#define RGB_TURQUOISE 0x47, 0x6E, 0x6A -#define RGB_WHITE 0xFF, 0xFF, 0xFF -#define RGB_YELLOW 0xFF, 0xFF, 0x00 -#define RGB_OFF RGB_BLACK - -/* - * HSV Colors - * - * All values (including hue) are scaled to 0-255 - */ -#define HSV_AZURE 132, 102, 255 -#define HSV_BLACK 0, 0, 0 -#define HSV_BLUE 170, 255, 255 -#define HSV_CHARTREUSE 64, 255, 255 -#define HSV_CORAL 11, 176, 255 -#define HSV_CYAN 128, 255, 255 -#define HSV_GOLD 36, 255, 255 -#define HSV_GOLDENROD 30, 218, 218 -#define HSV_GREEN 85, 255, 255 -#define HSV_MAGENTA 213, 255, 255 -#define HSV_ORANGE 21, 255, 255 -#define HSV_PINK 234, 128, 255 -#define HSV_PURPLE 191, 255, 255 -#define HSV_RED 0, 255, 255 -#define HSV_SPRINGGREEN 106, 255, 255 -#define HSV_TEAL 128, 255, 128 -#define HSV_TURQUOISE 123, 90, 112 -#define HSV_WHITE 0, 0, 255 -#define HSV_YELLOW 43, 255, 255 -#define HSV_OFF HSV_BLACK - -// clang-format on - -#if defined(__GNUC__) -# define PACKED __attribute__((__packed__)) -#else -# define PACKED -#endif - -#if defined(_MSC_VER) -# pragma pack(push, 1) -#endif - -#ifdef RGBW -# define LED_TYPE cRGBW -#else -# define LED_TYPE RGB -#endif - -#define WS2812_BYTE_ORDER_RGB 0 -#define WS2812_BYTE_ORDER_GRB 1 -#define WS2812_BYTE_ORDER_BGR 2 - -#ifndef WS2812_BYTE_ORDER -# define WS2812_BYTE_ORDER WS2812_BYTE_ORDER_GRB -#endif - -typedef struct PACKED { -#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) - uint8_t g; - uint8_t r; - uint8_t b; -#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) - uint8_t r; - uint8_t g; - uint8_t b; -#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) - uint8_t b; - uint8_t g; - uint8_t r; -#endif -} cRGB; - -typedef cRGB RGB; - -// WS2812 specific layout -typedef struct PACKED { -#if (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_GRB) - uint8_t g; - uint8_t r; - uint8_t b; -#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_RGB) - uint8_t r; - uint8_t g; - uint8_t b; -#elif (WS2812_BYTE_ORDER == WS2812_BYTE_ORDER_BGR) - uint8_t b; - uint8_t g; - uint8_t r; -#endif - uint8_t w; -} cRGBW; - -typedef struct PACKED { - uint8_t h; - uint8_t s; - uint8_t v; -} HSV; - -#if defined(_MSC_VER) -# pragma pack(pop) -#endif - -RGB hsv_to_rgb(HSV hsv); -RGB hsv_to_rgb_nocie(HSV hsv); -#ifdef RGBW -void convert_rgb_to_rgbw(LED_TYPE *led); -#endif diff --git a/quantum/command.c b/quantum/command.c deleted file mode 100644 index aa64b75064f6..000000000000 --- a/quantum/command.c +++ /dev/null @@ -1,748 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ -#include -#include -#include "wait.h" -#include "keycode.h" -#include "host.h" -#include "print.h" -#include "debug.h" -#include "util.h" -#include "timer.h" -#include "keyboard.h" -#include "bootloader.h" -#include "action_layer.h" -#include "action_util.h" -#include "eeconfig.h" -#include "sleep_led.h" -#include "led.h" -#include "command.h" -#include "quantum.h" -#include "version.h" - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#if defined(MOUSEKEY_ENABLE) -# include "mousekey.h" -#endif - -#ifdef AUDIO_ENABLE -# include "audio.h" -#endif /* AUDIO_ENABLE */ - -static bool command_common(uint8_t code); -static void command_common_help(void); -static void print_version(void); -static void print_status(void); -static bool command_console(uint8_t code); -static void command_console_help(void); -#if defined(MOUSEKEY_ENABLE) -static bool mousekey_console(uint8_t code); -#endif - -static void switch_default_layer(uint8_t layer); - -command_state_t command_state = ONESHOT; - -bool command_proc(uint8_t code) { - switch (command_state) { - case ONESHOT: - if (!IS_COMMAND()) return false; - return (command_extra(code) || command_common(code)); - break; - case CONSOLE: - if (IS_COMMAND()) - return (command_extra(code) || command_common(code)); - else - return (command_console_extra(code) || command_console(code)); - break; -#if defined(MOUSEKEY_ENABLE) - case MOUSEKEY: - mousekey_console(code); - break; -#endif - default: - command_state = ONESHOT; - return false; - } - return true; -} - -/* TODO: Refactoring is needed. */ -/* This allows to define extra commands. return false when not processed. */ -bool command_extra(uint8_t code) __attribute__((weak)); -bool command_extra(uint8_t code) { - (void)code; - return false; -} - -bool command_console_extra(uint8_t code) __attribute__((weak)); -bool command_console_extra(uint8_t code) { - (void)code; - return false; -} - -/*********************************************************** - * Command common - ***********************************************************/ - -static void command_common_help(void) { - print(/* clang-format off */ - "\n\t- Magic -\n" - - STR(MAGIC_KEY_DEBUG) ": Debug Message Toggle\n" - STR(MAGIC_KEY_DEBUG_MATRIX) ": Matrix Debug Mode Toggle" - " - Show keypresses in matrix grid\n" - STR(MAGIC_KEY_DEBUG_KBD) ": Keyboard Debug Toggle" - " - Show keypress report\n" - STR(MAGIC_KEY_DEBUG_MOUSE) ": Debug Mouse Toggle\n" - STR(MAGIC_KEY_VERSION) ": Version\n" - STR(MAGIC_KEY_STATUS) ": Status\n" - STR(MAGIC_KEY_CONSOLE) ": Activate Console Mode\n" - -#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM - STR(MAGIC_KEY_LAYER0) ": Switch to Layer 0\n" - STR(MAGIC_KEY_LAYER1) ": Switch to Layer 1\n" - STR(MAGIC_KEY_LAYER2) ": Switch to Layer 2\n" - STR(MAGIC_KEY_LAYER3) ": Switch to Layer 3\n" - STR(MAGIC_KEY_LAYER4) ": Switch to Layer 4\n" - STR(MAGIC_KEY_LAYER5) ": Switch to Layer 5\n" - STR(MAGIC_KEY_LAYER6) ": Switch to Layer 6\n" - STR(MAGIC_KEY_LAYER7) ": Switch to Layer 7\n" - STR(MAGIC_KEY_LAYER8) ": Switch to Layer 8\n" - STR(MAGIC_KEY_LAYER9) ": Switch to Layer 9\n" -#endif - -#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS - "F1-F10: Switch to Layer 0-9 (F10 = L0)\n" -#endif - -#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS - "0-9: Switch to Layer 0-9\n" -#endif - - STR(MAGIC_KEY_LAYER0_ALT) ": Switch to Layer 0 (alternate)\n" - - STR(MAGIC_KEY_BOOTLOADER) ": Jump to Bootloader\n" - STR(MAGIC_KEY_BOOTLOADER_ALT) ": Jump to Bootloader (alternate)\n" - -#ifdef KEYBOARD_LOCK_ENABLE - STR(MAGIC_KEY_LOCK) ": Lock Keyboard\n" -#endif - - STR(MAGIC_KEY_EEPROM) ": Print EEPROM Settings\n" - STR(MAGIC_KEY_EEPROM_CLEAR) ": Clear EEPROM\n" - -#ifdef NKRO_ENABLE - STR(MAGIC_KEY_NKRO) ": NKRO Toggle\n" -#endif - -#ifdef SLEEP_LED_ENABLE - STR(MAGIC_KEY_SLEEP_LED) ": Sleep LED Test\n" -#endif - ); /* clang-format on */ -} - -static void print_version(void) { - xprintf("%s", /* clang-format off */ - "\n\t- Version -\n" - "VID: " STR(VENDOR_ID) "(" STR(MANUFACTURER) ") " - "PID: " STR(PRODUCT_ID) "(" STR(PRODUCT) ") " - "VER: " STR(DEVICE_VER) "\n" - "BUILD: (" __DATE__ ")\n" -#ifndef SKIP_VERSION -# ifdef PROTOCOL_CHIBIOS - "CHIBIOS: " STR(CHIBIOS_VERSION) - ", CONTRIB: " STR(CHIBIOS_CONTRIB_VERSION) "\n" -# endif -#endif - - /* build options */ - "OPTIONS:" - -#ifdef PROTOCOL_LUFA - " LUFA" -#endif -#ifdef PROTOCOL_VUSB - " VUSB" -#endif -#ifdef BOOTMAGIC_ENABLE - " BOOTMAGIC" -#endif -#ifdef MOUSEKEY_ENABLE - " MOUSEKEY" -#endif -#ifdef EXTRAKEY_ENABLE - " EXTRAKEY" -#endif -#ifdef CONSOLE_ENABLE - " CONSOLE" -#endif -#ifdef COMMAND_ENABLE - " COMMAND" -#endif -#ifdef NKRO_ENABLE - " NKRO" -#endif -#ifdef LTO_ENABLE - " LTO" -#endif - - " " STR(BOOTLOADER_SIZE) "\n" - - "GCC: " STR(__GNUC__) - "." STR(__GNUC_MINOR__) - "." STR(__GNUC_PATCHLEVEL__) -#if defined(__AVR__) - " AVR-LIBC: " __AVR_LIBC_VERSION_STRING__ - " AVR_ARCH: avr" STR(__AVR_ARCH__) -#endif - "\n" - ); /* clang-format on */ -} - -static void print_status(void) { - xprintf(/* clang-format off */ - "\n\t- Status -\n" - - "host_keyboard_leds(): %02X\n" -#ifndef PROTOCOL_VUSB - "keyboard_protocol: %02X\n" - "keyboard_idle: %02X\n" -#endif -#ifdef NKRO_ENABLE - "keymap_config.nkro: %02X\n" -#endif - "timer_read32(): %08lX\n" - - , host_keyboard_leds() -#ifndef PROTOCOL_VUSB - /* these aren't set on the V-USB protocol, so we just ignore them for now */ - , keyboard_protocol - , keyboard_idle -#endif -#ifdef NKRO_ENABLE - , keymap_config.nkro -#endif - , timer_read32() - - ); /* clang-format on */ -} - -#if !defined(NO_PRINT) && !defined(USER_PRINT) -static void print_eeconfig(void) { - xprintf("eeconfig:\ndefault_layer: %u\n", eeconfig_read_default_layer()); - - debug_config_t dc; - dc.raw = eeconfig_read_debug(); - xprintf(/* clang-format off */ - - "debug_config.raw: %02X\n" - ".enable: %u\n" - ".matrix: %u\n" - ".keyboard: %u\n" - ".mouse: %u\n" - - , dc.raw - , dc.enable - , dc.matrix - , dc.keyboard - , dc.mouse - ); /* clang-format on */ - - keymap_config_t kc; - kc.raw = eeconfig_read_keymap(); - xprintf(/* clang-format off */ - - "keymap_config.raw: %02X\n" - ".swap_control_capslock: %u\n" - ".capslock_to_control: %u\n" - ".swap_lctl_lgui: %u\n" - ".swap_rctl_rgui: %u\n" - ".swap_lalt_lgui: %u\n" - ".swap_ralt_rgui: %u\n" - ".no_gui: %u\n" - ".swap_grave_esc: %u\n" - ".swap_backslash_backspace: %u\n" - ".nkro: %u\n" - ".swap_escape_capslock: %u\n" - - , kc.raw - , kc.swap_control_capslock - , kc.capslock_to_control - , kc.swap_lctl_lgui - , kc.swap_rctl_rgui - , kc.swap_lalt_lgui - , kc.swap_ralt_rgui - , kc.no_gui - , kc.swap_grave_esc - , kc.swap_backslash_backspace - , kc.nkro - , kc.swap_escape_capslock - ); /* clang-format on */ - -# ifdef BACKLIGHT_ENABLE - - backlight_config_t bc; - bc.raw = eeconfig_read_backlight(); - xprintf(/* clang-format off */ - "backlight_config" - - ".raw: %02X\n" - ".enable: %u\n" - ".level: %u\n" - - , bc.raw - , bc.enable - , bc.level - - ); /* clang-format on */ - -# endif /* BACKLIGHT_ENABLE */ -} -#endif /* !NO_PRINT && !USER_PRINT */ - -static bool command_common(uint8_t code) { -#ifdef KEYBOARD_LOCK_ENABLE - static host_driver_t *host_driver = 0; -#endif - - switch (code) { -#ifdef SLEEP_LED_ENABLE - - // test breathing sleep LED - case MAGIC_KC(MAGIC_KEY_SLEEP_LED): - print("Sleep LED Test\n"); - sleep_led_toggle(); - led_set(host_keyboard_leds()); - break; -#endif - - // print stored eeprom config - case MAGIC_KC(MAGIC_KEY_EEPROM): -#if !defined(NO_PRINT) && !defined(USER_PRINT) - print_eeconfig(); -#endif /* !NO_PRINT && !USER_PRINT */ - break; - - // clear eeprom - case MAGIC_KC(MAGIC_KEY_EEPROM_CLEAR): - print("Clearing EEPROM\n"); - eeconfig_init(); - break; - -#ifdef KEYBOARD_LOCK_ENABLE - - // lock/unlock keyboard - case MAGIC_KC(MAGIC_KEY_LOCK): - if (host_get_driver()) { - host_driver = host_get_driver(); - clear_keyboard(); - host_set_driver(0); - print("Locked.\n"); - } else { - host_set_driver(host_driver); - print("Unlocked.\n"); - } - break; -#endif - - // print help - case MAGIC_KC(MAGIC_KEY_HELP): - case MAGIC_KC(MAGIC_KEY_HELP_ALT): - command_common_help(); - break; - - // activate console - case MAGIC_KC(MAGIC_KEY_CONSOLE): - debug_matrix = false; - debug_keyboard = false; - debug_mouse = false; - debug_enable = false; - command_console_help(); - print("C> "); - command_state = CONSOLE; - break; - - // jump to bootloader - case MAGIC_KC(MAGIC_KEY_BOOTLOADER): - case MAGIC_KC(MAGIC_KEY_BOOTLOADER_ALT): - print("\n\nJumping to bootloader... "); - reset_keyboard(); - break; - - // debug toggle - case MAGIC_KC(MAGIC_KEY_DEBUG): - debug_enable = !debug_enable; - if (debug_enable) { - print("\ndebug: on\n"); - } else { - print("\ndebug: off\n"); - debug_matrix = false; - debug_keyboard = false; - debug_mouse = false; - } - break; - - // debug matrix toggle - case MAGIC_KC(MAGIC_KEY_DEBUG_MATRIX): - debug_matrix = !debug_matrix; - if (debug_matrix) { - print("\nmatrix: on\n"); - debug_enable = true; - } else { - print("\nmatrix: off\n"); - } - break; - - // debug keyboard toggle - case MAGIC_KC(MAGIC_KEY_DEBUG_KBD): - debug_keyboard = !debug_keyboard; - if (debug_keyboard) { - print("\nkeyboard: on\n"); - debug_enable = true; - } else { - print("\nkeyboard: off\n"); - } - break; - - // debug mouse toggle - case MAGIC_KC(MAGIC_KEY_DEBUG_MOUSE): - debug_mouse = !debug_mouse; - if (debug_mouse) { - print("\nmouse: on\n"); - debug_enable = true; - } else { - print("\nmouse: off\n"); - } - break; - - // print version - case MAGIC_KC(MAGIC_KEY_VERSION): - print_version(); - break; - - // print status - case MAGIC_KC(MAGIC_KEY_STATUS): - print_status(); - break; - -#ifdef NKRO_ENABLE - - // NKRO toggle - case MAGIC_KC(MAGIC_KEY_NKRO): - clear_keyboard(); // clear to prevent stuck keys - keymap_config.nkro = !keymap_config.nkro; - if (keymap_config.nkro) { - print("NKRO: on\n"); - } else { - print("NKRO: off\n"); - } - break; -#endif - - // switch layers - - case MAGIC_KC(MAGIC_KEY_LAYER0_ALT): - switch_default_layer(0); - break; - -#if MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM - - case MAGIC_KC(MAGIC_KEY_LAYER0): - switch_default_layer(0); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER1): - switch_default_layer(1); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER2): - switch_default_layer(2); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER3): - switch_default_layer(3); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER4): - switch_default_layer(4); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER5): - switch_default_layer(5); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER6): - switch_default_layer(6); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER7): - switch_default_layer(7); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER8): - switch_default_layer(8); - break; - - case MAGIC_KC(MAGIC_KEY_LAYER9): - switch_default_layer(9); - break; -#endif - -#if MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS - - case KC_F1 ... KC_F9: - switch_default_layer((code - KC_F1) + 1); - break; - case KC_F10: - switch_default_layer(0); - break; -#endif - -#if MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS - - case KC_1 ... KC_9: - switch_default_layer((code - KC_1) + 1); - break; - case KC_0: - switch_default_layer(0); - break; -#endif - - default: - print("?"); - return false; - } - return true; -} - -/*********************************************************** - * Command console - ***********************************************************/ -static void command_console_help(void) { - print("\n\t- Console -\n" - "ESC/q: quit\n" -#ifdef MOUSEKEY_ENABLE - "m: mousekey\n" -#endif - ); -} - -static bool command_console(uint8_t code) { - switch (code) { - case KC_H: - case KC_SLASH: /* ? */ - command_console_help(); - print("C> "); - return true; - case KC_Q: - case KC_ESC: - command_state = ONESHOT; - return false; -#if defined(MOUSEKEY_ENABLE) - case KC_M: - command_state = MOUSEKEY; - mousekey_console(KC_SLASH /* ? */); - return true; -#endif - default: - print("?"); - return false; - } -} - -/*********************************************************** - * Mousekey console - ***********************************************************/ - -#if defined(MOUSEKEY_ENABLE) - -# if !defined(NO_PRINT) && !defined(USER_PRINT) -static void mousekey_param_print(void) { - xprintf(/* clang-format off */ - -#ifndef MK_3_SPEED - "1: delay(*10ms): %u\n" - "2: interval(ms): %u\n" - "3: max_speed: %u\n" - "4: time_to_max: %u\n" - "5: wheel_max_speed: %u\n" - "6: wheel_time_to_max: %u\n" - - , mk_delay - , mk_interval - , mk_max_speed - , mk_time_to_max - , mk_wheel_max_speed - , mk_wheel_time_to_max -#else - "no knobs sorry\n" -#endif - - ); /* clang-format on */ -} -# endif /* !NO_PRINT && !USER_PRINT */ - -# if !defined(NO_PRINT) && !defined(USER_PRINT) -static void mousekey_console_help(void) { - mousekey_param_print(); - xprintf(/* clang-format off */ - "p: print values\n" - "d: set defaults\n" - "up: +1\n" - "dn: -1\n" - "lt: +10\n" - "rt: -10\n" - "ESC/q: quit\n" - -#ifndef MK_3_SPEED - "\n" - "speed = delta * max_speed * (repeat / time_to_max)\n" - "where delta: cursor=%d, wheel=%d\n" - "See http://en.wikipedia.org/wiki/Mouse_keys\n" - , MOUSEKEY_MOVE_DELTA, MOUSEKEY_WHEEL_DELTA -#endif - - ); /* clang-format on */ -} -# endif /* !NO_PRINT && !USER_PRINT */ - -/* Only used by `quantum/command.c` / `command_proc()`. To avoid - * any doubt: we return `false` to return to the main console, - * which differs from the `bool` that `command_proc()` returns. */ -bool mousekey_console(uint8_t code) { - static uint8_t param = 0; - static uint8_t *pp = NULL; - static char * desc = NULL; - -# if defined(NO_PRINT) || defined(USER_PRINT) /* -Wunused-parameter */ - (void)desc; -# endif - - int8_t change = 0; - - switch (code) { - case KC_H: - case KC_SLASH: /* ? */ -# if !defined(NO_PRINT) && !defined(USER_PRINT) - print("\n\t- Mousekey -\n"); - mousekey_console_help(); -# endif - break; - - case KC_Q: - case KC_ESC: - print("q\n"); - if (!param) return false; - param = 0; - pp = NULL; - desc = NULL; - break; - - case KC_P: -# if !defined(NO_PRINT) && !defined(USER_PRINT) - print("\n\t- Values -\n"); - mousekey_param_print(); -# endif - break; - - case KC_1 ... KC_0: /* KC_0 gives param = 10 */ - param = 1 + code - KC_1; - switch (param) { /* clang-format off */ -# define PARAM(n, v) case n: pp = &(v); desc = #v; break - -#ifndef MK_3_SPEED - PARAM(1, mk_delay); - PARAM(2, mk_interval); - PARAM(3, mk_max_speed); - PARAM(4, mk_time_to_max); - PARAM(5, mk_wheel_max_speed); - PARAM(6, mk_wheel_time_to_max); -#endif /* MK_3_SPEED */ - -# undef PARAM - default: - param = 0; - print("?\n"); - break; - } /* clang-format on */ - if (param) xprintf("%u\n", param); - break; - - /* clang-format off */ - case KC_UP: change = +1; break; - case KC_DOWN: change = -1; break; - case KC_LEFT: change = -10; break; - case KC_RIGHT: change = +10; break; - /* clang-format on */ - - case KC_D: - -# ifndef MK_3_SPEED - mk_delay = MOUSEKEY_DELAY / 10; - mk_interval = MOUSEKEY_INTERVAL; - mk_max_speed = MOUSEKEY_MAX_SPEED; - mk_time_to_max = MOUSEKEY_TIME_TO_MAX; - mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; - mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; -# endif /* MK_3_SPEED */ - - print("defaults\n"); - break; - - default: - print("?\n"); - break; - } - - if (change) { - if (pp) { - int16_t val = *pp + change; - if (val > (int16_t)UINT8_MAX) - *pp = UINT8_MAX; - else if (val < 0) - *pp = 0; - else - *pp = (uint8_t)val; - xprintf("= %u\n", *pp); - } else { - print("?\n"); - } - } - - if (param) { - xprintf("M%u:%s> ", param, desc ? desc : "???"); - } else { - print("M> "); - } - return true; -} - -#endif /* MOUSEKEY_ENABLE */ - -/*********************************************************** - * Utilities - ***********************************************************/ - -static void switch_default_layer(uint8_t layer) { - xprintf("L%d\n", layer); - default_layer_set((layer_state_t)1 << layer); - clear_keyboard(); -} diff --git a/quantum/command.h b/quantum/command.h deleted file mode 100644 index a63f9ec7a70d..000000000000 --- a/quantum/command.h +++ /dev/null @@ -1,162 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -/* FIXME: Add doxygen comments for the behavioral defines in here. */ - -/* TODO: Refactoring */ -typedef enum { ONESHOT, CONSOLE, MOUSEKEY } command_state_t; -extern command_state_t command_state; - -/* This allows to extend commands. Return false when command is not processed. */ -bool command_extra(uint8_t code); -bool command_console_extra(uint8_t code); - -#ifdef COMMAND_ENABLE -bool command_proc(uint8_t code); -#else -# define command_proc(code) false -#endif - -#ifndef IS_COMMAND -# define IS_COMMAND() (get_mods() == MOD_MASK_SHIFT) -#endif - -#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS -# define MAGIC_KEY_SWITCH_LAYER_WITH_FKEYS true -#endif - -#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS -# define MAGIC_KEY_SWITCH_LAYER_WITH_NKEYS true -#endif - -#ifndef MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM -# define MAGIC_KEY_SWITCH_LAYER_WITH_CUSTOM false -#endif - -#ifndef MAGIC_KEY_HELP -# define MAGIC_KEY_HELP H -#endif - -#ifndef MAGIC_KEY_HELP_ALT -# define MAGIC_KEY_HELP_ALT SLASH -#endif - -#ifndef MAGIC_KEY_DEBUG -# define MAGIC_KEY_DEBUG D -#endif - -#ifndef MAGIC_KEY_DEBUG_MATRIX -# define MAGIC_KEY_DEBUG_MATRIX X -#endif - -#ifndef MAGIC_KEY_DEBUG_KBD -# define MAGIC_KEY_DEBUG_KBD K -#endif - -#ifndef MAGIC_KEY_DEBUG_MOUSE -# define MAGIC_KEY_DEBUG_MOUSE M -#endif - -#ifndef MAGIC_KEY_VERSION -# define MAGIC_KEY_VERSION V -#endif - -#ifndef MAGIC_KEY_STATUS -# define MAGIC_KEY_STATUS S -#endif - -#ifndef MAGIC_KEY_CONSOLE -# define MAGIC_KEY_CONSOLE C -#endif - -#ifndef MAGIC_KEY_LAYER0 -# define MAGIC_KEY_LAYER0 0 -#endif - -#ifndef MAGIC_KEY_LAYER0_ALT -# define MAGIC_KEY_LAYER0_ALT GRAVE -#endif - -#ifndef MAGIC_KEY_LAYER1 -# define MAGIC_KEY_LAYER1 1 -#endif - -#ifndef MAGIC_KEY_LAYER2 -# define MAGIC_KEY_LAYER2 2 -#endif - -#ifndef MAGIC_KEY_LAYER3 -# define MAGIC_KEY_LAYER3 3 -#endif - -#ifndef MAGIC_KEY_LAYER4 -# define MAGIC_KEY_LAYER4 4 -#endif - -#ifndef MAGIC_KEY_LAYER5 -# define MAGIC_KEY_LAYER5 5 -#endif - -#ifndef MAGIC_KEY_LAYER6 -# define MAGIC_KEY_LAYER6 6 -#endif - -#ifndef MAGIC_KEY_LAYER7 -# define MAGIC_KEY_LAYER7 7 -#endif - -#ifndef MAGIC_KEY_LAYER8 -# define MAGIC_KEY_LAYER8 8 -#endif - -#ifndef MAGIC_KEY_LAYER9 -# define MAGIC_KEY_LAYER9 9 -#endif - -#ifndef MAGIC_KEY_BOOTLOADER -# define MAGIC_KEY_BOOTLOADER B -#endif - -#ifndef MAGIC_KEY_BOOTLOADER_ALT -# define MAGIC_KEY_BOOTLOADER_ALT ESC -#endif - -#ifndef MAGIC_KEY_LOCK -# define MAGIC_KEY_LOCK CAPS -#endif - -#ifndef MAGIC_KEY_EEPROM -# define MAGIC_KEY_EEPROM E -#endif - -#ifndef MAGIC_KEY_EEPROM_CLEAR -# define MAGIC_KEY_EEPROM_CLEAR BACKSPACE -#endif - -#ifndef MAGIC_KEY_NKRO -# define MAGIC_KEY_NKRO N -#endif - -#ifndef MAGIC_KEY_SLEEP_LED -# define MAGIC_KEY_SLEEP_LED Z - -#endif - -#define XMAGIC_KC(key) KC_##key -#define MAGIC_KC(key) XMAGIC_KC(key) diff --git a/quantum/crc.c b/quantum/crc.c deleted file mode 100644 index 6b406df64af8..000000000000 --- a/quantum/crc.c +++ /dev/null @@ -1,75 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#include "crc.h" - -__attribute__((weak)) void crc_init(void) { - // Software implementation nothing todo here. -} - -#if defined(CRC8_USE_TABLE) -/** - * Static table used for the table_driven implementation. - */ -static const crc_t crc_table[256] = { - 0x00, 0x07, 0x0e, 0x09, 0x1c, 0x1b, 0x12, 0x15, 0x38, 0x3f, 0x36, 0x31, 0x24, 0x23, 0x2a, 0x2d, // - 0x70, 0x77, 0x7e, 0x79, 0x6c, 0x6b, 0x62, 0x65, 0x48, 0x4f, 0x46, 0x41, 0x54, 0x53, 0x5a, 0x5d, // - 0xe0, 0xe7, 0xee, 0xe9, 0xfc, 0xfb, 0xf2, 0xf5, 0xd8, 0xdf, 0xd6, 0xd1, 0xc4, 0xc3, 0xca, 0xcd, // - 0x90, 0x97, 0x9e, 0x99, 0x8c, 0x8b, 0x82, 0x85, 0xa8, 0xaf, 0xa6, 0xa1, 0xb4, 0xb3, 0xba, 0xbd, // - 0xc7, 0xc0, 0xc9, 0xce, 0xdb, 0xdc, 0xd5, 0xd2, 0xff, 0xf8, 0xf1, 0xf6, 0xe3, 0xe4, 0xed, 0xea, // - 0xb7, 0xb0, 0xb9, 0xbe, 0xab, 0xac, 0xa5, 0xa2, 0x8f, 0x88, 0x81, 0x86, 0x93, 0x94, 0x9d, 0x9a, // - 0x27, 0x20, 0x29, 0x2e, 0x3b, 0x3c, 0x35, 0x32, 0x1f, 0x18, 0x11, 0x16, 0x03, 0x04, 0x0d, 0x0a, // - 0x57, 0x50, 0x59, 0x5e, 0x4b, 0x4c, 0x45, 0x42, 0x6f, 0x68, 0x61, 0x66, 0x73, 0x74, 0x7d, 0x7a, // - 0x89, 0x8e, 0x87, 0x80, 0x95, 0x92, 0x9b, 0x9c, 0xb1, 0xb6, 0xbf, 0xb8, 0xad, 0xaa, 0xa3, 0xa4, // - 0xf9, 0xfe, 0xf7, 0xf0, 0xe5, 0xe2, 0xeb, 0xec, 0xc1, 0xc6, 0xcf, 0xc8, 0xdd, 0xda, 0xd3, 0xd4, // - 0x69, 0x6e, 0x67, 0x60, 0x75, 0x72, 0x7b, 0x7c, 0x51, 0x56, 0x5f, 0x58, 0x4d, 0x4a, 0x43, 0x44, // - 0x19, 0x1e, 0x17, 0x10, 0x05, 0x02, 0x0b, 0x0c, 0x21, 0x26, 0x2f, 0x28, 0x3d, 0x3a, 0x33, 0x34, // - 0x4e, 0x49, 0x40, 0x47, 0x52, 0x55, 0x5c, 0x5b, 0x76, 0x71, 0x78, 0x7f, 0x6a, 0x6d, 0x64, 0x63, // - 0x3e, 0x39, 0x30, 0x37, 0x22, 0x25, 0x2c, 0x2b, 0x06, 0x01, 0x08, 0x0f, 0x1a, 0x1d, 0x14, 0x13, // - 0xae, 0xa9, 0xa0, 0xa7, 0xb2, 0xb5, 0xbc, 0xbb, 0x96, 0x91, 0x98, 0x9f, 0x8a, 0x8d, 0x84, 0x83, // - 0xde, 0xd9, 0xd0, 0xd7, 0xc2, 0xc5, 0xcc, 0xcb, 0xe6, 0xe1, 0xe8, 0xef, 0xfa, 0xfd, 0xf4, 0xf3 // -}; - -__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) { - const uint8_t *d = (const uint8_t *)data; - crc_t crc = 0xff; - size_t tbl_idx; - - while (data_len--) { - tbl_idx = crc ^ *d; - crc = crc_table[tbl_idx] & 0xff; - d++; - } - return crc & 0xff; -} -#else -__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len) { - const uint8_t *d = (const uint8_t *)data; - crc_t crc = 0xff; - size_t i, j; - - for (i = 0; i < data_len; i++) { - crc ^= d[i]; - for (j = 0; j < 8; j++) { - if ((crc & 0x80) != 0) - crc = (crc_t)((crc << 1) ^ 0x31); - else - crc <<= 1; - } - } - return crc; -} -#endif diff --git a/quantum/crc.h b/quantum/crc.h deleted file mode 100644 index 86635847d077..000000000000 --- a/quantum/crc.h +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#pragma once - -#include -#include - -/** - * The type of the CRC values. - * - * This type must be big enough to contain at least 8 bits. - */ -#if defined(CRC8_OPTIMIZE_SPEED) -typedef uint_fast8_t crc_t; -#else -typedef uint_least8_t crc_t; -#endif - -/** - * Initialize crc subsystem. - */ -__attribute__((weak)) void crc_init(void); - -/** - * Generate CRC8 value from given data. - * - * \param[in] data Pointer to a buffer of \a data_len bytes. - * \param[in] data_len Number of bytes in the \a data buffer. - * \return The calculated crc value. - */ -__attribute__((weak)) uint8_t crc8(const void *data, size_t data_len); diff --git a/quantum/debounce.h b/quantum/debounce.h deleted file mode 100644 index a8629654c20f..000000000000 --- a/quantum/debounce.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -/** - * @brief Debounce raw matrix events according to the choosen debounce algorithm. - * - * @param raw The current key state - * @param cooked The debounced key state - * @param num_rows Number of rows to debounce - * @param changed True if raw has changed since the last call - * @return true Cooked has new keychanges after debouncing - * @return false Cooked is the same as before - */ -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed); - -void debounce_init(uint8_t num_rows); - -void debounce_free(void); diff --git a/quantum/debounce/asym_eager_defer_pk.c b/quantum/debounce/asym_eager_defer_pk.c deleted file mode 100644 index 4745c6f4654f..000000000000 --- a/quantum/debounce/asym_eager_defer_pk.c +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright 2017 Alex Ong - * Copyright 2020 Andrei Purdea - * Copyright 2021 Simon Arlott - * - * 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 . - */ - -/* -Basic symmetric per-key algorithm. Uses an 8-bit counter per key. -When no state changes have occured for DEBOUNCE milliseconds, we push the state. -*/ - -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include - -#ifdef PROTOCOL_CHIBIOS -# if CH_CFG_USE_MEMCORE == FALSE -# error ChibiOS is configured without a memory allocator. Your keyboard may have set `#define CH_CFG_USE_MEMCORE FALSE`, which is incompatible with this debounce algorithm. -# endif -#endif - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -// Maximum debounce: 127ms -#if DEBOUNCE > 127 -# undef DEBOUNCE -# define DEBOUNCE 127 -#endif - -#define ROW_SHIFTER ((matrix_row_t)1) - -typedef struct { - bool pressed : 1; - uint8_t time : 7; -} debounce_counter_t; - -#if DEBOUNCE > 0 -static debounce_counter_t *debounce_counters; -static fast_timer_t last_time; -static bool counters_need_update; -static bool matrix_need_update; -static bool cooked_changed; - -# define DEBOUNCE_ELAPSED 0 - -static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time); -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); - -// we use num_rows rather than MATRIX_ROWS to support split keyboards -void debounce_init(uint8_t num_rows) { - debounce_counters = malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); - int i = 0; - for (uint8_t r = 0; r < num_rows; r++) { - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - debounce_counters[i++].time = DEBOUNCE_ELAPSED; - } - } -} - -void debounce_free(void) { - free(debounce_counters); - debounce_counters = NULL; -} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool updated_last = false; - cooked_changed = false; - - if (counters_need_update) { - fast_timer_t now = timer_read_fast(); - fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); - - last_time = now; - updated_last = true; - if (elapsed_time > UINT8_MAX) { - elapsed_time = UINT8_MAX; - } - - if (elapsed_time > 0) { - update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, elapsed_time); - } - } - - if (changed || matrix_need_update) { - if (!updated_last) { - last_time = timer_read_fast(); - } - - transfer_matrix_values(raw, cooked, num_rows); - } - - return cooked_changed; -} - -static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time) { - debounce_counter_t *debounce_pointer = debounce_counters; - - counters_need_update = false; - matrix_need_update = false; - - for (uint8_t row = 0; row < num_rows; row++) { - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - matrix_row_t col_mask = (ROW_SHIFTER << col); - - if (debounce_pointer->time != DEBOUNCE_ELAPSED) { - if (debounce_pointer->time <= elapsed_time) { - debounce_pointer->time = DEBOUNCE_ELAPSED; - - if (debounce_pointer->pressed) { - // key-down: eager - matrix_need_update = true; - } else { - // key-up: defer - matrix_row_t cooked_next = (cooked[row] & ~col_mask) | (raw[row] & col_mask); - cooked_changed |= cooked_next ^ cooked[row]; - cooked[row] = cooked_next; - } - } else { - debounce_pointer->time -= elapsed_time; - counters_need_update = true; - } - } - debounce_pointer++; - } - } -} - -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) { - debounce_counter_t *debounce_pointer = debounce_counters; - - for (uint8_t row = 0; row < num_rows; row++) { - matrix_row_t delta = raw[row] ^ cooked[row]; - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - matrix_row_t col_mask = (ROW_SHIFTER << col); - - if (delta & col_mask) { - if (debounce_pointer->time == DEBOUNCE_ELAPSED) { - debounce_pointer->pressed = (raw[row] & col_mask); - debounce_pointer->time = DEBOUNCE; - counters_need_update = true; - - if (debounce_pointer->pressed) { - // key-down: eager - cooked[row] ^= col_mask; - cooked_changed = true; - } - } - } else if (debounce_pointer->time != DEBOUNCE_ELAPSED) { - if (!debounce_pointer->pressed) { - // key-up: defer - debounce_pointer->time = DEBOUNCE_ELAPSED; - } - } - debounce_pointer++; - } - } -} - -#else -# include "none.c" -#endif diff --git a/quantum/debounce/none.c b/quantum/debounce/none.c deleted file mode 100644 index 4cff5e05e260..000000000000 --- a/quantum/debounce/none.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "matrix.h" -#include "quantum.h" -#include -#include - -void debounce_init(uint8_t num_rows) {} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool cooked_changed = memcmp(raw, cooked, sizeof(matrix_row_t) * num_rows) != 0; - - memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows); - - return cooked_changed; -} - -void debounce_free(void) {} diff --git a/quantum/debounce/sym_defer_g.c b/quantum/debounce/sym_defer_g.c deleted file mode 100644 index d04310a76151..000000000000 --- a/quantum/debounce/sym_defer_g.c +++ /dev/null @@ -1,56 +0,0 @@ -/* -Copyright 2017 Alex Ong -Copyright 2021 Simon Arlott -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 . -*/ - -/* -Basic global debounce algorithm. Used in 99% of keyboards at time of implementation -When no state changes have occured for DEBOUNCE milliseconds, we push the state. -*/ -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -#if DEBOUNCE > 0 -static bool debouncing = false; -static fast_timer_t debouncing_time; - -void debounce_init(uint8_t num_rows) {} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool cooked_changed = false; - - if (changed) { - debouncing = true; - debouncing_time = timer_read_fast(); - } - - if (debouncing && timer_elapsed_fast(debouncing_time) >= DEBOUNCE) { - if (memcmp(cooked, raw, sizeof(matrix_row_t) * num_rows) != 0) { - memcpy(cooked, raw, sizeof(matrix_row_t) * num_rows); - cooked_changed = true; - } - debouncing = false; - } - - return cooked_changed; -} - -void debounce_free(void) {} -#else // no debouncing. -# include "none.c" -#endif diff --git a/quantum/debounce/sym_defer_pk.c b/quantum/debounce/sym_defer_pk.c deleted file mode 100644 index 7b59b5e10076..000000000000 --- a/quantum/debounce/sym_defer_pk.c +++ /dev/null @@ -1,145 +0,0 @@ -/* -Copyright 2017 Alex Ong -Copyright 2020 Andrei Purdea -Copyright 2021 Simon Arlott -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 . -*/ - -/* -Basic symmetric per-key algorithm. Uses an 8-bit counter per key. -When no state changes have occured for DEBOUNCE milliseconds, we push the state. -*/ - -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include - -#ifdef PROTOCOL_CHIBIOS -# if CH_CFG_USE_MEMCORE == FALSE -# error ChibiOS is configured without a memory allocator. Your keyboard may have set `#define CH_CFG_USE_MEMCORE FALSE`, which is incompatible with this debounce algorithm. -# endif -#endif - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -// Maximum debounce: 255ms -#if DEBOUNCE > UINT8_MAX -# undef DEBOUNCE -# define DEBOUNCE UINT8_MAX -#endif - -#define ROW_SHIFTER ((matrix_row_t)1) - -typedef uint8_t debounce_counter_t; - -#if DEBOUNCE > 0 -static debounce_counter_t *debounce_counters; -static fast_timer_t last_time; -static bool counters_need_update; -static bool cooked_changed; - -# define DEBOUNCE_ELAPSED 0 - -static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time); -static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); - -// we use num_rows rather than MATRIX_ROWS to support split keyboards -void debounce_init(uint8_t num_rows) { - debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); - int i = 0; - for (uint8_t r = 0; r < num_rows; r++) { - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - debounce_counters[i++] = DEBOUNCE_ELAPSED; - } - } -} - -void debounce_free(void) { - free(debounce_counters); - debounce_counters = NULL; -} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool updated_last = false; - cooked_changed = false; - - if (counters_need_update) { - fast_timer_t now = timer_read_fast(); - fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); - - last_time = now; - updated_last = true; - if (elapsed_time > UINT8_MAX) { - elapsed_time = UINT8_MAX; - } - - if (elapsed_time > 0) { - update_debounce_counters_and_transfer_if_expired(raw, cooked, num_rows, elapsed_time); - } - } - - if (changed) { - if (!updated_last) { - last_time = timer_read_fast(); - } - - start_debounce_counters(raw, cooked, num_rows); - } - - return cooked_changed; -} - -static void update_debounce_counters_and_transfer_if_expired(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, uint8_t elapsed_time) { - counters_need_update = false; - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - if (*debounce_pointer != DEBOUNCE_ELAPSED) { - if (*debounce_pointer <= elapsed_time) { - *debounce_pointer = DEBOUNCE_ELAPSED; - matrix_row_t cooked_next = (cooked[row] & ~(ROW_SHIFTER << col)) | (raw[row] & (ROW_SHIFTER << col)); - cooked_changed |= cooked[row] ^ cooked_next; - cooked[row] = cooked_next; - } else { - *debounce_pointer -= elapsed_time; - counters_need_update = true; - } - } - debounce_pointer++; - } - } -} - -static void start_debounce_counters(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) { - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - matrix_row_t delta = raw[row] ^ cooked[row]; - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - if (delta & (ROW_SHIFTER << col)) { - if (*debounce_pointer == DEBOUNCE_ELAPSED) { - *debounce_pointer = DEBOUNCE; - counters_need_update = true; - } - } else { - *debounce_pointer = DEBOUNCE_ELAPSED; - } - debounce_pointer++; - } - } -} - -#else -# include "none.c" -#endif diff --git a/quantum/debounce/sym_defer_pr.c b/quantum/debounce/sym_defer_pr.c deleted file mode 100644 index 452c4599d0a7..000000000000 --- a/quantum/debounce/sym_defer_pr.c +++ /dev/null @@ -1,78 +0,0 @@ -/* -Copyright 2021 Chad Austin -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 . -*/ - -/* -Symmetric per-row debounce algorithm. Changes only apply when -DEBOUNCE milliseconds have elapsed since the last change. -*/ - -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -static uint16_t last_time; -// [row] milliseconds until key's state is considered debounced. -static uint8_t* countdowns; -// [row] -static matrix_row_t* last_raw; - -void debounce_init(uint8_t num_rows) { - countdowns = (uint8_t*)calloc(num_rows, sizeof(uint8_t)); - last_raw = (matrix_row_t*)calloc(num_rows, sizeof(matrix_row_t)); - - last_time = timer_read(); -} - -void debounce_free(void) { - free(countdowns); - countdowns = NULL; - free(last_raw); - last_raw = NULL; -} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - uint16_t now = timer_read(); - uint16_t elapsed16 = TIMER_DIFF_16(now, last_time); - last_time = now; - uint8_t elapsed = (elapsed16 > 255) ? 255 : elapsed16; - bool cooked_changed = false; - - uint8_t* countdown = countdowns; - - for (uint8_t row = 0; row < num_rows; ++row, ++countdown) { - matrix_row_t raw_row = raw[row]; - - if (raw_row != last_raw[row]) { - *countdown = DEBOUNCE; - last_raw[row] = raw_row; - } else if (*countdown > elapsed) { - *countdown -= elapsed; - } else if (*countdown) { - cooked_changed |= cooked[row] ^ raw_row; - cooked[row] = raw_row; - *countdown = 0; - } - } - - return cooked_changed; -} - -bool debounce_active(void) { - return true; -} diff --git a/quantum/debounce/sym_eager_pk.c b/quantum/debounce/sym_eager_pk.c deleted file mode 100644 index f736d1645cd4..000000000000 --- a/quantum/debounce/sym_eager_pk.c +++ /dev/null @@ -1,150 +0,0 @@ -/* -Copyright 2017 Alex Ong -Copyright 2021 Simon Arlott -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 . -*/ - -/* -Basic per-key algorithm. Uses an 8-bit counter per key. -After pressing a key, it immediately changes state, and sets a counter. -No further inputs are accepted until DEBOUNCE milliseconds have occurred. -*/ - -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include - -#ifdef PROTOCOL_CHIBIOS -# if CH_CFG_USE_MEMCORE == FALSE -# error ChibiOS is configured without a memory allocator. Your keyboard may have set `#define CH_CFG_USE_MEMCORE FALSE`, which is incompatible with this debounce algorithm. -# endif -#endif - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -// Maximum debounce: 255ms -#if DEBOUNCE > UINT8_MAX -# undef DEBOUNCE -# define DEBOUNCE UINT8_MAX -#endif - -#define ROW_SHIFTER ((matrix_row_t)1) - -typedef uint8_t debounce_counter_t; - -#if DEBOUNCE > 0 -static debounce_counter_t *debounce_counters; -static fast_timer_t last_time; -static bool counters_need_update; -static bool matrix_need_update; -static bool cooked_changed; - -# define DEBOUNCE_ELAPSED 0 - -static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time); -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); - -// we use num_rows rather than MATRIX_ROWS to support split keyboards -void debounce_init(uint8_t num_rows) { - debounce_counters = (debounce_counter_t *)malloc(num_rows * MATRIX_COLS * sizeof(debounce_counter_t)); - int i = 0; - for (uint8_t r = 0; r < num_rows; r++) { - for (uint8_t c = 0; c < MATRIX_COLS; c++) { - debounce_counters[i++] = DEBOUNCE_ELAPSED; - } - } -} - -void debounce_free(void) { - free(debounce_counters); - debounce_counters = NULL; -} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool updated_last = false; - cooked_changed = false; - - if (counters_need_update) { - fast_timer_t now = timer_read_fast(); - fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); - - last_time = now; - updated_last = true; - if (elapsed_time > UINT8_MAX) { - elapsed_time = UINT8_MAX; - } - - if (elapsed_time > 0) { - update_debounce_counters(num_rows, elapsed_time); - } - } - - if (changed || matrix_need_update) { - if (!updated_last) { - last_time = timer_read_fast(); - } - - transfer_matrix_values(raw, cooked, num_rows); - } - - return cooked_changed; -} - -// If the current time is > debounce counter, set the counter to enable input. -static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) { - counters_need_update = false; - matrix_need_update = false; - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - if (*debounce_pointer != DEBOUNCE_ELAPSED) { - if (*debounce_pointer <= elapsed_time) { - *debounce_pointer = DEBOUNCE_ELAPSED; - matrix_need_update = true; - } else { - *debounce_pointer -= elapsed_time; - counters_need_update = true; - } - } - debounce_pointer++; - } - } -} - -// upload from raw_matrix to final matrix; -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) { - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - matrix_row_t delta = raw[row] ^ cooked[row]; - matrix_row_t existing_row = cooked[row]; - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - matrix_row_t col_mask = (ROW_SHIFTER << col); - if (delta & col_mask) { - if (*debounce_pointer == DEBOUNCE_ELAPSED) { - *debounce_pointer = DEBOUNCE; - counters_need_update = true; - existing_row ^= col_mask; // flip the bit. - cooked_changed = true; - } - } - debounce_pointer++; - } - cooked[row] = existing_row; - } -} - -#else -# include "none.c" -#endif diff --git a/quantum/debounce/sym_eager_pr.c b/quantum/debounce/sym_eager_pr.c deleted file mode 100644 index aad5ca351b89..000000000000 --- a/quantum/debounce/sym_eager_pr.c +++ /dev/null @@ -1,142 +0,0 @@ -/* -Copyright 2019 Alex Ong -Copyright 2021 Simon Arlott -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 . -*/ - -/* -Basic per-row algorithm. Uses an 8-bit counter per row. -After pressing a key, it immediately changes state, and sets a counter. -No further inputs are accepted until DEBOUNCE milliseconds have occurred. -*/ - -#include "matrix.h" -#include "timer.h" -#include "quantum.h" -#include - -#ifdef PROTOCOL_CHIBIOS -# if CH_CFG_USE_MEMCORE == FALSE -# error ChibiOS is configured without a memory allocator. Your keyboard may have set `#define CH_CFG_USE_MEMCORE FALSE`, which is incompatible with this debounce algorithm. -# endif -#endif - -#ifndef DEBOUNCE -# define DEBOUNCE 5 -#endif - -// Maximum debounce: 255ms -#if DEBOUNCE > UINT8_MAX -# undef DEBOUNCE -# define DEBOUNCE UINT8_MAX -#endif - -typedef uint8_t debounce_counter_t; - -#if DEBOUNCE > 0 -static bool matrix_need_update; - -static debounce_counter_t *debounce_counters; -static fast_timer_t last_time; -static bool counters_need_update; -static bool cooked_changed; - -# define DEBOUNCE_ELAPSED 0 - -static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time); -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows); - -// we use num_rows rather than MATRIX_ROWS to support split keyboards -void debounce_init(uint8_t num_rows) { - debounce_counters = (debounce_counter_t *)malloc(num_rows * sizeof(debounce_counter_t)); - for (uint8_t r = 0; r < num_rows; r++) { - debounce_counters[r] = DEBOUNCE_ELAPSED; - } -} - -void debounce_free(void) { - free(debounce_counters); - debounce_counters = NULL; -} - -bool debounce(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows, bool changed) { - bool updated_last = false; - cooked_changed = false; - - if (counters_need_update) { - fast_timer_t now = timer_read_fast(); - fast_timer_t elapsed_time = TIMER_DIFF_FAST(now, last_time); - - last_time = now; - updated_last = true; - if (elapsed_time > UINT8_MAX) { - elapsed_time = UINT8_MAX; - } - - if (elapsed_time > 0) { - update_debounce_counters(num_rows, elapsed_time); - } - } - - if (changed || matrix_need_update) { - if (!updated_last) { - last_time = timer_read_fast(); - } - - transfer_matrix_values(raw, cooked, num_rows); - } - - return cooked_changed; -} - -// If the current time is > debounce counter, set the counter to enable input. -static void update_debounce_counters(uint8_t num_rows, uint8_t elapsed_time) { - counters_need_update = false; - matrix_need_update = false; - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - if (*debounce_pointer != DEBOUNCE_ELAPSED) { - if (*debounce_pointer <= elapsed_time) { - *debounce_pointer = DEBOUNCE_ELAPSED; - matrix_need_update = true; - } else { - *debounce_pointer -= elapsed_time; - counters_need_update = true; - } - } - debounce_pointer++; - } -} - -// upload from raw_matrix to final matrix; -static void transfer_matrix_values(matrix_row_t raw[], matrix_row_t cooked[], uint8_t num_rows) { - debounce_counter_t *debounce_pointer = debounce_counters; - for (uint8_t row = 0; row < num_rows; row++) { - matrix_row_t existing_row = cooked[row]; - matrix_row_t raw_row = raw[row]; - - // determine new value basd on debounce pointer + raw value - if (existing_row != raw_row) { - if (*debounce_pointer == DEBOUNCE_ELAPSED) { - *debounce_pointer = DEBOUNCE; - cooked[row] = raw_row; - cooked_changed |= cooked[row] ^ raw[row]; - counters_need_update = true; - } - } - debounce_pointer++; - } -} - -#else -# include "none.c" -#endif diff --git a/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp b/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp deleted file mode 100644 index 44b4fe195607..000000000000 --- a/quantum/debounce/tests/asym_eager_defer_pk_tests.cpp +++ /dev/null @@ -1,394 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 1ms delay */ - {1, {{0, 1, UP}}, {}}, - - /* - * Until the eager timer on DOWN is observed to finish, the defer timer - * on UP can't start. There's no workaround for this because it's not - * possible to debounce an event that isn't being tracked. - * - * sym_defer_pk has the same problem but the test has to track that the - * key changed state so the DOWN timer is always allowed to finish - * before starting the UP timer. - */ - {5, {}, {}}, - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 2ms delay */ - {2, {{0, 1, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 3ms delay */ - {3, {{0, 1, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 4ms delay */ - {4, {{0, 1, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Release key after 5ms delay */ - {5, {{0, 1, UP}}, {}}, - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Release key after 6ms delay */ - {6, {{0, 1, UP}}, {}}, - - {11, {}, {{0, 1, UP}}}, /* 5ms after UP at time 6 */ - /* Press key again after 1ms delay */ - {12, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort7) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Release key after 7ms delay */ - {7, {{0, 1, UP}}, {}}, - - {12, {}, {{0, 1, UP}}}, /* 5ms after UP at time 7 */ - /* Press key again after 1ms delay */ - {13, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort8) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 1ms delay */ - {1, {{0, 1, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - - {10, {}, {{0, 1, UP}}}, /* 5ms after UP at time 7 */ - /* Press key again after 0ms delay (scan 2) */ - {10, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort9) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Release key after 1ms delay */ - {1, {{0, 1, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - - /* Press key again after 0ms delay (same scan) before debounce finishes */ - {10, {{0, 1, DOWN}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {}}, - {6, {{0, 1, DOWN}}, {}}, - {7, {{0, 1, UP}}, {}}, - {8, {{0, 1, DOWN}}, {}}, - {9, {{0, 1, UP}}, {}}, - {10, {{0, 1, DOWN}}, {}}, - {11, {{0, 1, UP}}, {}}, - {12, {{0, 1, DOWN}}, {}}, - {13, {{0, 1, UP}}, {}}, - {14, {{0, 1, DOWN}}, {}}, - {15, {{0, 1, UP}}, {}}, - - {20, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay */ - {21, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Change twice in the same time period */ - {1, {{0, 1, UP}}, {}}, - {1, {{0, 1, DOWN}}, {}}, - /* Change three times in the same time period */ - {2, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {2, {{0, 1, UP}}, {}}, - /* Change twice in the same time period */ - {6, {{0, 1, DOWN}}, {}}, - {6, {{0, 1, UP}}, {}}, - /* Change three times in the same time period */ - {7, {{0, 1, DOWN}}, {}}, - {7, {{0, 1, UP}}, {}}, - {7, {{0, 1, DOWN}}, {}}, - /* Change twice in the same time period */ - {8, {{0, 1, UP}}, {}}, - {8, {{0, 1, DOWN}}, {}}, - /* Change three times in the same time period */ - {9, {{0, 1, UP}}, {}}, - {9, {{0, 1, DOWN}}, {}}, - {9, {{0, 1, UP}}, {}}, - - {14, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay */ - {15, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {}}, - - {30, {}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {75, {{0, 1, UP}}, {}}, - - {80, {}, {{0, 1, UP}}}, - - {100, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, - /* Release key after 2ms delay */ - {2, {{0, 1, UP}}, {}}, - {3, {{0, 2, UP}}, {}}, - - {5, {}, {}}, /* See OneKeyShort1 */ - {6, {}, {}}, /* See OneKeyShort1 */ - - {10, {}, {{0, 1, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - /* Press key again after 1ms delay */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}, {0, 2, UP}}}, /* 5ms+5ms after DOWN at time 0 */ - {12, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, /* 5ms+5ms after DOWN at time 0 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late, immediately release key */ - {300, {{0, 1, UP}}, {}}, - - {305, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late, immediately release key */ - {300, {{0, 1, UP}}, {}}, - - /* Processing is very late again */ - {600, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late */ - {300, {}, {}}, - /* Release key after 1ms */ - {301, {{0, 1, UP}}, {}}, - - {306, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late */ - {300, {}, {}}, - /* Release key after 1ms */ - {301, {{0, 1, UP}}, {}}, - - /* Processing is very late again */ - {600, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {5, {{0, 1, UP}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, UP}}}, - /* Immediately press key again */ - {300, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {5, {{0, 1, UP}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, UP}}}, - - /* Press key again after 1ms */ - {301, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan7) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {5, {{0, 1, UP}}, {}}, - - /* Press key again before debounce expires */ - {300, {{0, 1, DOWN}}, {}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan8) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is a bit late */ - {50, {}, {}}, - /* Release key after 1ms */ - {51, {{0, 1, UP}}, {}}, - - /* Processing is a bit late again */ - {100, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/debounce_test_common.cpp b/quantum/debounce/tests/debounce_test_common.cpp deleted file mode 100644 index bd98e329554a..000000000000 --- a/quantum/debounce/tests/debounce_test_common.cpp +++ /dev/null @@ -1,211 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -#include -#include -#include - -extern "C" { -#include "quantum.h" -#include "timer.h" -#include "debounce.h" - -void set_time(uint32_t t); -void advance_time(uint32_t ms); -} - -void DebounceTest::addEvents(std::initializer_list events) { - events_.insert(events_.end(), events.begin(), events.end()); -} - -void DebounceTest::runEvents() { - /* Run the test multiple times, from 1kHz to 10kHz scan rate */ - for (extra_iterations_ = 0; extra_iterations_ < 10; extra_iterations_++) { - if (time_jumps_) { - /* Don't advance time smoothly, jump to the next event (some tests require this) */ - auto_advance_time_ = false; - runEventsInternal(); - } else { - /* Run the test with both smooth and irregular time; it must produce the same result */ - auto_advance_time_ = true; - runEventsInternal(); - auto_advance_time_ = false; - runEventsInternal(); - } - } -} - -void DebounceTest::runEventsInternal() { - fast_timer_t previous = 0; - bool first = true; - - /* Initialise keyboard with start time (offset to avoid testing at 0) and all keys UP */ - debounce_init(MATRIX_ROWS); - set_time(time_offset_); - std::fill(std::begin(input_matrix_), std::end(input_matrix_), 0); - std::fill(std::begin(output_matrix_), std::end(output_matrix_), 0); - - for (auto &event : events_) { - if (!auto_advance_time_) { - /* Jump to the next event */ - set_time(time_offset_ + event.time_); - } else if (!first && event.time_ == previous + 1) { - /* This event immediately follows the previous one, don't make extra debounce() calls */ - advance_time(1); - } else { - /* Fast forward to the time for this event, calling debounce() with no changes */ - ASSERT_LT((time_offset_ + event.time_) - timer_read_fast(), 60000) << "Test tries to advance more than 1 minute of time"; - - while (timer_read_fast() != time_offset_ + event.time_) { - runDebounce(false); - checkCookedMatrix(false, "debounce() modified cooked matrix"); - advance_time(1); - } - } - - first = false; - previous = event.time_; - - /* Prepare input matrix */ - for (auto &input : event.inputs_) { - matrixUpdate(input_matrix_, "input", input); - } - - /* Call debounce */ - runDebounce(!event.inputs_.empty()); - - /* Prepare output matrix */ - for (auto &output : event.outputs_) { - matrixUpdate(output_matrix_, "output", output); - } - - /* Check output matrix has expected change events */ - for (auto &output : event.outputs_) { - EXPECT_EQ(!!(cooked_matrix_[output.row_] & (1U << output.col_)), directionValue(output.direction_)) << "Missing event at " << strTime() << " expected key " << output.row_ << "," << output.col_ << " " << directionLabel(output.direction_) << "\ninput_matrix: changed=" << !event.inputs_.empty() << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_); - } - - /* Check output matrix has no other changes */ - checkCookedMatrix(!event.inputs_.empty(), "debounce() cooked matrix does not match expected output matrix"); - - /* Perform some extra iterations of the matrix scan with no changes */ - for (int i = 0; i < extra_iterations_; i++) { - runDebounce(false); - checkCookedMatrix(false, "debounce() modified cooked matrix"); - } - } - - /* Check that no further changes happen for 1 minute */ - for (int i = 0; i < 60000; i++) { - runDebounce(false); - checkCookedMatrix(false, "debounce() modified cooked matrix"); - advance_time(1); - } - - debounce_free(); -} - -void DebounceTest::runDebounce(bool changed) { - std::copy(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_)); - std::copy(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_)); - - bool cooked_changed = debounce(raw_matrix_, cooked_matrix_, MATRIX_ROWS, changed); - - if (!std::equal(std::begin(input_matrix_), std::end(input_matrix_), std::begin(raw_matrix_))) { - FAIL() << "Fatal error: debounce() modified raw matrix at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nraw_matrix:\n" << strMatrix(raw_matrix_); - } - - if (std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_)) && cooked_changed) { - FAIL() << "Fatal error: debounce() did detect a wrong cooked matrix change at " << strTime() << "\noutput_matrix: cooked_changed=" << cooked_changed << "\n" << strMatrix(output_matrix_) << "\ncooked_matrix:\n" << strMatrix(cooked_matrix_); - } -} - -void DebounceTest::checkCookedMatrix(bool changed, const std::string &error_message) { - if (!std::equal(std::begin(output_matrix_), std::end(output_matrix_), std::begin(cooked_matrix_))) { - FAIL() << "Unexpected event: " << error_message << " at " << strTime() << "\ninput_matrix: changed=" << changed << "\n" << strMatrix(input_matrix_) << "\nexpected_matrix:\n" << strMatrix(output_matrix_) << "\nactual_matrix:\n" << strMatrix(cooked_matrix_); - } -} - -std::string DebounceTest::strTime() { - std::stringstream text; - - text << "time " << (timer_read_fast() - time_offset_) << " (extra_iterations=" << extra_iterations_ << ", auto_advance_time=" << auto_advance_time_ << ")"; - - return text.str(); -} - -std::string DebounceTest::strMatrix(matrix_row_t matrix[]) { - std::stringstream text; - - text << "\t" << std::setw(3) << ""; - for (int col = 0; col < MATRIX_COLS; col++) { - text << " " << std::setw(2) << col; - } - text << "\n"; - - for (int row = 0; row < MATRIX_ROWS; row++) { - text << "\t" << std::setw(2) << row << ":"; - for (int col = 0; col < MATRIX_COLS; col++) { - text << ((matrix[row] & (1U << col)) ? " XX" : " __"); - } - - text << "\n"; - } - - return text.str(); -} - -bool DebounceTest::directionValue(Direction direction) { - switch (direction) { - case DOWN: - return true; - - case UP: - return false; - } -} - -std::string DebounceTest::directionLabel(Direction direction) { - switch (direction) { - case DOWN: - return "DOWN"; - - case UP: - return "UP"; - } -} - -/* Modify a matrix and verify that events always specify a change */ -void DebounceTest::matrixUpdate(matrix_row_t matrix[], const std::string &name, const MatrixTestEvent &event) { - ASSERT_NE(!!(matrix[event.row_] & (1U << event.col_)), directionValue(event.direction_)) << "Test " << name << " at " << strTime() << " sets key " << event.row_ << "," << event.col_ << " " << directionLabel(event.direction_) << " but it is already " << directionLabel(event.direction_) << "\n" << name << "_matrix:\n" << strMatrix(matrix); - - switch (event.direction_) { - case DOWN: - matrix[event.row_] |= (1U << event.col_); - break; - - case UP: - matrix[event.row_] &= ~(1U << event.col_); - break; - } -} - -DebounceTestEvent::DebounceTestEvent(fast_timer_t time, std::initializer_list inputs, std::initializer_list outputs) : time_(time), inputs_(inputs), outputs_(outputs) {} - -MatrixTestEvent::MatrixTestEvent(int row, int col, Direction direction) : row_(row), col_(col), direction_(direction) {} diff --git a/quantum/debounce/tests/debounce_test_common.h b/quantum/debounce/tests/debounce_test_common.h deleted file mode 100644 index b7becb378260..000000000000 --- a/quantum/debounce/tests/debounce_test_common.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include -#include -#include - -extern "C" { -#include "quantum.h" -#include "timer.h" -} - -enum Direction { - DOWN, - UP, -}; - -class MatrixTestEvent { - public: - MatrixTestEvent(int row, int col, Direction direction); - - const int row_; - const int col_; - const Direction direction_; -}; - -class DebounceTestEvent { - public: - // 0, {{0, 1, DOWN}}, {{0, 1, DOWN}}) - DebounceTestEvent(fast_timer_t time, std::initializer_list inputs, std::initializer_list outputs); - - const fast_timer_t time_; - const std::list inputs_; - const std::list outputs_; -}; - -class DebounceTest : public ::testing::Test { - protected: - void addEvents(std::initializer_list events); - void runEvents(); - - fast_timer_t time_offset_ = 7777; - bool time_jumps_ = false; - - private: - static bool directionValue(Direction direction); - static std::string directionLabel(Direction direction); - - void runEventsInternal(); - void runDebounce(bool changed); - void checkCookedMatrix(bool changed, const std::string &error_message); - void matrixUpdate(matrix_row_t matrix[], const std::string &name, const MatrixTestEvent &event); - - std::string strTime(); - std::string strMatrix(matrix_row_t matrix[]); - - std::list events_; - - matrix_row_t input_matrix_[MATRIX_ROWS]; - matrix_row_t raw_matrix_[MATRIX_ROWS]; - matrix_row_t cooked_matrix_[MATRIX_ROWS]; - matrix_row_t output_matrix_[MATRIX_ROWS]; - - int extra_iterations_; - bool auto_advance_time_; -}; diff --git a/quantum/debounce/tests/rules.mk b/quantum/debounce/tests/rules.mk deleted file mode 100644 index 8318b1c6683d..000000000000 --- a/quantum/debounce/tests/rules.mk +++ /dev/null @@ -1,49 +0,0 @@ -# Copyright 2021 Simon Arlott -# -# 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 . - -DEBOUNCE_COMMON_DEFS := -DMATRIX_ROWS=4 -DMATRIX_COLS=10 -DDEBOUNCE=5 - -DEBOUNCE_COMMON_SRC := $(QUANTUM_PATH)/debounce/tests/debounce_test_common.cpp \ - $(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c - -debounce_sym_defer_g_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_sym_defer_g_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/sym_defer_g.c \ - $(QUANTUM_PATH)/debounce/tests/sym_defer_g_tests.cpp - -debounce_sym_defer_pk_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_sym_defer_pk_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/sym_defer_pk.c \ - $(QUANTUM_PATH)/debounce/tests/sym_defer_pk_tests.cpp - -debounce_sym_defer_pr_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_sym_defer_pr_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/sym_defer_pr.c \ - $(QUANTUM_PATH)/debounce/tests/sym_defer_pr_tests.cpp - -debounce_sym_eager_pk_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_sym_eager_pk_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/sym_eager_pk.c \ - $(QUANTUM_PATH)/debounce/tests/sym_eager_pk_tests.cpp - -debounce_sym_eager_pr_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_sym_eager_pr_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/sym_eager_pr.c \ - $(QUANTUM_PATH)/debounce/tests/sym_eager_pr_tests.cpp - -debounce_asym_eager_defer_pk_DEFS := $(DEBOUNCE_COMMON_DEFS) -debounce_asym_eager_defer_pk_SRC := $(DEBOUNCE_COMMON_SRC) \ - $(QUANTUM_PATH)/debounce/asym_eager_defer_pk.c \ - $(QUANTUM_PATH)/debounce/tests/asym_eager_defer_pk_tests.cpp diff --git a/quantum/debounce/tests/sym_defer_g_tests.cpp b/quantum/debounce/tests/sym_defer_g_tests.cpp deleted file mode 100644 index 73d3d45e306d..000000000000 --- a/quantum/debounce/tests/sym_defer_g_tests.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 0ms delay (fast scan rate) */ - {5, {{0, 1, UP}}, {}}, - - {10, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 1ms delay */ - {6, {{0, 1, UP}}, {}}, - - {11, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 2ms delay */ - {7, {{0, 1, UP}}, {}}, - - {12, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - /* Release key exactly on the debounce time */ - {5, {{0, 1, UP}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - - /* Press key exactly on the debounce time */ - {11, {{0, 1, DOWN}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {}}, - {6, {{0, 1, DOWN}}, {}}, - {11, {}, {{0, 1, DOWN}}}, /* 5ms after DOWN at time 7 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - {7, {{0, 1, DOWN}}, {}}, - {8, {{0, 1, UP}}, {}}, - {9, {{0, 1, DOWN}}, {}}, - {10, {{0, 1, UP}}, {}}, - {15, {}, {{0, 1, UP}}}, /* 5ms after UP at time 10 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {}}, - - {30, {}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {}}, - - {55, {}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - - {7, {{0, 1, UP}}, {}}, - {8, {{0, 2, UP}}, {}}, - - {13, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {6, {{0, 1, UP}, {0, 2, UP}}, {}}, - - {11, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {5, {}, {}}, - {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {7, {{0, 1, UP}}, {}}, - {8, {{0, 2, UP}}, {}}, - - {13, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Immediately release key */ - {300, {{0, 1, UP}}, {}}, - - {305, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {301, {{0, 1, UP}}, {}}, - - {306, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Release key before debounce expires */ - {300, {{0, 1, UP}}, {}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is a bit late */ - {50, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {51, {{0, 1, UP}}, {}}, - - {56, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/sym_defer_pk_tests.cpp b/quantum/debounce/tests/sym_defer_pk_tests.cpp deleted file mode 100644 index 7542c2dad424..000000000000 --- a/quantum/debounce/tests/sym_defer_pk_tests.cpp +++ /dev/null @@ -1,240 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 0ms delay (fast scan rate) */ - {5, {{0, 1, UP}}, {}}, - - {10, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 1ms delay */ - {6, {{0, 1, UP}}, {}}, - - {11, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 2ms delay */ - {7, {{0, 1, UP}}, {}}, - - {12, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - /* Release key exactly on the debounce time */ - {5, {{0, 1, UP}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - - /* Press key exactly on the debounce time */ - {11, {{0, 1, DOWN}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {}}, - {6, {{0, 1, DOWN}}, {}}, - {11, {}, {{0, 1, DOWN}}}, /* 5ms after DOWN at time 7 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - {7, {{0, 1, DOWN}}, {}}, - {8, {{0, 1, UP}}, {}}, - {9, {{0, 1, DOWN}}, {}}, - {10, {{0, 1, UP}}, {}}, - {15, {}, {{0, 1, UP}}}, /* 5ms after UP at time 10 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {}}, - - {30, {}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {}}, - - {55, {}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - {6, {}, {{0, 2, DOWN}}}, - - {7, {{0, 1, UP}}, {}}, - {8, {{0, 2, UP}}, {}}, - - {12, {}, {{0, 1, UP}}}, - {13, {}, {{0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {6, {{0, 1, UP}, {0, 2, UP}}, {}}, - - {11, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {{0, 2, DOWN}}}, - {7, {{0, 2, UP}}, {}}, - - {11, {}, {{0, 1, UP}}}, - {12, {}, {{0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Immediately release key */ - {300, {{0, 1, UP}}, {}}, - - {305, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {301, {{0, 1, UP}}, {}}, - - {306, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Release key before debounce expires */ - {300, {{0, 1, UP}}, {}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is a bit late */ - {50, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {51, {{0, 1, UP}}, {}}, - - {56, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/sym_defer_pr_tests.cpp b/quantum/debounce/tests/sym_defer_pr_tests.cpp deleted file mode 100644 index 417e1f4ca24a..000000000000 --- a/quantum/debounce/tests/sym_defer_pr_tests.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 0ms delay (fast scan rate) */ - {5, {{0, 1, UP}}, {}}, - - {10, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 1ms delay */ - {6, {{0, 1, UP}}, {}}, - - {11, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - /* 2ms delay */ - {7, {{0, 1, UP}}, {}}, - - {12, {}, {{0, 1, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - /* Release key exactly on the debounce time */ - {5, {{0, 1, UP}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyTooQuick2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - - /* Press key exactly on the debounce time */ - {11, {{0, 1, DOWN}}, {}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {}}, - {6, {{0, 1, DOWN}}, {}}, - {11, {}, {{0, 1, DOWN}}}, /* 5ms after DOWN at time 7 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {5, {}, {{0, 1, DOWN}}}, - {6, {{0, 1, UP}}, {}}, - {7, {{0, 1, DOWN}}, {}}, - {8, {{0, 1, UP}}, {}}, - {9, {{0, 1, DOWN}}, {}}, - {10, {{0, 1, UP}}, {}}, - {15, {}, {{0, 1, UP}}}, /* 5ms after UP at time 10 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {}}, - - {30, {}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {}}, - - {55, {}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - - {7, {{0, 1, UP}}, {}}, - {8, {{0, 2, UP}}, {}}, - - {13, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {}}, - - {5, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {6, {{0, 1, UP}, {0, 2, UP}}, {}}, - - {11, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - {1, {{0, 2, DOWN}}, {}}, - - {6, {}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {7, {{0, 2, UP}}, {}}, - {9, {{0, 1, UP}}, {}}, - - // Debouncing loses the specific ordering -- both events report simultaneously. - {14, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Immediately release key */ - {300, {{0, 1, UP}}, {}}, - - {305, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is very late */ - {300, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {301, {{0, 1, UP}}, {}}, - - {306, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Release key before debounce expires */ - {300, {{0, 1, UP}}, {}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {}}, - - /* Processing is a bit late */ - {50, {}, {{0, 1, DOWN}}}, - /* Release key after 1ms */ - {51, {{0, 1, UP}}, {}}, - - {56, {}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/sym_eager_pk_tests.cpp b/quantum/debounce/tests/sym_eager_pk_tests.cpp deleted file mode 100644 index d9a02fe33c7f..000000000000 --- a/quantum/debounce/tests/sym_eager_pk_tests.cpp +++ /dev/null @@ -1,253 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 2ms delay (debounce has not yet finished) */ - {7, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 3ms delay (debounce has not yet finished) */ - {8, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 4ms delay (debounce has not yet finished) */ - {9, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 5ms delay (debounce has finished) */ - {10, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key after after 6ms delay (debounce has finished) */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Change twice in the same time period */ - {1, {{0, 1, UP}}, {}}, - {1, {{0, 1, DOWN}}, {}}, - /* Change three times in the same time period */ - {2, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {2, {{0, 1, UP}}, {}}, - /* Change three times in the same time period */ - {3, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {3, {{0, 1, DOWN}}, {}}, - /* Change twice in the same time period */ - {4, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 2, DOWN}}, {{0, 2, DOWN}}}, - {3, {{0, 2, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {7, {}, {{0, 2, UP}}}, - - /* Press key again after 1ms delay (debounce has not yet finished) */ - {9, {{0, 2, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - - {12, {}, {{0, 2, DOWN}}}, /* 5ms after UP at time 7 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted */ - {300, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1 scan delay */ - {300, {}, {}}, - {300, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1ms delay */ - {300, {}, {}}, - {301, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is a bit late but the change will now be accepted */ - {50, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1 scan delay */ - {50, {}, {}}, - {50, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1ms delay */ - {50, {}, {}}, - {51, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/sym_eager_pr_tests.cpp b/quantum/debounce/tests/sym_eager_pr_tests.cpp deleted file mode 100644 index e91dd9cb87c7..000000000000 --- a/quantum/debounce/tests/sym_eager_pr_tests.cpp +++ /dev/null @@ -1,299 +0,0 @@ -/* Copyright 2021 Simon Arlott - * - * 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 . - */ - -#include "gtest/gtest.h" - -#include "debounce_test_common.h" - -TEST_F(DebounceTest, OneKeyShort1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 2ms delay (debounce has not yet finished) */ - {7, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 3ms delay (debounce has not yet finished) */ - {8, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 4ms delay (debounce has not yet finished) */ - {9, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 5ms delay (debounce has finished) */ - {10, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyShort6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key after after 6ms delay (debounce has finished) */ - {11, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyBouncing2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - /* Change twice in the same time period */ - {1, {{0, 1, UP}}, {}}, - {1, {{0, 1, DOWN}}, {}}, - /* Change three times in the same time period */ - {2, {{0, 1, UP}}, {}}, - {2, {{0, 1, DOWN}}, {}}, - {2, {{0, 1, UP}}, {}}, - /* Change three times in the same time period */ - {3, {{0, 1, DOWN}}, {}}, - {3, {{0, 1, UP}}, {}}, - {3, {{0, 1, DOWN}}, {}}, - /* Change twice in the same time period */ - {4, {{0, 1, UP}}, {}}, - {4, {{0, 1, DOWN}}, {}}, - {5, {{0, 1, UP}}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyLong) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - {25, {{0, 1, UP}}, {{0, 1, UP}}}, - - {50, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoRowsShort) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - {2, {{2, 0, DOWN}}, {{2, 0, DOWN}}}, - {3, {{2, 0, UP}}, {}}, - - {5, {}, {{0, 1, UP}}}, - /* Press key again after 1ms delay (debounce has not yet finished) */ - {6, {{0, 1, DOWN}}, {}}, - {7, {}, {{2, 0, UP}}}, - - /* Press key again after 1ms delay (debounce has not yet finished) */ - {9, {{2, 0, DOWN}}, {}}, - {10, {}, {{0, 1, DOWN}}}, /* 5ms after UP at time 5 */ - - {12, {}, {{2, 0, DOWN}}}, /* 5ms after UP at time 7 */ - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysOverlap) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - {1, {{0, 1, UP}}, {}}, - /* Press a second key during the first debounce */ - {2, {{0, 2, DOWN}}, {}}, - - /* Key registers as soon as debounce finishes, 5ms after time 0 */ - {5, {}, {{0, 1, UP}, {0, 2, DOWN}}}, - {6, {{0, 1, DOWN}}, {}}, - - /* Key registers as soon as debounce finishes, 5ms after time 5 */ - {10, {}, {{0, 1, DOWN}}}, - /* Release both keys */ - {11, {{0, 1, UP}}, {}}, - {12, {{0, 2, UP}}, {}}, - - /* Keys register as soon as debounce finishes, 5ms after time 10 */ - {15, {}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {20, {{0, 1, UP}}, {{0, 1, UP}}}, - {21, {{0, 2, UP}}, {}}, - - /* Key registers as soon as debounce finishes, 5ms after time 20 */ - {25, {}, {{0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, TwoKeysSimultaneous2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}, {0, 2, DOWN}}, {{0, 1, DOWN}, {0, 2, DOWN}}}, - {20, {{0, 1, UP}, {0, 2, UP}}, {{0, 1, UP}, {0, 2, UP}}}, - }); - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan1) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted */ - {300, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan2) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1 scan delay */ - {300, {}, {}}, - {300, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan3) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1ms delay */ - {300, {}, {}}, - {301, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan4) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is a bit late but the change will now be accepted */ - {50, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan5) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1 scan delay */ - {50, {}, {}}, - {50, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} - -TEST_F(DebounceTest, OneKeyDelayedScan6) { - addEvents({ - /* Time, Inputs, Outputs */ - {0, {{0, 1, DOWN}}, {{0, 1, DOWN}}}, - - /* Processing is very late but the change will now be accepted even with a 1ms delay */ - {50, {}, {}}, - {51, {{0, 1, UP}}, {{0, 1, UP}}}, - }); - time_jumps_ = true; - runEvents(); -} diff --git a/quantum/debounce/tests/testlist.mk b/quantum/debounce/tests/testlist.mk deleted file mode 100644 index f7bd5206983b..000000000000 --- a/quantum/debounce/tests/testlist.mk +++ /dev/null @@ -1,7 +0,0 @@ -TEST_LIST += \ - debounce_sym_defer_g \ - debounce_sym_defer_pk \ - debounce_sym_defer_pr \ - debounce_sym_eager_pk \ - debounce_sym_eager_pr \ - debounce_asym_eager_defer_pk diff --git a/quantum/deferred_exec.c b/quantum/deferred_exec.c deleted file mode 100644 index a0046a9648d6..000000000000 --- a/quantum/deferred_exec.c +++ /dev/null @@ -1,171 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include -#include - -#ifndef MAX_DEFERRED_EXECUTORS -# define MAX_DEFERRED_EXECUTORS 8 -#endif - -//------------------------------------ -// Helpers -// - -static deferred_token current_token = 0; - -static inline bool token_can_be_used(deferred_executor_t *table, size_t table_count, deferred_token token) { - if (token == INVALID_DEFERRED_TOKEN) { - return false; - } - for (int i = 0; i < table_count; ++i) { - if (table[i].token == token) { - return false; - } - } - return true; -} - -static inline deferred_token allocate_token(deferred_executor_t *table, size_t table_count) { - deferred_token first = ++current_token; - while (!token_can_be_used(table, table_count, current_token)) { - ++current_token; - if (current_token == first) { - // If we've looped back around to the first, everything is already allocated (yikes!). Need to exit with a failure. - return INVALID_DEFERRED_TOKEN; - } - } - return current_token; -} - -//------------------------------------ -// Advanced API: used when a custom-allocated table is used, primarily for core code. -// - -deferred_token defer_exec_advanced(deferred_executor_t *table, size_t table_count, uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg) { - // Ignore queueing if the table isn't valid, it's a zero-time delay, or the token is not valid - if (!table || table_count == 0 || delay_ms == 0 || !callback) { - return INVALID_DEFERRED_TOKEN; - } - - // Find an unused slot and claim it - for (int i = 0; i < table_count; ++i) { - deferred_executor_t *entry = &table[i]; - if (entry->token == INVALID_DEFERRED_TOKEN) { - // Work out the new token value, dropping out if none were available - deferred_token token = allocate_token(table, table_count); - if (token == INVALID_DEFERRED_TOKEN) { - return false; - } - - // Set up the executor table entry - entry->token = current_token; - entry->trigger_time = timer_read32() + delay_ms; - entry->callback = callback; - entry->cb_arg = cb_arg; - return current_token; - } - } - - // None available - return INVALID_DEFERRED_TOKEN; -} - -bool extend_deferred_exec_advanced(deferred_executor_t *table, size_t table_count, deferred_token token, uint32_t delay_ms) { - // Ignore queueing if the table isn't valid, it's a zero-time delay, or the token is not valid - if (!table || table_count == 0 || delay_ms == 0 || token == INVALID_DEFERRED_TOKEN) { - return false; - } - - // Find the entry corresponding to the token - for (int i = 0; i < table_count; ++i) { - deferred_executor_t *entry = &table[i]; - if (entry->token == token) { - // Found it, extend the delay - entry->trigger_time = timer_read32() + delay_ms; - return true; - } - } - - // Not found - return false; -} - -bool cancel_deferred_exec_advanced(deferred_executor_t *table, size_t table_count, deferred_token token) { - // Ignore request if the table/token are not valid - if (!table || table_count == 0 || token == INVALID_DEFERRED_TOKEN) { - return false; - } - - // Find the entry corresponding to the token - for (int i = 0; i < table_count; ++i) { - deferred_executor_t *entry = &table[i]; - if (entry->token == token) { - // Found it, cancel and clear the table entry - entry->token = INVALID_DEFERRED_TOKEN; - entry->trigger_time = 0; - entry->callback = NULL; - entry->cb_arg = NULL; - return true; - } - } - - // Not found - return false; -} - -void deferred_exec_advanced_task(deferred_executor_t *table, size_t table_count, uint32_t *last_execution_time) { - uint32_t now = timer_read32(); - - // Throttle only once per millisecond - if (((int32_t)TIMER_DIFF_32(now, (*last_execution_time))) > 0) { - *last_execution_time = now; - - // Run through each of the executors - for (int i = 0; i < table_count; ++i) { - deferred_executor_t *entry = &table[i]; - - // Check if we're supposed to execute this entry - if (entry->token != INVALID_DEFERRED_TOKEN && ((int32_t)TIMER_DIFF_32(entry->trigger_time, now)) <= 0) { - // Invoke the callback and work work out if we should be requeued - uint32_t delay_ms = entry->callback(entry->trigger_time, entry->cb_arg); - - // Update the trigger time if we have to repeat, otherwise clear it out - if (delay_ms > 0) { - // Intentionally add just the delay to the existing trigger time -- this ensures the next - // invocation is with respect to the previous trigger, rather than when it got to execution. Under - // normal circumstances this won't cause issue, but if another executor is invoked that takes a - // considerable length of time, then this ensures best-effort timing between invocations. - entry->trigger_time += delay_ms; - } else { - // If it was zero, then the callback is cancelling repeated execution. Free up the slot. - entry->token = INVALID_DEFERRED_TOKEN; - entry->trigger_time = 0; - entry->callback = NULL; - entry->cb_arg = NULL; - } - } - } - } -} - -//------------------------------------ -// Basic API: used by user-mode code, guaranteed to not collide with core deferred execution -// - -static uint32_t last_deferred_exec_check = 0; -static deferred_executor_t basic_executors[MAX_DEFERRED_EXECUTORS] = {0}; - -deferred_token defer_exec(uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg) { - return defer_exec_advanced(basic_executors, MAX_DEFERRED_EXECUTORS, delay_ms, callback, cb_arg); -} -bool extend_deferred_exec(deferred_token token, uint32_t delay_ms) { - return extend_deferred_exec_advanced(basic_executors, MAX_DEFERRED_EXECUTORS, token, delay_ms); -} -bool cancel_deferred_exec(deferred_token token) { - return cancel_deferred_exec_advanced(basic_executors, MAX_DEFERRED_EXECUTORS, token); -} -void deferred_exec_task(void) { - deferred_exec_advanced_task(basic_executors, MAX_DEFERRED_EXECUTORS, &last_deferred_exec_check); -} diff --git a/quantum/deferred_exec.h b/quantum/deferred_exec.h deleted file mode 100644 index 97ef0f6c0e2b..000000000000 --- a/quantum/deferred_exec.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include - -//------------------------------------ -// Common -//------------------------------------ - -/** - * @typedef A token that can be used to cancel or extend an existing deferred execution. - */ -typedef uint8_t deferred_token; - -/** - * @def The constant used to denote an invalid deferred execution token. - */ -#define INVALID_DEFERRED_TOKEN 0 - -/** - * @typedef Callback to execute. - * @param trigger_time[in] the intended trigger time to execute the callback -- equivalent time-space as timer_read32() - * @param cb_arg[in] the callback argument specified when enqueueing the deferred executor - * @return non-zero re-queues the callback to execute after the returned number of milliseconds. Zero cancels repeated execution. - */ -typedef uint32_t (*deferred_exec_callback)(uint32_t trigger_time, void *cb_arg); - -//------------------------------------ -// Basic API: used by user-mode code, guaranteed to not collide with core deferred execution -//------------------------------------ - -/** - * Configures the supplied deferred executor to be executed after the required number of milliseconds. - * - * @param delay_ms[in] the number of milliseconds before executing the callback - * @param callback[in] the executor to invoke - * @param cb_arg[in] the argument to pass to the executor, may be NULL if unused by the executor - * @return a token usable for extension/cancellation, or INVALID_DEFERRED_TOKEN if an error occurred - */ -deferred_token defer_exec(uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg); - -/** - * Allows for extending the timeframe before an existing deferred execution is invoked. - * - * @param token[in] the returned value from defer_exec for the deferred execution you wish to extend - * @param delay_ms[in] the number of milliseconds before executing the callback - * @return true if the token was extended successfully, otherwise false - */ -bool extend_deferred_exec(deferred_token token, uint32_t delay_ms); - -/** - * Allows for cancellation of an existing deferred execution. - * - * @param token[in] the returned value from defer_exec for the deferred execution you wish to cancel - * @return true if the token was cancelled successfully, otherwise false - */ -bool cancel_deferred_exec(deferred_token token); - -/** - * Forward declaration for the main loop in order to execute any deferred executors. Should not be invoked by keyboard/user code. - */ -void deferred_exec_task(void); - -//------------------------------------ -// Advanced API: used when a custom-allocated table is used, primarily for core code. -//------------------------------------ - -/** - * @struct Structure for containing self-hosted deferred executor tables. - * @brief Core-side code can use this to create their own tables without impacting on the use of users' ability to add deferred execution. - * Code outside deferred_exec.c should not worry about internals of this struct, and should just allocate the required number in an array. - */ -typedef struct deferred_executor_t { - deferred_token token; - uint32_t trigger_time; - deferred_exec_callback callback; - void * cb_arg; -} deferred_executor_t; - -/** - * Configures the supplied deferred executor to be executed after the required number of milliseconds. - * - * @param table[in] the custom table used for storage - * @param table_count[in] the number of available items in the table - * @param delay_ms[in] the number of milliseconds before executing the callback - * @param callback[in] the executor to invoke - * @param cb_arg[in] the argument to pass to the executor, may be NULL if unused by the executor - * @return a token usable for extension/cancellation, or INVALID_DEFERRED_TOKEN if an error occurred - */ -deferred_token defer_exec_advanced(deferred_executor_t *table, size_t table_count, uint32_t delay_ms, deferred_exec_callback callback, void *cb_arg); - -/** - * Allows for extending the timeframe before an existing deferred execution is invoked. - * - * @param token[in] the returned value from defer_exec for the deferred execution you wish to extend - * @param delay_ms[in] the number of milliseconds before executing the callback - * @return true if the token was extended successfully, otherwise false - */ -bool extend_deferred_exec_advanced(deferred_executor_t *table, size_t table_count, deferred_token token, uint32_t delay_ms); - -/** - * Allows for cancellation of an existing deferred execution. - * - * @param token[in] the returned value from defer_exec for the deferred execution you wish to cancel - * @return true if the token was cancelled successfully, otherwise false - */ -bool cancel_deferred_exec_advanced(deferred_executor_t *table, size_t table_count, deferred_token token); - -/** - * Forward declaration for the main loop in order to execute any custom table deferred executors. Should not be invoked by keyboard/user code. - * Needed for any custom-allocated deferred execution tables. Any core tasks should add appropriate invocation to quantum/main.c. - * - * @param table[in] the custom table used for storage - * @param table_count[in] the number of available items in the table - * @param last_execution_time[in,out] the last execution time -- this will be checked first to determine if execution is needed, and updated if execution occurred - */ -void deferred_exec_advanced_task(deferred_executor_t *table, size_t table_count, uint32_t *last_execution_time); diff --git a/quantum/digitizer.c b/quantum/digitizer.c deleted file mode 100644 index f1b926181ef6..000000000000 --- a/quantum/digitizer.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -#include "digitizer.h" - -digitizer_t digitizer_state = { - .in_range = false, - .tip = false, - .barrel = false, - .x = 0, - .y = 0, - .dirty = false, -}; - -void digitizer_flush(void) { - if (digitizer_state.dirty) { - host_digitizer_send(&digitizer_state); - digitizer_state.dirty = false; - } -} - -void digitizer_in_range_on(void) { - digitizer_state.in_range = true; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_in_range_off(void) { - digitizer_state.in_range = false; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_tip_switch_on(void) { - digitizer_state.tip = true; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_tip_switch_off(void) { - digitizer_state.tip = false; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_barrel_switch_on(void) { - digitizer_state.barrel = true; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_barrel_switch_off(void) { - digitizer_state.barrel = false; - digitizer_state.dirty = true; - digitizer_flush(); -} - -void digitizer_set_position(float x, float y) { - digitizer_state.x = x; - digitizer_state.y = y; - digitizer_state.dirty = true; - digitizer_flush(); -} diff --git a/quantum/digitizer.h b/quantum/digitizer.h deleted file mode 100644 index 6a9c24ed34df..000000000000 --- a/quantum/digitizer.h +++ /dev/null @@ -1,84 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -#pragma once - -#include - -/** - * \file - * - * defgroup digitizer HID Digitizer - * \{ - */ - -typedef struct { - bool in_range : 1; - bool tip : 1; - bool barrel : 1; - float x; - float y; - bool dirty; -} digitizer_t; - -extern digitizer_t digitizer_state; - -/** - * \brief Send the digitizer report to the host if it is marked as dirty. - */ -void digitizer_flush(void); - -/** - * \brief Assert the "in range" indicator, and flush the report. - */ -void digitizer_in_range_on(void); - -/** - * \brief Deassert the "in range" indicator, and flush the report. - */ -void digitizer_in_range_off(void); - -/** - * \brief Assert the tip switch, and flush the report. - */ -void digitizer_tip_switch_on(void); - -/** - * \brief Deassert the tip switch, and flush the report. - */ -void digitizer_tip_switch_off(void); - -/** - * \brief Assert the barrel switch, and flush the report. - */ -void digitizer_barrel_switch_on(void); - -/** - * \brief Deassert the barrel switch, and flush the report. - */ -void digitizer_barrel_switch_off(void); - -/** - * \brief Set the absolute X and Y position of the digitizer contact, and flush the report. - * - * \param x The X value of the contact position, from 0 to 1. - * \param y The Y value of the contact position, from 0 to 1. - */ -void digitizer_set_position(float x, float y); - -void host_digitizer_send(digitizer_t *digitizer); - -/** \} */ diff --git a/quantum/dip_switch.c b/quantum/dip_switch.c deleted file mode 100644 index 6e254578d137..000000000000 --- a/quantum/dip_switch.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright 2018 Jack Humbert - * Copyright 2019 Drashna Jaelre (Christopher Courtney) - * - * 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 . - */ - -#include // for memcpy - -#include "dip_switch.h" -#include "gpio.h" -#include "util.h" - -#ifdef SPLIT_KEYBOARD -# include "split_common/split_util.h" -#endif - -#if !defined(DIP_SWITCH_PINS) && !defined(DIP_SWITCH_MATRIX_GRID) -# error "Either DIP_SWITCH_PINS or DIP_SWITCH_MATRIX_GRID must be defined." -#endif - -#if defined(DIP_SWITCH_PINS) && defined(DIP_SWITCH_MATRIX_GRID) -# error "Both DIP_SWITCH_PINS and DIP_SWITCH_MATRIX_GRID are defined." -#endif - -#ifdef DIP_SWITCH_PINS -# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad)) -static pin_t dip_switch_pad[] = DIP_SWITCH_PINS; -#endif - -#ifdef DIP_SWITCH_MATRIX_GRID -typedef struct matrix_index_t { - uint8_t row; - uint8_t col; -} matrix_index_t; - -# define NUMBER_OF_DIP_SWITCHES (ARRAY_SIZE(dip_switch_pad)) -static matrix_index_t dip_switch_pad[] = DIP_SWITCH_MATRIX_GRID; -extern bool peek_matrix(uint8_t row_index, uint8_t col_index, bool read_raw); -static uint16_t scan_count; -#endif /* DIP_SWITCH_MATRIX_GRID */ - -static bool dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0}; -static bool last_dip_switch_state[NUMBER_OF_DIP_SWITCHES] = {0}; - -__attribute__((weak)) bool dip_switch_update_user(uint8_t index, bool active) { - return true; -} - -__attribute__((weak)) bool dip_switch_update_kb(uint8_t index, bool active) { - return dip_switch_update_user(index, active); -} - -__attribute__((weak)) bool dip_switch_update_mask_user(uint32_t state) { - return true; -} - -__attribute__((weak)) bool dip_switch_update_mask_kb(uint32_t state) { - return dip_switch_update_mask_user(state); -} - -void dip_switch_init(void) { -#ifdef DIP_SWITCH_PINS -# if defined(SPLIT_KEYBOARD) && defined(DIP_SWITCH_PINS_RIGHT) - if (!isLeftHand) { - const pin_t dip_switch_pad_right[] = DIP_SWITCH_PINS_RIGHT; - for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { - dip_switch_pad[i] = dip_switch_pad_right[i]; - } - } -# endif - for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { - setPinInputHigh(dip_switch_pad[i]); - } - dip_switch_read(true); -#endif -#ifdef DIP_SWITCH_MATRIX_GRID - scan_count = 0; -#endif -} - -void dip_switch_read(bool forced) { - bool has_dip_state_changed = false; - uint32_t dip_switch_mask = 0; - -#ifdef DIP_SWITCH_MATRIX_GRID - bool read_raw = false; - - if (scan_count < 500) { - scan_count++; - if (scan_count == 10) { - read_raw = true; - forced = true; /* First reading of the dip switch */ - } else { - return; - } - } -#endif - - for (uint8_t i = 0; i < NUMBER_OF_DIP_SWITCHES; i++) { -#ifdef DIP_SWITCH_PINS - dip_switch_state[i] = !readPin(dip_switch_pad[i]); -#endif -#ifdef DIP_SWITCH_MATRIX_GRID - dip_switch_state[i] = peek_matrix(dip_switch_pad[i].row, dip_switch_pad[i].col, read_raw); -#endif - dip_switch_mask |= dip_switch_state[i] << i; - if (last_dip_switch_state[i] != dip_switch_state[i] || forced) { - has_dip_state_changed = true; - dip_switch_update_kb(i, dip_switch_state[i]); - } - } - if (has_dip_state_changed) { - dip_switch_update_mask_kb(dip_switch_mask); - memcpy(last_dip_switch_state, dip_switch_state, sizeof(dip_switch_state)); - } -} diff --git a/quantum/dip_switch.h b/quantum/dip_switch.h deleted file mode 100644 index 6e79dcb0bf76..000000000000 --- a/quantum/dip_switch.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2018 Jack Humbert - * Copyright 2018 Drashna Jaelre (Christopher Courtney) - * - * 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 . - */ - -#pragma once - -#include -#include - -bool dip_switch_update_kb(uint8_t index, bool active); -bool dip_switch_update_user(uint8_t index, bool active); -bool dip_switch_update_mask_user(uint32_t state); -bool dip_switch_update_mask_kb(uint32_t state); - -void dip_switch_init(void); -void dip_switch_read(bool forced); diff --git a/quantum/dynamic_keymap.c b/quantum/dynamic_keymap.c deleted file mode 100644 index 90a0f2083828..000000000000 --- a/quantum/dynamic_keymap.c +++ /dev/null @@ -1,346 +0,0 @@ -/* Copyright 2017 Jason Williams (Wilba) - * - * 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 . - */ - -#include "keymap_introspection.h" // to get keymaps[][][] -#include "eeprom.h" -#include "progmem.h" // to read default from flash -#include "quantum.h" // for send_string() -#include "dynamic_keymap.h" - -#ifdef VIA_ENABLE -# include "via.h" // for VIA_EEPROM_CONFIG_END -# define DYNAMIC_KEYMAP_EEPROM_START (VIA_EEPROM_CONFIG_END) -#else -# define DYNAMIC_KEYMAP_EEPROM_START (EECONFIG_SIZE) -#endif - -#ifdef ENCODER_ENABLE -# include "encoder.h" -#else -# define NUM_ENCODERS 0 -#endif - -#ifndef DYNAMIC_KEYMAP_LAYER_COUNT -# define DYNAMIC_KEYMAP_LAYER_COUNT 4 -#endif - -#ifndef DYNAMIC_KEYMAP_MACRO_COUNT -# define DYNAMIC_KEYMAP_MACRO_COUNT 16 -#endif - -#ifndef TOTAL_EEPROM_BYTE_COUNT -# error Unknown total EEPROM size. Cannot derive maximum for dynamic keymaps. -#endif - -#ifndef DYNAMIC_KEYMAP_EEPROM_MAX_ADDR -# define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1) -#endif - -#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > (TOTAL_EEPROM_BYTE_COUNT - 1) -# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > " STR((TOTAL_EEPROM_BYTE_COUNT - 1)) -# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR is configured to use more space than what is available for the selected EEPROM driver -#endif - -// Due to usage of uint16_t check for max 65535 -#if DYNAMIC_KEYMAP_EEPROM_MAX_ADDR > 65535 -# pragma message STR(DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) " > 65535" -# error DYNAMIC_KEYMAP_EEPROM_MAX_ADDR must be less than 65536 -#endif - -// If DYNAMIC_KEYMAP_EEPROM_ADDR not explicitly defined in config.h, -#ifndef DYNAMIC_KEYMAP_EEPROM_ADDR -# define DYNAMIC_KEYMAP_EEPROM_ADDR DYNAMIC_KEYMAP_EEPROM_START -#endif - -// Dynamic encoders starts after dynamic keymaps -#ifndef DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR -# define DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2)) -#endif - -// Dynamic macro starts after dynamic encoders, but only when using ENCODER_MAP -#ifdef ENCODER_MAP_ENABLE -# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR -# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * NUM_ENCODERS * 2 * 2)) -# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR -#else // ENCODER_MAP_ENABLE -# ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR -# define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) -# endif // DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR -#endif // ENCODER_MAP_ENABLE - -// Sanity check that dynamic keymaps fit in available EEPROM -// If there's not 100 bytes available for macros, then something is wrong. -// The keyboard should override DYNAMIC_KEYMAP_LAYER_COUNT to reduce it, -// or DYNAMIC_KEYMAP_EEPROM_MAX_ADDR to increase it, *only if* the microcontroller has -// more than the default. -_Static_assert((DYNAMIC_KEYMAP_EEPROM_MAX_ADDR) - (DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR) >= 100, "Dynamic keymaps are configured to use more EEPROM than is available."); - -// Dynamic macros are stored after the keymaps and use what is available -// up to and including DYNAMIC_KEYMAP_EEPROM_MAX_ADDR. -#ifndef DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE -# define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 1) -#endif - -#ifndef DYNAMIC_KEYMAP_MACRO_DELAY -# define DYNAMIC_KEYMAP_MACRO_DELAY TAP_CODE_DELAY -#endif - -uint8_t dynamic_keymap_get_layer_count(void) { - return DYNAMIC_KEYMAP_LAYER_COUNT; -} - -void *dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column) { - // TODO: optimize this with some left shifts - return ((void *)DYNAMIC_KEYMAP_EEPROM_ADDR) + (layer * MATRIX_ROWS * MATRIX_COLS * 2) + (row * MATRIX_COLS * 2) + (column * 2); -} - -uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column) { - if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return KC_NO; - void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); - // Big endian, so we can read/write EEPROM directly from host if we want - uint16_t keycode = eeprom_read_byte(address) << 8; - keycode |= eeprom_read_byte(address + 1); - return keycode; -} - -void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode) { - if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || row >= MATRIX_ROWS || column >= MATRIX_COLS) return; - void *address = dynamic_keymap_key_to_eeprom_address(layer, row, column); - // Big endian, so we can read/write EEPROM directly from host if we want - eeprom_update_byte(address, (uint8_t)(keycode >> 8)); - eeprom_update_byte(address + 1, (uint8_t)(keycode & 0xFF)); -} - -#ifdef ENCODER_MAP_ENABLE -void *dynamic_keymap_encoder_to_eeprom_address(uint8_t layer, uint8_t encoder_id) { - return ((void *)DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) + (layer * NUM_ENCODERS * 2 * 2) + (encoder_id * 2 * 2); -} - -uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise) { - if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return KC_NO; - void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id); - // Big endian, so we can read/write EEPROM directly from host if we want - uint16_t keycode = ((uint16_t)eeprom_read_byte(address + (clockwise ? 0 : 2))) << 8; - keycode |= eeprom_read_byte(address + (clockwise ? 0 : 2) + 1); - return keycode; -} - -void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode) { - if (layer >= DYNAMIC_KEYMAP_LAYER_COUNT || encoder_id >= NUM_ENCODERS) return; - void *address = dynamic_keymap_encoder_to_eeprom_address(layer, encoder_id); - // Big endian, so we can read/write EEPROM directly from host if we want - eeprom_update_byte(address + (clockwise ? 0 : 2), (uint8_t)(keycode >> 8)); - eeprom_update_byte(address + (clockwise ? 0 : 2) + 1, (uint8_t)(keycode & 0xFF)); -} -#endif // ENCODER_MAP_ENABLE - -void dynamic_keymap_reset(void) { - // Reset the keymaps in EEPROM to what is in flash. - for (int layer = 0; layer < DYNAMIC_KEYMAP_LAYER_COUNT; layer++) { - for (int row = 0; row < MATRIX_ROWS; row++) { - for (int column = 0; column < MATRIX_COLS; column++) { - if (layer < keymap_layer_count()) { - dynamic_keymap_set_keycode(layer, row, column, keycode_at_keymap_location_raw(layer, row, column)); - } else { - dynamic_keymap_set_keycode(layer, row, column, KC_TRANSPARENT); - } - } - } -#ifdef ENCODER_MAP_ENABLE - for (int encoder = 0; encoder < NUM_ENCODERS; encoder++) { - if (layer < encodermap_layer_count()) { - dynamic_keymap_set_encoder(layer, encoder, true, keycode_at_encodermap_location_raw(layer, encoder, true)); - dynamic_keymap_set_encoder(layer, encoder, false, keycode_at_encodermap_location_raw(layer, encoder, false)); - } else { - dynamic_keymap_set_encoder(layer, encoder, true, KC_TRANSPARENT); - dynamic_keymap_set_encoder(layer, encoder, false, KC_TRANSPARENT); - } - } -#endif // ENCODER_MAP_ENABLE - } -} - -void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { - uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; - void * source = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset); - uint8_t *target = data; - for (uint16_t i = 0; i < size; i++) { - if (offset + i < dynamic_keymap_eeprom_size) { - *target = eeprom_read_byte(source); - } else { - *target = 0x00; - } - source++; - target++; - } -} - -void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { - uint16_t dynamic_keymap_eeprom_size = DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2; - void * target = (void *)(DYNAMIC_KEYMAP_EEPROM_ADDR + offset); - uint8_t *source = data; - for (uint16_t i = 0; i < size; i++) { - if (offset + i < dynamic_keymap_eeprom_size) { - eeprom_update_byte(target, *source); - } - source++; - target++; - } -} - -uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) { - if (layer_num < DYNAMIC_KEYMAP_LAYER_COUNT && row < MATRIX_ROWS && column < MATRIX_COLS) { - return dynamic_keymap_get_keycode(layer_num, row, column); - } - return KC_NO; -} - -#ifdef ENCODER_MAP_ENABLE -uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { - if (layer_num < DYNAMIC_KEYMAP_LAYER_COUNT && encoder_idx < NUM_ENCODERS) { - return dynamic_keymap_get_encoder(layer_num, encoder_idx, clockwise); - } - return KC_NO; -} -#endif // ENCODER_MAP_ENABLE - -uint8_t dynamic_keymap_macro_get_count(void) { - return DYNAMIC_KEYMAP_MACRO_COUNT; -} - -uint16_t dynamic_keymap_macro_get_buffer_size(void) { - return DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE; -} - -void dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data) { - void * source = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); - uint8_t *target = data; - for (uint16_t i = 0; i < size; i++) { - if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) { - *target = eeprom_read_byte(source); - } else { - *target = 0x00; - } - source++; - target++; - } -} - -void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data) { - void * target = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + offset); - uint8_t *source = data; - for (uint16_t i = 0; i < size; i++) { - if (offset + i < DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) { - eeprom_update_byte(target, *source); - } - source++; - target++; - } -} - -void dynamic_keymap_macro_reset(void) { - void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); - void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); - while (p != end) { - eeprom_update_byte(p, 0); - ++p; - } -} - -void dynamic_keymap_macro_send(uint8_t id) { - if (id >= DYNAMIC_KEYMAP_MACRO_COUNT) { - return; - } - - // Check the last byte of the buffer. - // If it's not zero, then we are in the middle - // of buffer writing, possibly an aborted buffer - // write. So do nothing. - void *p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE - 1); - if (eeprom_read_byte(p) != 0) { - return; - } - - // Skip N null characters - // p will then point to the Nth macro - p = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR); - void *end = (void *)(DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE); - while (id > 0) { - // If we are past the end of the buffer, then there is - // no Nth macro in the buffer. - if (p == end) { - return; - } - if (eeprom_read_byte(p) == 0) { - --id; - } - ++p; - } - - // Send the macro string by making a temporary string. - char data[8] = {0}; - // We already checked there was a null at the end of - // the buffer, so this cannot go past the end - while (1) { - data[0] = eeprom_read_byte(p++); - data[1] = 0; - // Stop at the null terminator of this macro string - if (data[0] == 0) { - break; - } - if (data[0] == SS_QMK_PREFIX) { - // Get the code - data[1] = eeprom_read_byte(p++); - // Unexpected null, abort. - if (data[1] == 0) { - return; - } - if (data[1] == SS_TAP_CODE || data[1] == SS_DOWN_CODE || data[1] == SS_UP_CODE) { - // Get the keycode - data[2] = eeprom_read_byte(p++); - // Unexpected null, abort. - if (data[2] == 0) { - return; - } - // Null terminate - data[3] = 0; - } else if (data[1] == SS_DELAY_CODE) { - // Get the number and '|' - // At most this is 4 digits plus '|' - uint8_t i = 2; - while (1) { - data[i] = eeprom_read_byte(p++); - // Unexpected null, abort - if (data[i] == 0) { - return; - } - // Found '|', send it - if (data[i] == '|') { - data[i + 1] = 0; - break; - } - // If haven't found '|' by i==6 then - // number too big, abort - if (i == 6) { - return; - } - ++i; - } - } - } - send_string_with_delay(data, DYNAMIC_KEYMAP_MACRO_DELAY); - } -} diff --git a/quantum/dynamic_keymap.h b/quantum/dynamic_keymap.h deleted file mode 100644 index 806342efa3ca..000000000000 --- a/quantum/dynamic_keymap.h +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2017 Jason Williams (Wilba) - * - * 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 . - */ -#pragma once - -#include -#include - -uint8_t dynamic_keymap_get_layer_count(void); -void * dynamic_keymap_key_to_eeprom_address(uint8_t layer, uint8_t row, uint8_t column); -uint16_t dynamic_keymap_get_keycode(uint8_t layer, uint8_t row, uint8_t column); -void dynamic_keymap_set_keycode(uint8_t layer, uint8_t row, uint8_t column, uint16_t keycode); -#ifdef ENCODER_MAP_ENABLE -uint16_t dynamic_keymap_get_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise); -void dynamic_keymap_set_encoder(uint8_t layer, uint8_t encoder_id, bool clockwise, uint16_t keycode); -#endif // ENCODER_MAP_ENABLE -void dynamic_keymap_reset(void); -// These get/set the keycodes as stored in the EEPROM buffer -// Data is big-endian 16-bit values (the keycodes) -// Order is by layer/row/column -// Thus offset 0 = 0,0,0, offset MATRIX_COLS*2 = 0,1,0, offset MATRIX_ROWS*MATRIX_COLS*2 = 1,0,0 -// Note the *2, because offset is in bytes and keycodes are two bytes -// This is only really useful for host applications that want to get a whole keymap fast, -// by reading 14 keycodes (28 bytes) at a time, reducing the number of raw HID transfers by -// a factor of 14. -void dynamic_keymap_get_buffer(uint16_t offset, uint16_t size, uint8_t *data); -void dynamic_keymap_set_buffer(uint16_t offset, uint16_t size, uint8_t *data); - -// This overrides the one in quantum/keymap_common.c -// uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); - -// Note regarding dynamic_keymap_macro_set_buffer(): -// The last byte of the buffer is used as a valid flag, -// so macro sending is disabled during writing a new buffer, -// should it happen during, or after an interrupted transfer. -// -// Users writing to the buffer must first set the last byte of the buffer -// to non-zero (i.e. 0xFF). After (or during) the final write, set the -// last byte of the buffer to zero. -// -// Since the contents of the buffer must be a list of null terminated -// strings, the last byte must be a null when at maximum capacity, -// and it not being null means the buffer can be considered in an -// invalid state. -// -// The buffer *may* contain less macro strings than the maximum. -// This allows a higher maximum number of macros without requiring that -// number of nulls to be in the buffer. -// Note: dynamic_keymap_macro_get_count() returns the maximum that *can* be -// stored, not the current count of macros in the buffer. - -uint8_t dynamic_keymap_macro_get_count(void); -uint16_t dynamic_keymap_macro_get_buffer_size(void); -void dynamic_keymap_macro_get_buffer(uint16_t offset, uint16_t size, uint8_t *data); -void dynamic_keymap_macro_set_buffer(uint16_t offset, uint16_t size, uint8_t *data); -void dynamic_keymap_macro_reset(void); - -void dynamic_keymap_macro_send(uint8_t id); diff --git a/quantum/dynamic_macro.h b/quantum/dynamic_macro.h deleted file mode 100644 index 64c532e6ce58..000000000000 --- a/quantum/dynamic_macro.h +++ /dev/null @@ -1,264 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -/* Author: Wojciech Siewierski < wojciech dot siewierski at onet dot pl > */ -#pragma once - -/* Warn users that this is now deprecated and they should use the core feature instead. */ -#pragma message "Dynamic Macros is now a core feature. See updated documentation to see how to configure it: https://docs.qmk.fm/#/feature_dynamic_macros" - -#include "action_layer.h" - -#ifndef DYNAMIC_MACRO_SIZE -/* May be overridden with a custom value. Be aware that the effective - * macro length is half of this value: each keypress is recorded twice - * because of the down-event and up-event. This is not a bug, it's the - * intended behavior. - * - * Usually it should be fine to set the macro size to at least 256 but - * there have been reports of it being too much in some users' cases, - * so 128 is considered a safe default. - */ -# define DYNAMIC_MACRO_SIZE 128 -#endif - -/* Blink the LEDs to notify the user about some event. */ -void dynamic_macro_led_blink(void) { -#ifdef BACKLIGHT_ENABLE - backlight_toggle(); - wait_ms(100); - backlight_toggle(); -#endif -} - -/* Convenience macros used for retrieving the debug info. All of them - * need a `direction` variable accessible at the call site. - */ -#define DYNAMIC_MACRO_CURRENT_SLOT() (direction > 0 ? 1 : 2) -#define DYNAMIC_MACRO_CURRENT_LENGTH(BEGIN, POINTER) ((int)(direction * ((POINTER) - (BEGIN)))) -#define DYNAMIC_MACRO_CURRENT_CAPACITY(BEGIN, END2) ((int)(direction * ((END2) - (BEGIN)) + 1)) - -/** - * Start recording of the dynamic macro. - * - * @param[out] macro_pointer The new macro buffer iterator. - * @param[in] macro_buffer The macro buffer used to initialize macro_pointer. - */ -void dynamic_macro_record_start(keyrecord_t **macro_pointer, keyrecord_t *macro_buffer) { - dprintln("dynamic macro recording: started"); - - dynamic_macro_led_blink(); - - clear_keyboard(); - layer_clear(); - *macro_pointer = macro_buffer; -} - -/** - * Play the dynamic macro. - * - * @param macro_buffer[in] The beginning of the macro buffer being played. - * @param macro_end[in] The element after the last macro buffer element. - * @param direction[in] Either +1 or -1, which way to iterate the buffer. - */ -void dynamic_macro_play(keyrecord_t *macro_buffer, keyrecord_t *macro_end, int8_t direction) { - dprintf("dynamic macro: slot %d playback\n", DYNAMIC_MACRO_CURRENT_SLOT()); - - uint32_t saved_layer_state = layer_state; - - clear_keyboard(); - layer_clear(); - - while (macro_buffer != macro_end) { - process_record(macro_buffer); - macro_buffer += direction; - } - - clear_keyboard(); - - layer_state = saved_layer_state; -} - -/** - * Record a single key in a dynamic macro. - * - * @param macro_buffer[in] The start of the used macro buffer. - * @param macro_pointer[in,out] The current buffer position. - * @param macro2_end[in] The end of the other macro. - * @param direction[in] Either +1 or -1, which way to iterate the buffer. - * @param record[in] The current keypress. - */ -void dynamic_macro_record_key(keyrecord_t *macro_buffer, keyrecord_t **macro_pointer, keyrecord_t *macro2_end, int8_t direction, keyrecord_t *record) { - /* If we've just started recording, ignore all the key releases. */ - if (!record->event.pressed && *macro_pointer == macro_buffer) { - dprintln("dynamic macro: ignoring a leading key-up event"); - return; - } - - /* The other end of the other macro is the last buffer element it - * is safe to use before overwriting the other macro. - */ - if (*macro_pointer - direction != macro2_end) { - **macro_pointer = *record; - *macro_pointer += direction; - } else { - dynamic_macro_led_blink(); - } - - dprintf("dynamic macro: slot %d length: %d/%d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, *macro_pointer), DYNAMIC_MACRO_CURRENT_CAPACITY(macro_buffer, macro2_end)); -} - -/** - * End recording of the dynamic macro. Essentially just update the - * pointer to the end of the macro. - */ -void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_pointer, int8_t direction, keyrecord_t **macro_end) { - dynamic_macro_led_blink(); - - /* Do not save the keys being held when stopping the recording, - * i.e. the keys used to access the layer DM_RSTP is on. - */ - while (macro_pointer != macro_buffer && (macro_pointer - direction)->event.pressed) { - dprintln("dynamic macro: trimming a trailing key-down event"); - macro_pointer -= direction; - } - - dprintf("dynamic macro: slot %d saved, length: %d\n", DYNAMIC_MACRO_CURRENT_SLOT(), DYNAMIC_MACRO_CURRENT_LENGTH(macro_buffer, macro_pointer)); - - *macro_end = macro_pointer; -} - -/* Handle the key events related to the dynamic macros. Should be - * called from process_record_user() like this: - * - * bool process_record_user(uint16_t keycode, keyrecord_t *record) { - * if (!process_record_dynamic_macro(keycode, record)) { - * return false; - * } - * <...THE REST OF THE FUNCTION...> - * } - */ -bool process_record_dynamic_macro(uint16_t keycode, keyrecord_t *record) { - /* Both macros use the same buffer but read/write on different - * ends of it. - * - * Macro1 is written left-to-right starting from the beginning of - * the buffer. - * - * Macro2 is written right-to-left starting from the end of the - * buffer. - * - * ¯o_buffer macro_end - * v v - * +------------------------------------------------------------+ - * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| - * +------------------------------------------------------------+ - * ^ ^ - * r_macro_end r_macro_buffer - * - * During the recording when one macro encounters the end of the - * other macro, the recording is stopped. Apart from this, there - * are no arbitrary limits for the macros' length in relation to - * each other: for example one can either have two medium sized - * macros or one long macro and one short macro. Or even one empty - * and one using the whole buffer. - */ - static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; - - /* Pointer to the first buffer element after the first macro. - * Initially points to the very beginning of the buffer since the - * macro is empty. */ - static keyrecord_t *macro_end = macro_buffer; - - /* The other end of the macro buffer. Serves as the beginning of - * the second macro. */ - static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; - - /* Like macro_end but for the second macro. */ - static keyrecord_t *r_macro_end = r_macro_buffer; - - /* A persistent pointer to the current macro position (iterator) - * used during the recording. */ - static keyrecord_t *macro_pointer = NULL; - - /* 0 - no macro is being recorded right now - * 1,2 - either macro 1 or 2 is being recorded */ - static uint8_t macro_id = 0; - - if (macro_id == 0) { - /* No macro recording in progress. */ - if (!record->event.pressed) { - switch (keycode) { - case QK_DYNAMIC_MACRO_RECORD_START_1: - dynamic_macro_record_start(¯o_pointer, macro_buffer); - macro_id = 1; - return false; - case QK_DYNAMIC_MACRO_RECORD_START_2: - dynamic_macro_record_start(¯o_pointer, r_macro_buffer); - macro_id = 2; - return false; - case QK_DYNAMIC_MACRO_PLAY_1: - dynamic_macro_play(macro_buffer, macro_end, +1); - return false; - case QK_DYNAMIC_MACRO_PLAY_2: - dynamic_macro_play(r_macro_buffer, r_macro_end, -1); - return false; - } - } - } else { - /* A macro is being recorded right now. */ - switch (keycode) { - case QK_DYNAMIC_MACRO_RECORD_STOP: - /* Stop the macro recording. */ - if (record->event.pressed) { /* Ignore the initial release - * just after the recoding - * starts. */ - switch (macro_id) { - case 1: - dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); - break; - case 2: - dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); - break; - } - macro_id = 0; - } - return false; - case QK_DYNAMIC_MACRO_PLAY_1: - case QK_DYNAMIC_MACRO_PLAY_2: - dprintln("dynamic macro: ignoring macro play key while recording"); - return false; - default: - /* Store the key in the macro buffer and process it normally. */ - switch (macro_id) { - case 1: - dynamic_macro_record_key(macro_buffer, ¯o_pointer, r_macro_end, +1, record); - break; - case 2: - dynamic_macro_record_key(r_macro_buffer, ¯o_pointer, macro_end, -1, record); - break; - } - return true; - break; - } - } - - return true; -} - -#undef DYNAMIC_MACRO_CURRENT_SLOT -#undef DYNAMIC_MACRO_CURRENT_LENGTH -#undef DYNAMIC_MACRO_CURRENT_CAPACITY diff --git a/quantum/eeconfig.c b/quantum/eeconfig.c deleted file mode 100644 index 84de025f0e65..000000000000 --- a/quantum/eeconfig.c +++ /dev/null @@ -1,340 +0,0 @@ -#include -#include -#include -#include "eeprom.h" -#include "eeconfig.h" -#include "action_layer.h" - -#if defined(EEPROM_DRIVER) -# include "eeprom_driver.h" -#endif - -#if defined(HAPTIC_ENABLE) -# include "haptic.h" -#endif - -#if defined(VIA_ENABLE) -bool via_eeprom_is_valid(void); -void via_eeprom_set_valid(bool valid); -void eeconfig_init_via(void); -#endif - -/** \brief eeconfig enable - * - * FIXME: needs doc - */ -__attribute__((weak)) void eeconfig_init_user(void) { -#if (EECONFIG_USER_DATA_SIZE) == 0 - // Reset user EEPROM value to blank, rather than to a set value - eeconfig_update_user(0); -#endif -} - -__attribute__((weak)) void eeconfig_init_kb(void) { -#if (EECONFIG_KB_DATA_SIZE) == 0 - // Reset Keyboard EEPROM value to blank, rather than to a set value - eeconfig_update_kb(0); -#endif - - eeconfig_init_user(); -} - -/* - * FIXME: needs doc - */ -void eeconfig_init_quantum(void) { -#if defined(EEPROM_DRIVER) - eeprom_driver_erase(); -#endif - - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); - eeprom_update_byte(EECONFIG_DEBUG, 0); - eeprom_update_byte(EECONFIG_DEFAULT_LAYER, 0); - default_layer_state = 0; - // Enable oneshot and autocorrect by default: 0b0001 0100 0000 0000 - eeprom_update_word(EECONFIG_KEYMAP, 0x1400); - eeprom_update_byte(EECONFIG_BACKLIGHT, 0); - eeprom_update_byte(EECONFIG_AUDIO, 0xFF); // On by default - eeprom_update_dword(EECONFIG_RGBLIGHT, 0); - eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, 0); - eeprom_update_byte(EECONFIG_VELOCIKEY, 0); - eeprom_update_byte(EECONFIG_UNICODEMODE, 0); - eeprom_update_byte(EECONFIG_STENOMODE, 0); - uint64_t dummy = 0; - eeprom_update_block(&dummy, EECONFIG_RGB_MATRIX, sizeof(uint64_t)); - eeprom_update_dword(EECONFIG_HAPTIC, 0); -#if defined(HAPTIC_ENABLE) - haptic_reset(); -#endif - -#if (EECONFIG_KB_DATA_SIZE) > 0 - eeconfig_init_kb_datablock(); -#endif - -#if (EECONFIG_USER_DATA_SIZE) > 0 - eeconfig_init_user_datablock(); -#endif - -#if defined(VIA_ENABLE) - // Invalidate VIA eeprom config, and then reset. - // Just in case if power is lost mid init, this makes sure that it pets - // properly re-initialized. - via_eeprom_set_valid(false); - eeconfig_init_via(); -#endif - - eeconfig_init_kb(); -} - -/** \brief eeconfig initialization - * - * FIXME: needs doc - */ -void eeconfig_init(void) { - eeconfig_init_quantum(); -} - -/** \brief eeconfig enable - * - * FIXME: needs doc - */ -void eeconfig_enable(void) { - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER); -} - -/** \brief eeconfig disable - * - * FIXME: needs doc - */ -void eeconfig_disable(void) { -#if defined(EEPROM_DRIVER) - eeprom_driver_erase(); -#endif - eeprom_update_word(EECONFIG_MAGIC, EECONFIG_MAGIC_NUMBER_OFF); -} - -/** \brief eeconfig is enabled - * - * FIXME: needs doc - */ -bool eeconfig_is_enabled(void) { - bool is_eeprom_enabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER); -#ifdef VIA_ENABLE - if (is_eeprom_enabled) { - is_eeprom_enabled = via_eeprom_is_valid(); - } -#endif - return is_eeprom_enabled; -} - -/** \brief eeconfig is disabled - * - * FIXME: needs doc - */ -bool eeconfig_is_disabled(void) { - bool is_eeprom_disabled = (eeprom_read_word(EECONFIG_MAGIC) == EECONFIG_MAGIC_NUMBER_OFF); -#ifdef VIA_ENABLE - if (!is_eeprom_disabled) { - is_eeprom_disabled = !via_eeprom_is_valid(); - } -#endif - return is_eeprom_disabled; -} - -/** \brief eeconfig read debug - * - * FIXME: needs doc - */ -uint8_t eeconfig_read_debug(void) { - return eeprom_read_byte(EECONFIG_DEBUG); -} -/** \brief eeconfig update debug - * - * FIXME: needs doc - */ -void eeconfig_update_debug(uint8_t val) { - eeprom_update_byte(EECONFIG_DEBUG, val); -} - -/** \brief eeconfig read default layer - * - * FIXME: needs doc - */ -uint8_t eeconfig_read_default_layer(void) { - return eeprom_read_byte(EECONFIG_DEFAULT_LAYER); -} -/** \brief eeconfig update default layer - * - * FIXME: needs doc - */ -void eeconfig_update_default_layer(uint8_t val) { - eeprom_update_byte(EECONFIG_DEFAULT_LAYER, val); -} - -/** \brief eeconfig read keymap - * - * FIXME: needs doc - */ -uint16_t eeconfig_read_keymap(void) { - return eeprom_read_word(EECONFIG_KEYMAP); -} -/** \brief eeconfig update keymap - * - * FIXME: needs doc - */ -void eeconfig_update_keymap(uint16_t val) { - eeprom_update_word(EECONFIG_KEYMAP, val); -} - -/** \brief eeconfig read audio - * - * FIXME: needs doc - */ -uint8_t eeconfig_read_audio(void) { - return eeprom_read_byte(EECONFIG_AUDIO); -} -/** \brief eeconfig update audio - * - * FIXME: needs doc - */ -void eeconfig_update_audio(uint8_t val) { - eeprom_update_byte(EECONFIG_AUDIO, val); -} - -#if (EECONFIG_KB_DATA_SIZE) == 0 -/** \brief eeconfig read kb - * - * FIXME: needs doc - */ -uint32_t eeconfig_read_kb(void) { - return eeprom_read_dword(EECONFIG_KEYBOARD); -} -/** \brief eeconfig update kb - * - * FIXME: needs doc - */ -void eeconfig_update_kb(uint32_t val) { - eeprom_update_dword(EECONFIG_KEYBOARD, val); -} -#endif // (EECONFIG_KB_DATA_SIZE) == 0 - -#if (EECONFIG_USER_DATA_SIZE) == 0 -/** \brief eeconfig read user - * - * FIXME: needs doc - */ -uint32_t eeconfig_read_user(void) { - return eeprom_read_dword(EECONFIG_USER); -} -/** \brief eeconfig update user - * - * FIXME: needs doc - */ -void eeconfig_update_user(uint32_t val) { - eeprom_update_dword(EECONFIG_USER, val); -} -#endif // (EECONFIG_USER_DATA_SIZE) == 0 - -/** \brief eeconfig read haptic - * - * FIXME: needs doc - */ -uint32_t eeconfig_read_haptic(void) { - return eeprom_read_dword(EECONFIG_HAPTIC); -} -/** \brief eeconfig update haptic - * - * FIXME: needs doc - */ -void eeconfig_update_haptic(uint32_t val) { - eeprom_update_dword(EECONFIG_HAPTIC, val); -} - -/** \brief eeconfig read split handedness - * - * FIXME: needs doc - */ -bool eeconfig_read_handedness(void) { - return !!eeprom_read_byte(EECONFIG_HANDEDNESS); -} -/** \brief eeconfig update split handedness - * - * FIXME: needs doc - */ -void eeconfig_update_handedness(bool val) { - eeprom_update_byte(EECONFIG_HANDEDNESS, !!val); -} - -#if (EECONFIG_KB_DATA_SIZE) > 0 -/** \brief eeconfig assert keyboard data block version - * - * FIXME: needs doc - */ -bool eeconfig_is_kb_datablock_valid(void) { - return eeprom_read_dword(EECONFIG_KEYBOARD) == (EECONFIG_KB_DATA_VERSION); -} -/** \brief eeconfig read keyboard data block - * - * FIXME: needs doc - */ -void eeconfig_read_kb_datablock(void *data) { - if (eeconfig_is_kb_datablock_valid()) { - eeprom_read_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE)); - } else { - memset(data, 0, (EECONFIG_KB_DATA_SIZE)); - } -} -/** \brief eeconfig update keyboard data block - * - * FIXME: needs doc - */ -void eeconfig_update_kb_datablock(const void *data) { - eeprom_update_dword(EECONFIG_KEYBOARD, (EECONFIG_KB_DATA_VERSION)); - eeprom_update_block(data, EECONFIG_KB_DATABLOCK, (EECONFIG_KB_DATA_SIZE)); -} -/** \brief eeconfig init keyboard data block - * - * FIXME: needs doc - */ -__attribute__((weak)) void eeconfig_init_kb_datablock(void) { - uint8_t dummy_kb[(EECONFIG_KB_DATA_SIZE)] = {0}; - eeconfig_update_kb_datablock(dummy_kb); -} -#endif // (EECONFIG_KB_DATA_SIZE) > 0 - -#if (EECONFIG_USER_DATA_SIZE) > 0 -/** \brief eeconfig assert user data block version - * - * FIXME: needs doc - */ -bool eeconfig_is_user_datablock_valid(void) { - return eeprom_read_dword(EECONFIG_USER) == (EECONFIG_USER_DATA_VERSION); -} -/** \brief eeconfig read user data block - * - * FIXME: needs doc - */ -void eeconfig_read_user_datablock(void *data) { - if (eeconfig_is_user_datablock_valid()) { - eeprom_read_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE)); - } else { - memset(data, 0, (EECONFIG_USER_DATA_SIZE)); - } -} -/** \brief eeconfig update user data block - * - * FIXME: needs doc - */ -void eeconfig_update_user_datablock(const void *data) { - eeprom_update_dword(EECONFIG_USER, (EECONFIG_USER_DATA_VERSION)); - eeprom_update_block(data, EECONFIG_USER_DATABLOCK, (EECONFIG_USER_DATA_SIZE)); -} -/** \brief eeconfig init user data block - * - * FIXME: needs doc - */ -__attribute__((weak)) void eeconfig_init_user_datablock(void) { - uint8_t dummy_user[(EECONFIG_USER_DATA_SIZE)] = {0}; - eeconfig_update_user_datablock(dummy_user); -} -#endif // (EECONFIG_USER_DATA_SIZE) > 0 diff --git a/quantum/eeconfig.h b/quantum/eeconfig.h deleted file mode 100644 index 85e80226b6ff..000000000000 --- a/quantum/eeconfig.h +++ /dev/null @@ -1,193 +0,0 @@ -/* -Copyright 2013 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include - -#ifndef EECONFIG_MAGIC_NUMBER -# define EECONFIG_MAGIC_NUMBER (uint16_t)0xFEE6 // When changing, decrement this value to avoid future re-init issues -#endif -#define EECONFIG_MAGIC_NUMBER_OFF (uint16_t)0xFFFF - -/* EEPROM parameter address */ -#define EECONFIG_MAGIC (uint16_t *)0 -#define EECONFIG_DEBUG (uint8_t *)2 -#define EECONFIG_DEFAULT_LAYER (uint8_t *)3 -#define EECONFIG_KEYMAP (uint16_t *)4 -#define EECONFIG_BACKLIGHT (uint8_t *)6 -#define EECONFIG_AUDIO (uint8_t *)7 -#define EECONFIG_RGBLIGHT (uint32_t *)8 -#define EECONFIG_UNICODEMODE (uint8_t *)12 -#define EECONFIG_STENOMODE (uint8_t *)13 -// EEHANDS for two handed boards -#define EECONFIG_HANDEDNESS (uint8_t *)14 -#define EECONFIG_KEYBOARD (uint32_t *)15 -#define EECONFIG_USER (uint32_t *)19 -#define EECONFIG_VELOCIKEY (uint8_t *)23 -// Mutually exclusive -#define EECONFIG_LED_MATRIX (uint32_t *)24 -#define EECONFIG_RGB_MATRIX (uint64_t *)24 - -#define EECONFIG_HAPTIC (uint32_t *)32 -#define EECONFIG_RGBLIGHT_EXTENDED (uint8_t *)36 - -// Size of EEPROM being used for core data storage -#define EECONFIG_BASE_SIZE 37 - -// Size of EEPROM dedicated to keyboard- and user-specific data -#ifndef EECONFIG_KB_DATA_SIZE -# define EECONFIG_KB_DATA_SIZE 0 -#endif -#ifndef EECONFIG_KB_DATA_VERSION -# define EECONFIG_KB_DATA_VERSION (EECONFIG_KB_DATA_SIZE) -#endif -#ifndef EECONFIG_USER_DATA_SIZE -# define EECONFIG_USER_DATA_SIZE 0 -#endif -#ifndef EECONFIG_USER_DATA_VERSION -# define EECONFIG_USER_DATA_VERSION (EECONFIG_USER_DATA_SIZE) -#endif - -#define EECONFIG_KB_DATABLOCK ((uint8_t *)(EECONFIG_BASE_SIZE)) -#define EECONFIG_USER_DATABLOCK ((uint8_t *)((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE))) - -// Size of EEPROM being used, other code can refer to this for available EEPROM -#define EECONFIG_SIZE ((EECONFIG_BASE_SIZE) + (EECONFIG_KB_DATA_SIZE) + (EECONFIG_USER_DATA_SIZE)) - -/* debug bit */ -#define EECONFIG_DEBUG_ENABLE (1 << 0) -#define EECONFIG_DEBUG_MATRIX (1 << 1) -#define EECONFIG_DEBUG_KEYBOARD (1 << 2) -#define EECONFIG_DEBUG_MOUSE (1 << 3) - -/* keyconf bit */ -#define EECONFIG_KEYMAP_SWAP_CONTROL_CAPSLOCK (1 << 0) -#define EECONFIG_KEYMAP_CAPSLOCK_TO_CONTROL (1 << 1) -#define EECONFIG_KEYMAP_SWAP_LALT_LGUI (1 << 2) -#define EECONFIG_KEYMAP_SWAP_RALT_RGUI (1 << 3) -#define EECONFIG_KEYMAP_NO_GUI (1 << 4) -#define EECONFIG_KEYMAP_SWAP_GRAVE_ESC (1 << 5) -#define EECONFIG_KEYMAP_SWAP_BACKSLASH_BACKSPACE (1 << 6) -#define EECONFIG_KEYMAP_NKRO (1 << 7) - -bool eeconfig_is_enabled(void); -bool eeconfig_is_disabled(void); - -void eeconfig_init(void); -void eeconfig_init_quantum(void); -void eeconfig_init_kb(void); -void eeconfig_init_user(void); - -void eeconfig_enable(void); - -void eeconfig_disable(void); - -uint8_t eeconfig_read_debug(void); -void eeconfig_update_debug(uint8_t val); - -uint8_t eeconfig_read_default_layer(void); -void eeconfig_update_default_layer(uint8_t val); - -uint16_t eeconfig_read_keymap(void); -void eeconfig_update_keymap(uint16_t val); - -#ifdef AUDIO_ENABLE -uint8_t eeconfig_read_audio(void); -void eeconfig_update_audio(uint8_t val); -#endif - -#if (EECONFIG_KB_DATA_SIZE) == 0 -uint32_t eeconfig_read_kb(void); -void eeconfig_update_kb(uint32_t val); -#endif // (EECONFIG_KB_DATA_SIZE) == 0 - -#if (EECONFIG_USER_DATA_SIZE) == 0 -uint32_t eeconfig_read_user(void); -void eeconfig_update_user(uint32_t val); -#endif // (EECONFIG_USER_DATA_SIZE) == 0 - -#ifdef HAPTIC_ENABLE -uint32_t eeconfig_read_haptic(void); -void eeconfig_update_haptic(uint32_t val); -#endif - -bool eeconfig_read_handedness(void); -void eeconfig_update_handedness(bool val); - -#if (EECONFIG_KB_DATA_SIZE) > 0 -bool eeconfig_is_kb_datablock_valid(void); -void eeconfig_read_kb_datablock(void *data); -void eeconfig_update_kb_datablock(const void *data); -void eeconfig_init_kb_datablock(void); -#endif // (EECONFIG_KB_DATA_SIZE) > 0 - -#if (EECONFIG_USER_DATA_SIZE) > 0 -bool eeconfig_is_user_datablock_valid(void); -void eeconfig_read_user_datablock(void *data); -void eeconfig_update_user_datablock(const void *data); -void eeconfig_init_user_datablock(void); -#endif // (EECONFIG_USER_DATA_SIZE) > 0 - -// Any "checked" debounce variant used requires implementation of: -// -- bool eeconfig_check_valid_##name(void) -// -- void eeconfig_post_flush_##name(void) -#define EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \ - static uint8_t dirty_##name = false; \ - \ - bool eeconfig_check_valid_##name(void); \ - void eeconfig_post_flush_##name(void); \ - \ - static inline void eeconfig_init_##name(void) { \ - dirty_##name = true; \ - if (eeconfig_check_valid_##name()) { \ - eeprom_read_block(&config, offset, sizeof(config)); \ - dirty_##name = false; \ - } \ - } \ - static inline void eeconfig_flush_##name(bool force) { \ - if (force || dirty_##name) { \ - eeprom_update_block(&config, offset, sizeof(config)); \ - eeconfig_post_flush_##name(); \ - dirty_##name = false; \ - } \ - } \ - static inline void eeconfig_flush_##name##_task(uint16_t timeout) { \ - static uint16_t flush_timer = 0; \ - if (timer_elapsed(flush_timer) > timeout) { \ - eeconfig_flush_##name(false); \ - flush_timer = timer_read(); \ - } \ - } \ - static inline void eeconfig_flag_##name(bool v) { \ - dirty_##name |= v; \ - } \ - static inline void eeconfig_write_##name(typeof(config) *conf) { \ - if (memcmp(&config, conf, sizeof(config)) != 0) { \ - memcpy(&config, conf, sizeof(config)); \ - eeconfig_flag_##name(true); \ - } \ - } - -#define EECONFIG_DEBOUNCE_HELPER(name, offset, config) \ - EECONFIG_DEBOUNCE_HELPER_CHECKED(name, offset, config) \ - \ - bool eeconfig_check_valid_##name(void) { \ - return true; \ - } \ - void eeconfig_post_flush_##name(void) {} diff --git a/quantum/encoder.c b/quantum/encoder.c deleted file mode 100644 index 1046fe6cc3d2..000000000000 --- a/quantum/encoder.c +++ /dev/null @@ -1,292 +0,0 @@ -/* - * Copyright 2018 Jack Humbert - * - * 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 . - */ - -#include "encoder.h" -#ifdef SPLIT_KEYBOARD -# include "split_util.h" -#endif - -// for memcpy -#include - -#ifndef ENCODER_MAP_KEY_DELAY -# include "action.h" -# define ENCODER_MAP_KEY_DELAY TAP_CODE_DELAY -#endif - -#if !defined(ENCODER_RESOLUTIONS) && !defined(ENCODER_RESOLUTION) -# define ENCODER_RESOLUTION 4 -#endif - -#if !defined(ENCODERS_PAD_A) || !defined(ENCODERS_PAD_B) -# error "No encoder pads defined by ENCODERS_PAD_A and ENCODERS_PAD_B" -#endif - -extern volatile bool isLeftHand; - -static pin_t encoders_pad_a[NUM_ENCODERS_MAX_PER_SIDE] = ENCODERS_PAD_A; -static pin_t encoders_pad_b[NUM_ENCODERS_MAX_PER_SIDE] = ENCODERS_PAD_B; - -#ifdef ENCODER_RESOLUTIONS -static uint8_t encoder_resolutions[NUM_ENCODERS] = ENCODER_RESOLUTIONS; -#endif - -#ifndef ENCODER_DIRECTION_FLIP -# define ENCODER_CLOCKWISE true -# define ENCODER_COUNTER_CLOCKWISE false -#else -# define ENCODER_CLOCKWISE false -# define ENCODER_COUNTER_CLOCKWISE true -#endif -static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0}; - -static uint8_t encoder_state[NUM_ENCODERS] = {0}; -static int8_t encoder_pulses[NUM_ENCODERS] = {0}; - -// encoder counts -static uint8_t thisCount; -#ifdef SPLIT_KEYBOARD -// encoder offsets for each hand -static uint8_t thisHand, thatHand; -// encoder counts for each hand -static uint8_t thatCount; -#endif - -static uint8_t encoder_value[NUM_ENCODERS] = {0}; - -__attribute__((weak)) void encoder_wait_pullup_charge(void) { - wait_us(100); -} - -__attribute__((weak)) bool encoder_update_user(uint8_t index, bool clockwise) { - return true; -} - -__attribute__((weak)) bool encoder_update_kb(uint8_t index, bool clockwise) { - bool res = encoder_update_user(index, clockwise); -#if !defined(ENCODER_TESTS) - if (res) { - if (clockwise) { -# if defined(EXTRAKEY_ENABLE) - tap_code_delay(KC_VOLU, 10); -# elif defined(MOUSEKEY_ENABLE) - tap_code_delay(KC_MS_WH_UP, 10); -# else - tap_code_delay(KC_PGDN, 10); -# endif - } else { -# if defined(EXTRAKEY_ENABLE) - tap_code_delay(KC_VOLD, 10); -# elif defined(MOUSEKEY_ENABLE) - tap_code_delay(KC_MS_WH_DOWN, 10); -# else - tap_code_delay(KC_PGUP, 10); -# endif - } - } -#endif // ENCODER_TESTS - return res; -} - -__attribute__((weak)) bool should_process_encoder(void) { - return is_keyboard_master(); -} - -void encoder_init(void) { -#ifdef SPLIT_KEYBOARD - thisHand = isLeftHand ? 0 : NUM_ENCODERS_LEFT; - thatHand = NUM_ENCODERS_LEFT - thisHand; - thisCount = isLeftHand ? NUM_ENCODERS_LEFT : NUM_ENCODERS_RIGHT; - thatCount = isLeftHand ? NUM_ENCODERS_RIGHT : NUM_ENCODERS_LEFT; -#else // SPLIT_KEYBOARD - thisCount = NUM_ENCODERS; -#endif - -#ifdef ENCODER_TESTS - // Annoying that we have to clear out values during initialisation here, but - // because all the arrays are static locals, rerunning tests in the same - // executable doesn't reset any of these. Kinda crappy having test-only code - // here, but it's the simplest solution. - memset(encoder_value, 0, sizeof(encoder_value)); - memset(encoder_state, 0, sizeof(encoder_state)); - memset(encoder_pulses, 0, sizeof(encoder_pulses)); - static const pin_t encoders_pad_a_left[] = ENCODERS_PAD_A; - static const pin_t encoders_pad_b_left[] = ENCODERS_PAD_B; - for (uint8_t i = 0; i < thisCount; i++) { - encoders_pad_a[i] = encoders_pad_a_left[i]; - encoders_pad_b[i] = encoders_pad_b_left[i]; - } -#endif - -#if defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) - // Re-initialise the pads if it's the right-hand side - if (!isLeftHand) { - static const pin_t encoders_pad_a_right[] = ENCODERS_PAD_A_RIGHT; - static const pin_t encoders_pad_b_right[] = ENCODERS_PAD_B_RIGHT; - for (uint8_t i = 0; i < thisCount; i++) { - encoders_pad_a[i] = encoders_pad_a_right[i]; - encoders_pad_b[i] = encoders_pad_b_right[i]; - } - } -#endif // defined(SPLIT_KEYBOARD) && defined(ENCODERS_PAD_A_RIGHT) && defined(ENCODERS_PAD_B_RIGHT) - - // Encoder resolutions is handled purely master-side, so concatenate the two arrays -#if defined(SPLIT_KEYBOARD) && defined(ENCODER_RESOLUTIONS) -# if defined(ENCODER_RESOLUTIONS_RIGHT) - static const uint8_t encoder_resolutions_right[NUM_ENCODERS_RIGHT] = ENCODER_RESOLUTIONS_RIGHT; -# else // defined(ENCODER_RESOLUTIONS_RIGHT) - static const uint8_t encoder_resolutions_right[NUM_ENCODERS_RIGHT] = ENCODER_RESOLUTIONS; -# endif // defined(ENCODER_RESOLUTIONS_RIGHT) - for (uint8_t i = 0; i < NUM_ENCODERS_RIGHT; i++) { - encoder_resolutions[NUM_ENCODERS_LEFT + i] = encoder_resolutions_right[i]; - } -#endif // defined(SPLIT_KEYBOARD) && defined(ENCODER_RESOLUTIONS) - - for (uint8_t i = 0; i < thisCount; i++) { - setPinInputHigh(encoders_pad_a[i]); - setPinInputHigh(encoders_pad_b[i]); - } - encoder_wait_pullup_charge(); - for (uint8_t i = 0; i < thisCount; i++) { - encoder_state[i] = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); - } -} - -#ifdef ENCODER_MAP_ENABLE -static void encoder_exec_mapping(uint8_t index, bool clockwise) { - // The delays below cater for Windows and its wonderful requirements. - action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, true) : MAKE_ENCODER_CCW_EVENT(index, true)); -# if ENCODER_MAP_KEY_DELAY > 0 - wait_ms(ENCODER_MAP_KEY_DELAY); -# endif // ENCODER_MAP_KEY_DELAY > 0 - - action_exec(clockwise ? MAKE_ENCODER_CW_EVENT(index, false) : MAKE_ENCODER_CCW_EVENT(index, false)); -# if ENCODER_MAP_KEY_DELAY > 0 - wait_ms(ENCODER_MAP_KEY_DELAY); -# endif // ENCODER_MAP_KEY_DELAY > 0 -} -#endif // ENCODER_MAP_ENABLE - -static bool encoder_update(uint8_t index, uint8_t state) { - bool changed = false; - uint8_t i = index; - -#ifdef ENCODER_RESOLUTIONS - const uint8_t resolution = encoder_resolutions[i]; -#else - const uint8_t resolution = ENCODER_RESOLUTION; -#endif - -#ifdef SPLIT_KEYBOARD - index += thisHand; -#endif - encoder_pulses[i] += encoder_LUT[state & 0xF]; - -#ifdef ENCODER_DEFAULT_POS - if ((encoder_pulses[i] >= resolution) || (encoder_pulses[i] <= -resolution) || ((state & 0x3) == ENCODER_DEFAULT_POS)) { - if (encoder_pulses[i] >= 1) { -#else - if (encoder_pulses[i] >= resolution) { -#endif - - encoder_value[index]++; - changed = true; -#ifdef SPLIT_KEYBOARD - if (should_process_encoder()) -#endif // SPLIT_KEYBOARD -#ifdef ENCODER_MAP_ENABLE - encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE); -#else // ENCODER_MAP_ENABLE - encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); -#endif // ENCODER_MAP_ENABLE - } - -#ifdef ENCODER_DEFAULT_POS - if (encoder_pulses[i] <= -1) { -#else - if (encoder_pulses[i] <= -resolution) { // direction is arbitrary here, but this clockwise -#endif - encoder_value[index]--; - changed = true; -#ifdef SPLIT_KEYBOARD - if (should_process_encoder()) -#endif // SPLIT_KEYBOARD -#ifdef ENCODER_MAP_ENABLE - encoder_exec_mapping(index, ENCODER_CLOCKWISE); -#else // ENCODER_MAP_ENABLE - encoder_update_kb(index, ENCODER_CLOCKWISE); -#endif // ENCODER_MAP_ENABLE - } - encoder_pulses[i] %= resolution; -#ifdef ENCODER_DEFAULT_POS - encoder_pulses[i] = 0; - } -#endif - return changed; -} - -bool encoder_read(void) { - bool changed = false; - for (uint8_t i = 0; i < thisCount; i++) { - uint8_t new_status = (readPin(encoders_pad_a[i]) << 0) | (readPin(encoders_pad_b[i]) << 1); - if ((encoder_state[i] & 0x3) != new_status) { - encoder_state[i] <<= 2; - encoder_state[i] |= new_status; - changed |= encoder_update(i, encoder_state[i]); - } - } - return changed; -} - -#ifdef SPLIT_KEYBOARD -void last_encoder_activity_trigger(void); - -void encoder_state_raw(uint8_t *slave_state) { - memcpy(slave_state, &encoder_value[thisHand], sizeof(uint8_t) * thisCount); -} - -void encoder_update_raw(uint8_t *slave_state) { - bool changed = false; - for (uint8_t i = 0; i < thatCount; i++) { // Note inverted logic -- we want the opposite side - const uint8_t index = i + thatHand; - int8_t delta = slave_state[i] - encoder_value[index]; - while (delta > 0) { - delta--; - encoder_value[index]++; - changed = true; -# ifdef ENCODER_MAP_ENABLE - encoder_exec_mapping(index, ENCODER_COUNTER_CLOCKWISE); -# else // ENCODER_MAP_ENABLE - encoder_update_kb(index, ENCODER_COUNTER_CLOCKWISE); -# endif // ENCODER_MAP_ENABLE - } - while (delta < 0) { - delta++; - encoder_value[index]--; - changed = true; -# ifdef ENCODER_MAP_ENABLE - encoder_exec_mapping(index, ENCODER_CLOCKWISE); -# else // ENCODER_MAP_ENABLE - encoder_update_kb(index, ENCODER_CLOCKWISE); -# endif // ENCODER_MAP_ENABLE - } - } - - // Update the last encoder input time -- handled external to encoder_read() when we're running a split - if (changed) last_encoder_activity_trigger(); -} -#endif diff --git a/quantum/encoder.h b/quantum/encoder.h deleted file mode 100644 index 7644853b30a3..000000000000 --- a/quantum/encoder.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2018 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "quantum.h" -#include "util.h" - -void encoder_init(void); -bool encoder_read(void); - -bool encoder_update_kb(uint8_t index, bool clockwise); -bool encoder_update_user(uint8_t index, bool clockwise); - -#ifdef SPLIT_KEYBOARD - -void encoder_state_raw(uint8_t* slave_state); -void encoder_update_raw(uint8_t* slave_state); - -# if defined(ENCODERS_PAD_A_RIGHT) -# define NUM_ENCODERS_LEFT ARRAY_SIZE(((pin_t[])ENCODERS_PAD_A)) -# define NUM_ENCODERS_RIGHT ARRAY_SIZE(((pin_t[])ENCODERS_PAD_A_RIGHT)) -# else -# define NUM_ENCODERS_LEFT ARRAY_SIZE(((pin_t[])ENCODERS_PAD_A)) -# define NUM_ENCODERS_RIGHT NUM_ENCODERS_LEFT -# endif -# define NUM_ENCODERS (NUM_ENCODERS_LEFT + NUM_ENCODERS_RIGHT) - -#else // SPLIT_KEYBOARD - -# define NUM_ENCODERS ARRAY_SIZE(((pin_t[])ENCODERS_PAD_A)) -# define NUM_ENCODERS_LEFT NUM_ENCODERS -# define NUM_ENCODERS_RIGHT 0 - -#endif // SPLIT_KEYBOARD - -#ifndef NUM_ENCODERS -# define NUM_ENCODERS 0 -# define NUM_ENCODERS_LEFT 0 -# define NUM_ENCODERS_RIGHT 0 -#endif // NUM_ENCODERS - -#define NUM_ENCODERS_MAX_PER_SIDE MAX(NUM_ENCODERS_LEFT, NUM_ENCODERS_RIGHT) - -#ifdef ENCODER_MAP_ENABLE -# define NUM_DIRECTIONS 2 -# define ENCODER_CCW_CW(ccw, cw) \ - { (cw), (ccw) } -extern const uint16_t encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS]; -#endif // ENCODER_MAP_ENABLE diff --git a/quantum/encoder/tests/config_mock.h b/quantum/encoder/tests/config_mock.h deleted file mode 100644 index 703dcaf10361..000000000000 --- a/quantum/encoder/tests/config_mock.h +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0 } -#define ENCODERS_PAD_B \ - { 1 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_left_eq_right.h b/quantum/encoder/tests/config_mock_split_left_eq_right.h deleted file mode 100644 index c80ac4d51988..000000000000 --- a/quantum/encoder/tests/config_mock_split_left_eq_right.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0, 2 } -#define ENCODERS_PAD_B \ - { 1, 3 } -#define ENCODERS_PAD_A_RIGHT \ - { 4, 6 } -#define ENCODERS_PAD_B_RIGHT \ - { 5, 7 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_left_gt_right.h b/quantum/encoder/tests/config_mock_split_left_gt_right.h deleted file mode 100644 index 91d5f3d6058c..000000000000 --- a/quantum/encoder/tests/config_mock_split_left_gt_right.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0, 2, 4 } -#define ENCODERS_PAD_B \ - { 1, 3, 5 } -#define ENCODERS_PAD_A_RIGHT \ - { 6, 8 } -#define ENCODERS_PAD_B_RIGHT \ - { 7, 9 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_left_lt_right.h b/quantum/encoder/tests/config_mock_split_left_lt_right.h deleted file mode 100644 index 4108a184a68c..000000000000 --- a/quantum/encoder/tests/config_mock_split_left_lt_right.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0, 2 } -#define ENCODERS_PAD_B \ - { 1, 3 } -#define ENCODERS_PAD_A_RIGHT \ - { 4, 6, 8 } -#define ENCODERS_PAD_B_RIGHT \ - { 5, 7, 9 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_no_left.h b/quantum/encoder/tests/config_mock_split_no_left.h deleted file mode 100644 index 9db7fa7e41b1..000000000000 --- a/quantum/encoder/tests/config_mock_split_no_left.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - {} -#define ENCODERS_PAD_B \ - {} -#define ENCODERS_PAD_A_RIGHT \ - { 0, 2 } -#define ENCODERS_PAD_B_RIGHT \ - { 1, 3 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_no_right.h b/quantum/encoder/tests/config_mock_split_no_right.h deleted file mode 100644 index 14f18015e661..000000000000 --- a/quantum/encoder/tests/config_mock_split_no_right.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0, 2 } -#define ENCODERS_PAD_B \ - { 1, 3 } -#define ENCODERS_PAD_A_RIGHT \ - {} -#define ENCODERS_PAD_B_RIGHT \ - {} - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/config_mock_split_role.h b/quantum/encoder/tests/config_mock_split_role.h deleted file mode 100644 index c80ac4d51988..000000000000 --- a/quantum/encoder/tests/config_mock_split_role.h +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#define MATRIX_ROWS 1 -#define MATRIX_COLS 1 - -/* Here, "pins" from 0 to 31 are allowed. */ -#define ENCODERS_PAD_A \ - { 0, 2 } -#define ENCODERS_PAD_B \ - { 1, 3 } -#define ENCODERS_PAD_A_RIGHT \ - { 4, 6 } -#define ENCODERS_PAD_B_RIGHT \ - { 5, 7 } - -#ifdef __cplusplus -extern "C" { -#endif - -#include "mock_split.h" - -#ifdef __cplusplus -}; -#endif diff --git a/quantum/encoder/tests/encoder_tests.cpp b/quantum/encoder/tests/encoder_tests.cpp deleted file mode 100644 index b7c18aeec008..000000000000 --- a/quantum/encoder/tests/encoder_tests.cpp +++ /dev/null @@ -1,144 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderTest : public ::testing::Test {}; - -TEST_F(EncoderTest, TestInit) { - updates_array_idx = 0; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(updates_array_idx, 0); -} - -TEST_F(EncoderTest, TestOneClockwise) { - updates_array_idx = 0; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 1); - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderTest, TestOneCounterClockwise) { - updates_array_idx = 0; - encoder_init(); - setAndRead(1, false); - setAndRead(0, false); - setAndRead(1, true); - setAndRead(0, true); - - EXPECT_EQ(updates_array_idx, 1); - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, false); -} - -TEST_F(EncoderTest, TestTwoClockwiseOneCC) { - updates_array_idx = 0; - encoder_init(); - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - setAndRead(1, false); - setAndRead(0, false); - setAndRead(1, true); - setAndRead(0, true); - - EXPECT_EQ(updates_array_idx, 3); - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); - EXPECT_EQ(updates[1].index, 0); - EXPECT_EQ(updates[1].clockwise, true); - EXPECT_EQ(updates[2].index, 0); - EXPECT_EQ(updates[2].clockwise, false); -} - -TEST_F(EncoderTest, TestNoEarly) { - updates_array_idx = 0; - encoder_init(); - // send 3 pulses. with resolution 4, that's not enough for a step. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - EXPECT_EQ(updates_array_idx, 0); - // now send last pulse - setAndRead(1, true); - EXPECT_EQ(updates_array_idx, 1); - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderTest, TestHalfway) { - updates_array_idx = 0; - encoder_init(); - // go halfway - setAndRead(0, false); - setAndRead(1, false); - EXPECT_EQ(updates_array_idx, 0); - // back off - setAndRead(1, true); - setAndRead(0, true); - EXPECT_EQ(updates_array_idx, 0); - // go all the way - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - // should result in 1 update - EXPECT_EQ(updates_array_idx, 1); - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} diff --git a/quantum/encoder/tests/encoder_tests_split_left_eq_right.cpp b/quantum/encoder/tests/encoder_tests_split_left_eq_right.cpp deleted file mode 100644 index 916e47b18517..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_left_eq_right.cpp +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool isLeftHand; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isLeftHand) { - // this method has no effect on slave half - printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return true; - } - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestLeftEqRight : public ::testing::Test { - protected: - void SetUp() override { - updates_array_idx = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestLeftEqRight, TestInitLeft) { - isLeftHand = true; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(pinIsInputHigh[2], true); - EXPECT_EQ(pinIsInputHigh[3], true); - EXPECT_EQ(pinIsInputHigh[4], false); - EXPECT_EQ(pinIsInputHigh[5], false); - EXPECT_EQ(pinIsInputHigh[6], false); - EXPECT_EQ(pinIsInputHigh[7], false); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftEqRight, TestInitRight) { - isLeftHand = false; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], false); - EXPECT_EQ(pinIsInputHigh[1], false); - EXPECT_EQ(pinIsInputHigh[2], false); - EXPECT_EQ(pinIsInputHigh[3], false); - EXPECT_EQ(pinIsInputHigh[4], true); - EXPECT_EQ(pinIsInputHigh[5], true); - EXPECT_EQ(pinIsInputHigh[6], true); - EXPECT_EQ(pinIsInputHigh[7], true); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftEqRight, TestOneClockwiseLeft) { - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 1); // one update received - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderSplitTestLeftEqRight, TestOneClockwiseRightSent) { - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(6, false); - setAndRead(7, false); - setAndRead(6, true); - setAndRead(7, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(slave_state[0], 0); - EXPECT_EQ(slave_state[1], 0xFF); -} - -TEST_F(EncoderSplitTestLeftEqRight, TestMultipleEncodersRightReceived) { - isLeftHand = true; - encoder_init(); - - uint8_t slave_state[32] = {1, 0xFF}; // First right encoder is CCW, Second right encoder CW - encoder_update_raw(slave_state); - - EXPECT_EQ(updates_array_idx, 2); // two updates received, one for each changed item on the right side - EXPECT_EQ(updates[0].index, 2); - EXPECT_EQ(updates[0].clockwise, false); - EXPECT_EQ(updates[1].index, 3); - EXPECT_EQ(updates[1].clockwise, true); -} diff --git a/quantum/encoder/tests/encoder_tests_split_left_gt_right.cpp b/quantum/encoder/tests/encoder_tests_split_left_gt_right.cpp deleted file mode 100644 index 7b64bb298136..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_left_gt_right.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool isLeftHand; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isLeftHand) { - // this method has no effect on slave half - printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return true; - } - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestLeftGreaterThanRight : public ::testing::Test { - protected: - void SetUp() override { - updates_array_idx = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestLeftGreaterThanRight, TestInitLeft) { - isLeftHand = true; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(pinIsInputHigh[2], true); - EXPECT_EQ(pinIsInputHigh[3], true); - EXPECT_EQ(pinIsInputHigh[4], true); - EXPECT_EQ(pinIsInputHigh[5], true); - EXPECT_EQ(pinIsInputHigh[6], false); - EXPECT_EQ(pinIsInputHigh[7], false); - EXPECT_EQ(pinIsInputHigh[8], false); - EXPECT_EQ(pinIsInputHigh[9], false); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftGreaterThanRight, TestInitRight) { - isLeftHand = false; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], false); - EXPECT_EQ(pinIsInputHigh[1], false); - EXPECT_EQ(pinIsInputHigh[2], false); - EXPECT_EQ(pinIsInputHigh[3], false); - EXPECT_EQ(pinIsInputHigh[4], false); - EXPECT_EQ(pinIsInputHigh[5], false); - EXPECT_EQ(pinIsInputHigh[6], true); - EXPECT_EQ(pinIsInputHigh[7], true); - EXPECT_EQ(pinIsInputHigh[8], true); - EXPECT_EQ(pinIsInputHigh[9], true); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftGreaterThanRight, TestOneClockwiseLeft) { - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 1); // one update received - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderSplitTestLeftGreaterThanRight, TestOneClockwiseRightSent) { - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(6, false); - setAndRead(7, false); - setAndRead(6, true); - setAndRead(7, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(slave_state[0], 0xFF); - EXPECT_EQ(slave_state[1], 0); -} - -TEST_F(EncoderSplitTestLeftGreaterThanRight, TestMultipleEncodersRightReceived) { - isLeftHand = true; - encoder_init(); - - uint8_t slave_state[32] = {1, 0xFF}; // First right encoder is CCW, Second right encoder no change, third right encoder CW - encoder_update_raw(slave_state); - - EXPECT_EQ(updates_array_idx, 2); // two updates received, one for each changed item on the right side - EXPECT_EQ(updates[0].index, 3); - EXPECT_EQ(updates[0].clockwise, false); - EXPECT_EQ(updates[1].index, 4); - EXPECT_EQ(updates[1].clockwise, true); -} diff --git a/quantum/encoder/tests/encoder_tests_split_left_lt_right.cpp b/quantum/encoder/tests/encoder_tests_split_left_lt_right.cpp deleted file mode 100644 index a6519c576257..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_left_lt_right.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool isLeftHand; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isLeftHand) { - // this method has no effect on slave half - printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return true; - } - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestLeftLessThanRight : public ::testing::Test { - protected: - void SetUp() override { - updates_array_idx = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestLeftLessThanRight, TestInitLeft) { - isLeftHand = true; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(pinIsInputHigh[2], true); - EXPECT_EQ(pinIsInputHigh[3], true); - EXPECT_EQ(pinIsInputHigh[4], false); - EXPECT_EQ(pinIsInputHigh[5], false); - EXPECT_EQ(pinIsInputHigh[6], false); - EXPECT_EQ(pinIsInputHigh[7], false); - EXPECT_EQ(pinIsInputHigh[8], false); - EXPECT_EQ(pinIsInputHigh[9], false); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftLessThanRight, TestInitRight) { - isLeftHand = false; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], false); - EXPECT_EQ(pinIsInputHigh[1], false); - EXPECT_EQ(pinIsInputHigh[2], false); - EXPECT_EQ(pinIsInputHigh[3], false); - EXPECT_EQ(pinIsInputHigh[4], true); - EXPECT_EQ(pinIsInputHigh[5], true); - EXPECT_EQ(pinIsInputHigh[6], true); - EXPECT_EQ(pinIsInputHigh[7], true); - EXPECT_EQ(pinIsInputHigh[8], true); - EXPECT_EQ(pinIsInputHigh[9], true); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestLeftLessThanRight, TestOneClockwiseLeft) { - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 1); // one update received - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderSplitTestLeftLessThanRight, TestOneClockwiseRightSent) { - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(6, false); - setAndRead(7, false); - setAndRead(6, true); - setAndRead(7, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(slave_state[0], 0); - EXPECT_EQ(slave_state[1], 0xFF); -} - -TEST_F(EncoderSplitTestLeftLessThanRight, TestMultipleEncodersRightReceived) { - isLeftHand = true; - encoder_init(); - - uint8_t slave_state[32] = {1, 0, 0xFF}; // First right encoder is CCW, Second right encoder no change, third right encoder CW - encoder_update_raw(slave_state); - - EXPECT_EQ(updates_array_idx, 2); // two updates received, one for each changed item on the right side - EXPECT_EQ(updates[0].index, 2); - EXPECT_EQ(updates[0].clockwise, false); - EXPECT_EQ(updates[1].index, 4); - EXPECT_EQ(updates[1].clockwise, true); -} diff --git a/quantum/encoder/tests/encoder_tests_split_no_left.cpp b/quantum/encoder/tests/encoder_tests_split_no_left.cpp deleted file mode 100644 index b6b2d7e2d19a..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_no_left.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool isLeftHand; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isLeftHand) { - // this method has no effect on slave half - printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return true; - } - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestNoLeft : public ::testing::Test { - protected: - void SetUp() override { - updates_array_idx = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestNoLeft, TestInitLeft) { - isLeftHand = true; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], false); - EXPECT_EQ(pinIsInputHigh[1], false); - EXPECT_EQ(pinIsInputHigh[2], false); - EXPECT_EQ(pinIsInputHigh[3], false); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestNoLeft, TestInitRight) { - isLeftHand = false; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(pinIsInputHigh[2], true); - EXPECT_EQ(pinIsInputHigh[3], true); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestNoLeft, TestOneClockwiseLeft) { - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestNoLeft, TestOneClockwiseRightSent) { - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(2, false); - setAndRead(3, false); - setAndRead(2, true); - setAndRead(3, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(slave_state[0], 0); - EXPECT_EQ(slave_state[1], 0xFF); -} - -TEST_F(EncoderSplitTestNoLeft, TestMultipleEncodersRightReceived) { - isLeftHand = true; - encoder_init(); - - uint8_t slave_state[32] = {1, 0xFF}; // First right encoder is CCW, Second right encoder no change, third right encoder CW - encoder_update_raw(slave_state); - - EXPECT_EQ(updates_array_idx, 2); // two updates received, one for each changed item on the right side - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, false); - EXPECT_EQ(updates[1].index, 1); - EXPECT_EQ(updates[1].clockwise, true); -} diff --git a/quantum/encoder/tests/encoder_tests_split_no_right.cpp b/quantum/encoder/tests/encoder_tests_split_no_right.cpp deleted file mode 100644 index fa0a7c18a806..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_no_right.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t updates_array_idx = 0; -update updates[32]; - -bool isLeftHand; - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isLeftHand) { - // this method has no effect on slave half - printf("ignoring update on right hand (%d,%s)\n", index, clockwise ? "CW" : "CC"); - return true; - } - updates[updates_array_idx % 32] = {index, clockwise}; - updates_array_idx++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestNoRight : public ::testing::Test { - protected: - void SetUp() override { - updates_array_idx = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestNoRight, TestInitLeft) { - isLeftHand = true; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], true); - EXPECT_EQ(pinIsInputHigh[1], true); - EXPECT_EQ(pinIsInputHigh[2], true); - EXPECT_EQ(pinIsInputHigh[3], true); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestNoRight, TestInitRight) { - isLeftHand = false; - encoder_init(); - EXPECT_EQ(pinIsInputHigh[0], false); - EXPECT_EQ(pinIsInputHigh[1], false); - EXPECT_EQ(pinIsInputHigh[2], false); - EXPECT_EQ(pinIsInputHigh[3], false); - EXPECT_EQ(updates_array_idx, 0); // no updates received -} - -TEST_F(EncoderSplitTestNoRight, TestOneClockwiseLeft) { - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(updates_array_idx, 1); // one updates received - EXPECT_EQ(updates[0].index, 0); - EXPECT_EQ(updates[0].clockwise, true); -} - -TEST_F(EncoderSplitTestNoRight, TestOneClockwiseRightSent) { - isLeftHand = false; - encoder_init(); - - uint8_t slave_state[32] = {0xAA, 0xAA}; - encoder_state_raw(slave_state); - - EXPECT_EQ(slave_state[0], 0xAA); - EXPECT_EQ(slave_state[1], 0xAA); -} - -TEST_F(EncoderSplitTestNoRight, TestMultipleEncodersRightReceived) { - isLeftHand = true; - encoder_init(); - - uint8_t slave_state[32] = {1, 0xFF}; // These values would trigger updates if there were encoders on the other side - encoder_update_raw(slave_state); - - EXPECT_EQ(updates_array_idx, 0); // no updates received -- no right-hand encoders -} diff --git a/quantum/encoder/tests/encoder_tests_split_role.cpp b/quantum/encoder/tests/encoder_tests_split_role.cpp deleted file mode 100644 index 02264067f4c6..000000000000 --- a/quantum/encoder/tests/encoder_tests_split_role.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include -#include -#include - -extern "C" { -#include "encoder.h" -#include "encoder/tests/mock_split.h" -} - -struct update { - int8_t index; - bool clockwise; -}; - -uint8_t num_updates = 0; - -bool isMaster; -bool isLeftHand; - -bool is_keyboard_master(void) { - return isMaster; -} - -bool encoder_update_kb(uint8_t index, bool clockwise) { - if (!isMaster) { - ADD_FAILURE() << "We shouldn't get here."; - } - num_updates++; - return true; -} - -bool setAndRead(pin_t pin, bool val) { - setPin(pin, val); - return encoder_read(); -} - -class EncoderSplitTestRole : public ::testing::Test { - protected: - void SetUp() override { - num_updates = 0; - for (int i = 0; i < 32; i++) { - pinIsInputHigh[i] = 0; - pins[i] = 0; - } - } -}; - -TEST_F(EncoderSplitTestRole, TestPrimaryLeft) { - isMaster = true; - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(num_updates, 1); // one update received -} - -TEST_F(EncoderSplitTestRole, TestPrimaryRight) { - isMaster = true; - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(6, false); - setAndRead(7, false); - setAndRead(6, true); - setAndRead(7, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(num_updates, 1); // one update received -} - -TEST_F(EncoderSplitTestRole, TestNotPrimaryLeft) { - isMaster = false; - isLeftHand = true; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(0, false); - setAndRead(1, false); - setAndRead(0, true); - setAndRead(1, true); - - EXPECT_EQ(num_updates, 0); // zero updates received -} - -TEST_F(EncoderSplitTestRole, TestNotPrimaryRight) { - isMaster = false; - isLeftHand = false; - encoder_init(); - // send 4 pulses. with resolution 4, that's one step and we should get 1 update. - setAndRead(6, false); - setAndRead(7, false); - setAndRead(6, true); - setAndRead(7, true); - - uint8_t slave_state[32] = {0}; - encoder_state_raw(slave_state); - - EXPECT_EQ(num_updates, 0); // zero updates received -} diff --git a/quantum/encoder/tests/mock.c b/quantum/encoder/tests/mock.c deleted file mode 100644 index 61f2f8294dfc..000000000000 --- a/quantum/encoder/tests/mock.c +++ /dev/null @@ -1,40 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "mock.h" - -bool pins[32] = {0}; -bool pinIsInputHigh[32] = {0}; - -uint8_t mockSetPinInputHigh(pin_t pin) { - // dprintf("Setting pin %d input high.", pin); - pins[pin] = true; - pinIsInputHigh[pin] = true; - return 0; -} - -bool mockReadPin(pin_t pin) { - return pins[pin]; -} - -bool setPin(pin_t pin, bool val) { - pins[pin] = val; - return val; -} - -__attribute__((weak)) bool is_keyboard_master(void) { - return true; -} diff --git a/quantum/encoder/tests/mock.h b/quantum/encoder/tests/mock.h deleted file mode 100644 index 80c336b5ef61..000000000000 --- a/quantum/encoder/tests/mock.h +++ /dev/null @@ -1,34 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#pragma once - -#include -#include - -typedef uint8_t pin_t; - -extern bool pins[]; -extern bool pinIsInputHigh[]; - -#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) -#define readPin(pin) (mockReadPin(pin)) - -uint8_t mockSetPinInputHigh(pin_t pin); - -bool mockReadPin(pin_t pin); - -bool setPin(pin_t pin, bool val); diff --git a/quantum/encoder/tests/mock_split.c b/quantum/encoder/tests/mock_split.c deleted file mode 100644 index 5cc6cd19e172..000000000000 --- a/quantum/encoder/tests/mock_split.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#include "mock_split.h" - -bool pins[32] = {0}; -bool pinIsInputHigh[32] = {0}; - -uint8_t mockSetPinInputHigh(pin_t pin) { - // dprintf("Setting pin %d input high.", pin); - pins[pin] = true; - pinIsInputHigh[pin] = true; - return 0; -} - -bool mockReadPin(pin_t pin) { - return pins[pin]; -} - -bool setPin(pin_t pin, bool val) { - pins[pin] = val; - return val; -} - -void last_encoder_activity_trigger(void) {} - -__attribute__((weak)) bool is_keyboard_master(void) { - return true; -} diff --git a/quantum/encoder/tests/mock_split.h b/quantum/encoder/tests/mock_split.h deleted file mode 100644 index 2fc12f18306f..000000000000 --- a/quantum/encoder/tests/mock_split.h +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright 2021 Balz Guenat - * - * 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 . - */ - -#pragma once - -#include -#include - -#define SPLIT_KEYBOARD -typedef uint8_t pin_t; - -void encoder_state_raw(uint8_t* slave_state); -void encoder_update_raw(uint8_t* slave_state); - -extern bool pins[]; -extern bool pinIsInputHigh[]; - -#define setPinInputHigh(pin) (mockSetPinInputHigh(pin)) -#define readPin(pin) (mockReadPin(pin)) - -uint8_t mockSetPinInputHigh(pin_t pin); - -bool mockReadPin(pin_t pin); - -bool setPin(pin_t pin, bool val); diff --git a/quantum/encoder/tests/rules.mk b/quantum/encoder/tests/rules.mk deleted file mode 100644 index d01c1c66ee52..000000000000 --- a/quantum/encoder/tests/rules.mk +++ /dev/null @@ -1,68 +0,0 @@ -encoder_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SINGLE -encoder_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock.h - -encoder_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_left_eq_right_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_left_eq_right_INC := $(QUANTUM_PATH)/split_common -encoder_split_left_eq_right_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_left_eq_right.h - -encoder_split_left_eq_right_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_left_eq_right.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_left_gt_right_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_left_gt_right_INC := $(QUANTUM_PATH)/split_common -encoder_split_left_gt_right_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_left_gt_right.h - -encoder_split_left_gt_right_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_left_gt_right.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_left_lt_right_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_left_lt_right_INC := $(QUANTUM_PATH)/split_common -encoder_split_left_lt_right_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_left_lt_right.h - -encoder_split_left_lt_right_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_left_lt_right.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_no_left_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_no_left_INC := $(QUANTUM_PATH)/split_common -encoder_split_no_left_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_no_left.h - -encoder_split_no_left_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_no_left.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_no_right_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_no_right_INC := $(QUANTUM_PATH)/split_common -encoder_split_no_right_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_no_right.h - -encoder_split_no_right_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_no_right.cpp \ - $(QUANTUM_PATH)/encoder.c - -encoder_split_role_DEFS := -DENCODER_TESTS -DENCODER_ENABLE -DENCODER_MOCK_SPLIT -encoder_split_role_INC := $(QUANTUM_PATH)/split_common -encoder_split_role_CONFIG := $(QUANTUM_PATH)/encoder/tests/config_mock_split_role.h - -encoder_split_role_SRC := \ - platforms/test/timer.c \ - $(QUANTUM_PATH)/encoder/tests/mock_split.c \ - $(QUANTUM_PATH)/encoder/tests/encoder_tests_split_role.cpp \ - $(QUANTUM_PATH)/encoder.c diff --git a/quantum/encoder/tests/testlist.mk b/quantum/encoder/tests/testlist.mk deleted file mode 100644 index a407f1faddf4..000000000000 --- a/quantum/encoder/tests/testlist.mk +++ /dev/null @@ -1,8 +0,0 @@ -TEST_LIST += \ - encoder \ - encoder_split_left_eq_right \ - encoder_split_left_gt_right \ - encoder_split_left_lt_right \ - encoder_split_no_left \ - encoder_split_no_right \ - encoder_split_role \ diff --git a/quantum/haptic.c b/quantum/haptic.c deleted file mode 100644 index c151547fcafc..000000000000 --- a/quantum/haptic.c +++ /dev/null @@ -1,351 +0,0 @@ -/* Copyright 2019 ishtob - * Driver for haptic feedback written for QMK - * - * 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 . - */ -#include "haptic.h" -#include "eeconfig.h" -#include "debug.h" -#include "usb_device_state.h" -#include "gpio.h" -#ifdef DRV2605L -# include "DRV2605L.h" -#endif -#ifdef SOLENOID_ENABLE -# include "solenoid.h" -#endif -#if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE) -extern uint8_t split_haptic_play; -#endif - -haptic_config_t haptic_config; - -static void update_haptic_enable_gpios(void) { - if (haptic_config.enable && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { -#if defined(HAPTIC_ENABLE_PIN) - HAPTIC_ENABLE_PIN_WRITE_ACTIVE(); -#endif -#if defined(HAPTIC_ENABLE_STATUS_LED) - HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE(); -#endif - } else { -#if defined(HAPTIC_ENABLE_PIN) - HAPTIC_ENABLE_PIN_WRITE_INACTIVE(); -#endif -#if defined(HAPTIC_ENABLE_STATUS_LED) - HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE(); -#endif - } -} - -static void set_haptic_config_enable(bool enabled) { - haptic_config.enable = enabled; - update_haptic_enable_gpios(); -} - -void haptic_init(void) { - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - haptic_config.raw = eeconfig_read_haptic(); -#ifdef SOLENOID_ENABLE - solenoid_set_dwell(haptic_config.dwell); -#endif - if ((haptic_config.raw == 0) -#ifdef SOLENOID_ENABLE - || (haptic_config.dwell == 0) -#endif - ) { - // this will be called, if the eeprom is not corrupt, - // but the previous firmware didn't have haptic enabled, - // or the previous firmware didn't have solenoid enabled, - // and the current one has solenoid enabled. - haptic_reset(); - } else { - // Haptic configuration has been loaded through the "raw" union item. - // This is to execute any side effects of the configuration. - set_haptic_config_enable(haptic_config.enable); - } -#ifdef SOLENOID_ENABLE - solenoid_setup(); - dprintf("Solenoid driver initialized\n"); -#endif -#ifdef DRV2605L - DRV_init(); - dprintf("DRV2605 driver initialized\n"); -#endif - eeconfig_debug_haptic(); -#ifdef HAPTIC_ENABLE_PIN - setPinOutput(HAPTIC_ENABLE_PIN); -#endif -#ifdef HAPTIC_ENABLE_STATUS_LED - setPinOutput(HAPTIC_ENABLE_STATUS_LED); -#endif -} - -void haptic_task(void) { -#ifdef SOLENOID_ENABLE - solenoid_check(); -#endif -} - -void eeconfig_debug_haptic(void) { - dprintf("haptic_config eeprom\n"); - dprintf("haptic_config.enable = %d\n", haptic_config.enable); - dprintf("haptic_config.mode = %d\n", haptic_config.mode); -} - -void haptic_enable(void) { - set_haptic_config_enable(true); - xprintf("haptic_config.enable = %u\n", haptic_config.enable); - eeconfig_update_haptic(haptic_config.raw); -} - -void haptic_disable(void) { - set_haptic_config_enable(false); - xprintf("haptic_config.enable = %u\n", haptic_config.enable); - eeconfig_update_haptic(haptic_config.raw); -} - -void haptic_toggle(void) { - if (haptic_config.enable) { - haptic_disable(); - } else { - haptic_enable(); - } - eeconfig_update_haptic(haptic_config.raw); -} - -void haptic_feedback_toggle(void) { - haptic_config.feedback++; - if (haptic_config.feedback >= HAPTIC_FEEDBACK_MAX) haptic_config.feedback = KEY_PRESS; - xprintf("haptic_config.feedback = %u\n", !haptic_config.feedback); - eeconfig_update_haptic(haptic_config.raw); -} - -void haptic_buzz_toggle(void) { - bool buzz_stat = !haptic_config.buzz; - haptic_config.buzz = buzz_stat; - haptic_set_buzz(buzz_stat); -} - -void haptic_mode_increase(void) { - uint8_t mode = haptic_config.mode + 1; -#ifdef DRV2605L - if (haptic_config.mode >= drv_effect_max) { - mode = 1; - } -#endif - haptic_set_mode(mode); -} - -void haptic_mode_decrease(void) { - uint8_t mode = haptic_config.mode - 1; -#ifdef DRV2605L - if (haptic_config.mode < 1) { - mode = (drv_effect_max - 1); - } -#endif - haptic_set_mode(mode); -} - -void haptic_dwell_increase(void) { -#ifdef SOLENOID_ENABLE - int16_t next_dwell = ((int16_t)haptic_config.dwell) + SOLENOID_DWELL_STEP_SIZE; - if (haptic_config.dwell >= SOLENOID_MAX_DWELL) { - // if it's already at max, we wrap back to min - next_dwell = SOLENOID_MIN_DWELL; - } else if (next_dwell > SOLENOID_MAX_DWELL) { - // if we overshoot the max, then cap at max - next_dwell = SOLENOID_MAX_DWELL; - } - solenoid_set_dwell(next_dwell); -#else - int16_t next_dwell = ((int16_t)haptic_config.dwell) + 1; -#endif - haptic_set_dwell(next_dwell); -} - -void haptic_dwell_decrease(void) { -#ifdef SOLENOID_ENABLE - int16_t next_dwell = ((int16_t)haptic_config.dwell) - SOLENOID_DWELL_STEP_SIZE; - if (haptic_config.dwell <= SOLENOID_MIN_DWELL) { - // if it's already at min, we wrap to max - next_dwell = SOLENOID_MAX_DWELL; - } else if (next_dwell < SOLENOID_MIN_DWELL) { - // if we go below min, then we cap to min - next_dwell = SOLENOID_MIN_DWELL; - } - solenoid_set_dwell(next_dwell); -#else - int16_t next_dwell = ((int16_t)haptic_config.dwell) - 1; -#endif - haptic_set_dwell(next_dwell); -} - -void haptic_reset(void) { - set_haptic_config_enable(true); - uint8_t feedback = HAPTIC_FEEDBACK_DEFAULT; - haptic_config.feedback = feedback; -#ifdef DRV2605L - uint8_t mode = HAPTIC_MODE_DEFAULT; - haptic_config.mode = mode; -#endif -#ifdef SOLENOID_ENABLE - uint8_t dwell = SOLENOID_DEFAULT_DWELL; - haptic_config.dwell = dwell; - haptic_config.buzz = SOLENOID_DEFAULT_BUZZ; - solenoid_set_dwell(dwell); -#else - // This is to trigger haptic_reset again, if solenoid is enabled in the future. - haptic_config.dwell = 0; - haptic_config.buzz = 0; -#endif - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); - xprintf("haptic_config.mode = %u\n", haptic_config.mode); -} - -void haptic_set_feedback(uint8_t feedback) { - haptic_config.feedback = feedback; - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.feedback = %u\n", haptic_config.feedback); -} - -void haptic_set_mode(uint8_t mode) { - haptic_config.mode = mode; - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.mode = %u\n", haptic_config.mode); -} - -void haptic_set_amplitude(uint8_t amp) { - haptic_config.amplitude = amp; - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.amplitude = %u\n", haptic_config.amplitude); -#ifdef DRV2605L - DRV_amplitude(amp); -#endif -} - -void haptic_set_buzz(uint8_t buzz) { - haptic_config.buzz = buzz; - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.buzz = %u\n", haptic_config.buzz); -} - -void haptic_set_dwell(uint8_t dwell) { - haptic_config.dwell = dwell; - eeconfig_update_haptic(haptic_config.raw); - xprintf("haptic_config.dwell = %u\n", haptic_config.dwell); -} - -uint8_t haptic_get_enable(void) { - return haptic_config.enable; -} - -uint8_t haptic_get_mode(void) { - if (!haptic_config.enable) { - return false; - } - return haptic_config.mode; -} - -uint8_t haptic_get_feedback(void) { - if (!haptic_config.enable) { - return false; - } - return haptic_config.feedback; -} - -uint8_t haptic_get_dwell(void) { - if (!haptic_config.enable) { - return false; - } - return haptic_config.dwell; -} - -void haptic_enable_continuous(void) { - haptic_config.cont = 1; - xprintf("haptic_config.cont = %u\n", haptic_config.cont); - eeconfig_update_haptic(haptic_config.raw); -#ifdef DRV2605L - DRV_rtp_init(); -#endif -} - -void haptic_disable_continuous(void) { - haptic_config.cont = 0; - xprintf("haptic_config.cont = %u\n", haptic_config.cont); - eeconfig_update_haptic(haptic_config.raw); -#ifdef DRV2605L - DRV_write(DRV_MODE, 0x00); -#endif -} - -void haptic_toggle_continuous(void) { - if (haptic_config.cont) { - haptic_disable_continuous(); - } else { - haptic_enable_continuous(); - } -} - -void haptic_cont_increase(void) { - uint8_t amp = haptic_config.amplitude + 10; - if (haptic_config.amplitude >= 120) { - amp = 120; - } - haptic_set_amplitude(amp); -} - -void haptic_cont_decrease(void) { - uint8_t amp = haptic_config.amplitude - 10; - if (haptic_config.amplitude < 20) { - amp = 20; - } - haptic_set_amplitude(amp); -} - -void haptic_play(void) { -#ifdef DRV2605L - uint8_t play_eff = 0; - play_eff = haptic_config.mode; - DRV_pulse(play_eff); -# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE) - split_haptic_play = haptic_config.mode; -# endif -#endif -#ifdef SOLENOID_ENABLE - solenoid_fire_handler(); -# if defined(SPLIT_KEYBOARD) && defined(SPLIT_HAPTIC_ENABLE) - split_haptic_play = 1; -# endif -#endif -} - -void haptic_shutdown(void) { -#ifdef SOLENOID_ENABLE - solenoid_shutdown(); -#endif -} - -void haptic_notify_usb_device_state_change(void) { - update_haptic_enable_gpios(); -#if defined(HAPTIC_ENABLE_PIN) - setPinOutput(HAPTIC_ENABLE_PIN); -#endif -#if defined(HAPTIC_ENABLE_STATUS_LED) - setPinOutput(HAPTIC_ENABLE_STATUS_LED); -#endif -} diff --git a/quantum/haptic.h b/quantum/haptic.h deleted file mode 100644 index 71d95cc61b3e..000000000000 --- a/quantum/haptic.h +++ /dev/null @@ -1,106 +0,0 @@ -/* Copyright 2019 ishtob - * Driver for haptic feedback written for QMK - * - * 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 . - */ - -#pragma once -#include -#include - -#ifndef HAPTIC_FEEDBACK_DEFAULT -# define HAPTIC_FEEDBACK_DEFAULT 0 -#endif -#ifndef HAPTIC_MODE_DEFAULT -# define HAPTIC_MODE_DEFAULT DRV_MODE_DEFAULT -#endif - -/* EEPROM config settings */ -typedef union { - uint32_t raw; - struct { - bool enable : 1; - uint8_t mode : 7; - bool buzz : 1; - uint8_t dwell : 7; - uint8_t amplitude : 8; - uint8_t feedback : 2; - bool cont : 1; - uint8_t reserved : 5; - }; -} haptic_config_t; - -_Static_assert(sizeof(haptic_config_t) == sizeof(uint32_t), "Haptic EECONFIG out of spec."); - -typedef enum HAPTIC_FEEDBACK { - KEY_PRESS, - KEY_PRESS_RELEASE, - KEY_RELEASE, - HAPTIC_FEEDBACK_MAX, -} HAPTIC_FEEDBACK; - -void haptic_init(void); -void haptic_task(void); -void eeconfig_debug_haptic(void); -void haptic_enable(void); -void haptic_disable(void); -void haptic_toggle(void); -void haptic_feedback_toggle(void); -void haptic_mode_increase(void); -void haptic_mode_decrease(void); -void haptic_mode(uint8_t mode); -void haptic_reset(void); -void haptic_set_feedback(uint8_t feedback); -void haptic_set_mode(uint8_t mode); -void haptic_set_dwell(uint8_t dwell); -void haptic_set_buzz(uint8_t buzz); -void haptic_buzz_toggle(void); -uint8_t haptic_get_enable(void); -uint8_t haptic_get_mode(void); -uint8_t haptic_get_feedback(void); -void haptic_dwell_increase(void); -void haptic_dwell_decrease(void); -void haptic_toggle_continuous(void); -void haptic_cont_increase(void); -void haptic_cont_decrease(void); - -void haptic_play(void); -void haptic_shutdown(void); -void haptic_notify_usb_device_state_change(void); - -#ifdef HAPTIC_ENABLE_PIN_ACTIVE_LOW -# ifndef HAPTIC_ENABLE_PIN -# error HAPTIC_ENABLE_PIN not defined -# endif -# define HAPTIC_ENABLE_PIN_WRITE_ACTIVE() writePinLow(HAPTIC_ENABLE_PIN) -# define HAPTIC_ENABLE_PIN_WRITE_INACTIVE() writePinHigh(HAPTIC_ENABLE_PIN) -#else -# define HAPTIC_ENABLE_PIN_WRITE_ACTIVE() writePinHigh(HAPTIC_ENABLE_PIN) -# define HAPTIC_ENABLE_PIN_WRITE_INACTIVE() writePinLow(HAPTIC_ENABLE_PIN) -#endif - -#ifdef HAPTIC_ENABLE_STATUS_LED_ACTIVE_LOW -# ifndef HAPTIC_ENABLE_STATUS_LED -# error HAPTIC_ENABLE_STATUS_LED not defined -# endif -# define HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE() writePinLow(HAPTIC_ENABLE_STATUS_LED) -# define HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE() writePinHigh(HAPTIC_ENABLE_STATUS_LED) -#else -# define HAPTIC_ENABLE_STATUS_LED_WRITE_ACTIVE() writePinHigh(HAPTIC_ENABLE_STATUS_LED) -# define HAPTIC_ENABLE_STATUS_LED_WRITE_INACTIVE() writePinLow(HAPTIC_ENABLE_STATUS_LED) -#endif - -#ifndef HAPTIC_OFF_IN_LOW_POWER -# define HAPTIC_OFF_IN_LOW_POWER 0 -#endif diff --git a/quantum/joystick.c b/quantum/joystick.c deleted file mode 100644 index 02818e4acd39..000000000000 --- a/quantum/joystick.c +++ /dev/null @@ -1,135 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#include "joystick.h" - -#include "analog.h" -#include "wait.h" - -joystick_t joystick_state = { - .buttons = {0}, - .axes = - { -#if JOYSTICK_AXIS_COUNT > 0 - 0 -#endif - }, - .dirty = false, -}; - -// array defining the reading of analog values for each axis -__attribute__((weak)) joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = {}; - -__attribute__((weak)) void joystick_task(void) { - joystick_read_axes(); -} - -void joystick_flush(void) { - if (joystick_state.dirty) { - host_joystick_send(&joystick_state); - joystick_state.dirty = false; - } -} - -void register_joystick_button(uint8_t button) { - if (button >= JOYSTICK_BUTTON_COUNT) return; - joystick_state.buttons[button / 8] |= 1 << (button % 8); - joystick_state.dirty = true; - joystick_flush(); -} - -void unregister_joystick_button(uint8_t button) { - if (button >= JOYSTICK_BUTTON_COUNT) return; - joystick_state.buttons[button / 8] &= ~(1 << (button % 8)); - joystick_state.dirty = true; - joystick_flush(); -} - -int16_t joystick_read_axis(uint8_t axis) { - if (axis >= JOYSTICK_AXIS_COUNT) return 0; - - // disable pull-up resistor - writePinLow(joystick_axes[axis].input_pin); - - // if pin was a pull-up input, we need to uncharge it by turning it low - // before making it a low input - setPinOutput(joystick_axes[axis].input_pin); - - wait_us(10); - - if (joystick_axes[axis].output_pin != JS_VIRTUAL_AXIS) { - setPinOutput(joystick_axes[axis].output_pin); - writePinHigh(joystick_axes[axis].output_pin); - } - - if (joystick_axes[axis].ground_pin != JS_VIRTUAL_AXIS) { - setPinOutput(joystick_axes[axis].ground_pin); - writePinLow(joystick_axes[axis].ground_pin); - } - - wait_us(10); - - setPinInput(joystick_axes[axis].input_pin); - - wait_us(10); - -#if defined(ANALOG_JOYSTICK_ENABLE) && (defined(__AVR__) || defined(PROTOCOL_CHIBIOS)) - int16_t axis_val = analogReadPin(joystick_axes[axis].input_pin); -#else - // default to resting position - int16_t axis_val = joystick_axes[axis].mid_digit; -#endif - - // test the converted value against the lower range - int32_t ref = joystick_axes[axis].mid_digit; - int32_t range = joystick_axes[axis].min_digit; - int32_t ranged_val = ((axis_val - ref) * -JOYSTICK_MAX_VALUE) / (range - ref); - - if (ranged_val > 0) { - // the value is in the higher range - range = joystick_axes[axis].max_digit; - ranged_val = ((axis_val - ref) * JOYSTICK_MAX_VALUE) / (range - ref); - } - - // clamp the result in the valid range - ranged_val = ranged_val < -JOYSTICK_MAX_VALUE ? -JOYSTICK_MAX_VALUE : ranged_val; - ranged_val = ranged_val > JOYSTICK_MAX_VALUE ? JOYSTICK_MAX_VALUE : ranged_val; - - return ranged_val; -} - -void joystick_read_axes(void) { -#if JOYSTICK_AXIS_COUNT > 0 - for (int i = 0; i < JOYSTICK_AXIS_COUNT; ++i) { - if (joystick_axes[i].input_pin == JS_VIRTUAL_AXIS) { - continue; - } - - joystick_set_axis(i, joystick_read_axis(i)); - } - - joystick_flush(); -#endif -} - -void joystick_set_axis(uint8_t axis, int16_t value) { - if (axis >= JOYSTICK_AXIS_COUNT) return; - - if (value != joystick_state.axes[axis]) { - joystick_state.axes[axis] = value; - joystick_state.dirty = true; - } -} diff --git a/quantum/joystick.h b/quantum/joystick.h deleted file mode 100644 index 5de4ba66c6ab..000000000000 --- a/quantum/joystick.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#pragma once - -#include -#include - -#include "gpio.h" - -/** - * \file - * - * \defgroup joystick HID Joystick - * \{ - */ - -#ifndef JOYSTICK_BUTTON_COUNT -# define JOYSTICK_BUTTON_COUNT 8 -#elif JOYSTICK_BUTTON_COUNT > 32 -# error Joystick feature only supports up to 32 buttons -#endif - -#ifndef JOYSTICK_AXIS_COUNT -# define JOYSTICK_AXIS_COUNT 2 -#elif JOYSTICK_AXIS_COUNT > 6 -# error Joystick feature only supports up to 6 axes -#endif - -#if JOYSTICK_AXIS_COUNT == 0 && JOYSTICK_BUTTON_COUNT == 0 -# error Joystick feature requires at least one axis or button -#endif - -#ifndef JOYSTICK_AXIS_RESOLUTION -# define JOYSTICK_AXIS_RESOLUTION 8 -#elif JOYSTICK_AXIS_RESOLUTION < 8 || JOYSTICK_AXIS_RESOLUTION > 16 -# error JOYSTICK_AXIS_RESOLUTION must be between 8 and 16 -#endif - -#define JOYSTICK_MAX_VALUE ((1L << (JOYSTICK_AXIS_RESOLUTION - 1)) - 1) - -// configure on input_pin of the joystick_axes array entry to JS_VIRTUAL_AXIS -// to prevent it from being read from the ADC. This allows outputing forged axis value. -// -#define JS_VIRTUAL_AXIS 0xFF - -#define JOYSTICK_AXIS_VIRTUAL \ - { JS_VIRTUAL_AXIS, JS_VIRTUAL_AXIS, JS_VIRTUAL_AXIS, 0, 1023 } -#define JOYSTICK_AXIS_IN(INPUT_PIN, LOW, REST, HIGH) \ - { JS_VIRTUAL_AXIS, INPUT_PIN, JS_VIRTUAL_AXIS, LOW, REST, HIGH } -#define JOYSTICK_AXIS_IN_OUT(INPUT_PIN, OUTPUT_PIN, LOW, REST, HIGH) \ - { OUTPUT_PIN, INPUT_PIN, JS_VIRTUAL_AXIS, LOW, REST, HIGH } -#define JOYSTICK_AXIS_IN_OUT_GROUND(INPUT_PIN, OUTPUT_PIN, GROUND_PIN, LOW, REST, HIGH) \ - { OUTPUT_PIN, INPUT_PIN, GROUND_PIN, LOW, REST, HIGH } - -typedef struct { - pin_t output_pin; - pin_t input_pin; - pin_t ground_pin; - - // the AVR ADC offers 10 bit precision, with significant bits on the higher part - uint16_t min_digit; - uint16_t mid_digit; - uint16_t max_digit; -} joystick_config_t; - -extern joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT]; - -typedef struct { - uint8_t buttons[(JOYSTICK_BUTTON_COUNT - 1) / 8 + 1]; - int16_t axes[JOYSTICK_AXIS_COUNT]; - bool dirty; -} joystick_t; - -extern joystick_t joystick_state; - -void joystick_task(void); - -/** - * \brief Send the joystick report to the host, if it has been marked as dirty. - */ -void joystick_flush(void); - -/** - * \brief Set the state of a button, and flush the report. - * - * \param button The index of the button to press, from 0 to 31. - */ -void register_joystick_button(uint8_t button); - -/** - * \brief Reset the state of a button, and flush the report. - * - * \param button The index of the button to release, from 0 to 31. - */ -void unregister_joystick_button(uint8_t button); - -/** - * \brief Sample and process the analog value of the given axis. - * - * \param axis The axis to read. - * - * \return A signed 16-bit integer, where 0 is the resting or mid point. - */ -int16_t joystick_read_axis(uint8_t axis); - -void joystick_read_axes(void); - -/** - * \brief Set the value of the given axis. - * - * \param axis The axis to set the value of. - * \param value The value to set. - */ -void joystick_set_axis(uint8_t axis, int16_t value); - -void host_joystick_send(joystick_t *joystick); - -/** \} */ diff --git a/quantum/keyboard.c b/quantum/keyboard.c deleted file mode 100644 index 511570974878..000000000000 --- a/quantum/keyboard.c +++ /dev/null @@ -1,700 +0,0 @@ -/* -Copyright 2011, 2012, 2013 Jun Wako - -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 . -*/ - -#include -#include "quantum.h" -#include "keyboard.h" -#include "matrix.h" -#include "keymap_introspection.h" -#include "magic.h" -#include "host.h" -#include "led.h" -#include "keycode.h" -#include "timer.h" -#include "sync_timer.h" -#include "print.h" -#include "debug.h" -#include "command.h" -#include "util.h" -#include "sendchar.h" -#include "eeconfig.h" -#include "action_layer.h" -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif -#ifdef MOUSEKEY_ENABLE -# include "mousekey.h" -#endif -#ifdef PS2_MOUSE_ENABLE -# include "ps2_mouse.h" -#endif -#ifdef RGBLIGHT_ENABLE -# include "rgblight.h" -#endif -#ifdef LED_MATRIX_ENABLE -# include "led_matrix.h" -#endif -#ifdef RGB_MATRIX_ENABLE -# include "rgb_matrix.h" -#endif -#ifdef ENCODER_ENABLE -# include "encoder.h" -#endif -#ifdef STENO_ENABLE -# include "process_steno.h" -#endif -#ifdef POINTING_DEVICE_ENABLE -# include "pointing_device.h" -#endif -#ifdef MIDI_ENABLE -# include "process_midi.h" -#endif -#ifdef JOYSTICK_ENABLE -# include "process_joystick.h" -#endif -#ifdef HD44780_ENABLE -# include "hd44780.h" -#endif -#ifdef OLED_ENABLE -# include "oled_driver.h" -#endif -#ifdef ST7565_ENABLE -# include "st7565.h" -#endif -#ifdef VELOCIKEY_ENABLE -# include "velocikey.h" -#endif -#ifdef VIA_ENABLE -# include "via.h" -#endif -#ifdef DIP_SWITCH_ENABLE -# include "dip_switch.h" -#endif -#ifdef EEPROM_DRIVER -# include "eeprom_driver.h" -#endif -#if defined(CRC_ENABLE) -# include "crc.h" -#endif -#ifdef VIRTSER_ENABLE -# include "virtser.h" -#endif -#ifdef SLEEP_LED_ENABLE -# include "sleep_led.h" -#endif -#ifdef SPLIT_KEYBOARD -# include "split_util.h" -#endif -#ifdef BLUETOOTH_ENABLE -# include "bluetooth.h" -#endif -#ifdef CAPS_WORD_ENABLE -# include "caps_word.h" -#endif -#ifdef LEADER_ENABLE -# include "leader.h" -#endif - -static uint32_t last_input_modification_time = 0; -uint32_t last_input_activity_time(void) { - return last_input_modification_time; -} -uint32_t last_input_activity_elapsed(void) { - return sync_timer_elapsed32(last_input_modification_time); -} - -static uint32_t last_matrix_modification_time = 0; -uint32_t last_matrix_activity_time(void) { - return last_matrix_modification_time; -} -uint32_t last_matrix_activity_elapsed(void) { - return sync_timer_elapsed32(last_matrix_modification_time); -} -void last_matrix_activity_trigger(void) { - last_matrix_modification_time = last_input_modification_time = sync_timer_read32(); -} - -static uint32_t last_encoder_modification_time = 0; -uint32_t last_encoder_activity_time(void) { - return last_encoder_modification_time; -} -uint32_t last_encoder_activity_elapsed(void) { - return sync_timer_elapsed32(last_encoder_modification_time); -} -void last_encoder_activity_trigger(void) { - last_encoder_modification_time = last_input_modification_time = sync_timer_read32(); -} - -static uint32_t last_pointing_device_modification_time = 0; -uint32_t last_pointing_device_activity_time(void) { - return last_pointing_device_modification_time; -} -uint32_t last_pointing_device_activity_elapsed(void) { - return sync_timer_elapsed32(last_pointing_device_modification_time); -} -void last_pointing_device_activity_trigger(void) { - last_pointing_device_modification_time = last_input_modification_time = sync_timer_read32(); -} - -void set_activity_timestamps(uint32_t matrix_timestamp, uint32_t encoder_timestamp, uint32_t pointing_device_timestamp) { - last_matrix_modification_time = matrix_timestamp; - last_encoder_modification_time = encoder_timestamp; - last_pointing_device_modification_time = pointing_device_timestamp; - last_input_modification_time = MAX(matrix_timestamp, MAX(encoder_timestamp, pointing_device_timestamp)); -} - -// Only enable this if console is enabled to print to -#if defined(DEBUG_MATRIX_SCAN_RATE) -static uint32_t matrix_timer = 0; -static uint32_t matrix_scan_count = 0; -static uint32_t last_matrix_scan_count = 0; - -void matrix_scan_perf_task(void) { - matrix_scan_count++; - - uint32_t timer_now = timer_read32(); - if (TIMER_DIFF_32(timer_now, matrix_timer) >= 1000) { -# if defined(CONSOLE_ENABLE) - dprintf("matrix scan frequency: %lu\n", matrix_scan_count); -# endif - last_matrix_scan_count = matrix_scan_count; - matrix_timer = timer_now; - matrix_scan_count = 0; - } -} - -uint32_t get_matrix_scan_rate(void) { - return last_matrix_scan_count; -} -#else -# define matrix_scan_perf_task() -#endif - -#ifdef MATRIX_HAS_GHOST -static matrix_row_t get_real_keys(uint8_t row, matrix_row_t rowdata) { - matrix_row_t out = 0; - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - // read each key in the row data and check if the keymap defines it as a real key - if (keycode_at_keymap_location(0, row, col) && (rowdata & (((matrix_row_t)1) << col))) { - // this creates new row data, if a key is defined in the keymap, it will be set here - out |= ((matrix_row_t)1) << col; - } - } - return out; -} - -static inline bool popcount_more_than_one(matrix_row_t rowdata) { - rowdata &= rowdata - 1; // if there are less than two bits (keys) set, rowdata will become zero - return rowdata; -} - -static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) { - /* No ghost exists when less than 2 keys are down on the row. - If there are "active" blanks in the matrix, the key can't be pressed by the user, - there is no doubt as to which keys are really being pressed. - The ghosts will be ignored, they are KC_NO. */ - rowdata = get_real_keys(row, rowdata); - if ((popcount_more_than_one(rowdata)) == 0) { - return false; - } - /* Ghost occurs when the row shares a column line with other row, - and two columns are read on each row. Blanks in the matrix don't matter, - so they are filtered out. - If there are two or more real keys pressed and they match columns with - at least two of another row's real keys, the row will be ignored. Keep in mind, - we are checking one row at a time, not all of them at once. - */ - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - if (i != row && popcount_more_than_one(get_real_keys(i, matrix_get_row(i)) & rowdata)) { - return true; - } - } - return false; -} - -#else - -static inline bool has_ghost_in_row(uint8_t row, matrix_row_t rowdata) { - return false; -} - -#endif - -/** \brief matrix_setup - * - * FIXME: needs doc - */ -__attribute__((weak)) void matrix_setup(void) {} - -/** \brief keyboard_pre_init_user - * - * FIXME: needs doc - */ -__attribute__((weak)) void keyboard_pre_init_user(void) {} - -/** \brief keyboard_pre_init_kb - * - * FIXME: needs doc - */ -__attribute__((weak)) void keyboard_pre_init_kb(void) { - keyboard_pre_init_user(); -} - -/** \brief keyboard_post_init_user - * - * FIXME: needs doc - */ - -__attribute__((weak)) void keyboard_post_init_user(void) {} - -/** \brief keyboard_post_init_kb - * - * FIXME: needs doc - */ - -__attribute__((weak)) void keyboard_post_init_kb(void) { - keyboard_post_init_user(); -} - -/** \brief matrix_can_read - * - * Allows overriding when matrix scanning operations should be executed. - */ -__attribute__((weak)) bool matrix_can_read(void) { - return true; -} - -/** \brief keyboard_setup - * - * FIXME: needs doc - */ -void keyboard_setup(void) { - print_set_sendchar(sendchar); -#ifdef EEPROM_DRIVER - eeprom_driver_init(); -#endif - matrix_setup(); - keyboard_pre_init_kb(); -} - -#ifndef SPLIT_KEYBOARD - -/** \brief is_keyboard_master - * - * FIXME: needs doc - */ -__attribute__((weak)) bool is_keyboard_master(void) { - return true; -} - -/** \brief is_keyboard_left - * - * FIXME: needs doc - */ -__attribute__((weak)) bool is_keyboard_left(void) { - return true; -} - -#endif - -/** \brief should_process_keypress - * - * Override this function if you have a condition where keypresses processing should change: - * - splits where the slave side needs to process for rgb/oled functionality - */ -__attribute__((weak)) bool should_process_keypress(void) { - return is_keyboard_master(); -} - -/** \brief housekeeping_task_kb - * - * Override this function if you have a need to execute code for every keyboard main loop iteration. - * This is specific to keyboard-level functionality. - */ -__attribute__((weak)) void housekeeping_task_kb(void) {} - -/** \brief housekeeping_task_user - * - * Override this function if you have a need to execute code for every keyboard main loop iteration. - * This is specific to user/keymap-level functionality. - */ -__attribute__((weak)) void housekeeping_task_user(void) {} - -/** \brief housekeeping_task - * - * Invokes hooks for executing code after QMK is done after each loop iteration. - */ -void housekeeping_task(void) { - housekeeping_task_kb(); - housekeeping_task_user(); -} - -/** \brief Init tasks previously located in matrix_init_quantum - * - * TODO: rationalise against keyboard_init and current split role - */ -void quantum_init(void) { - magic(); - led_init_ports(); -#ifdef BACKLIGHT_ENABLE - backlight_init_ports(); -#endif -#ifdef AUDIO_ENABLE - audio_init(); -#endif -#ifdef LED_MATRIX_ENABLE - led_matrix_init(); -#endif -#ifdef RGB_MATRIX_ENABLE - rgb_matrix_init(); -#endif -#if defined(UNICODE_COMMON_ENABLE) - unicode_input_mode_init(); -#endif -#ifdef HAPTIC_ENABLE - haptic_init(); -#endif -} - -/** \brief keyboard_init - * - * FIXME: needs doc - */ -void keyboard_init(void) { - timer_init(); - sync_timer_init(); -#ifdef VIA_ENABLE - via_init(); -#endif -#ifdef SPLIT_KEYBOARD - split_pre_init(); -#endif -#ifdef ENCODER_ENABLE - encoder_init(); -#endif - matrix_init(); - quantum_init(); -#if defined(CRC_ENABLE) - crc_init(); -#endif -#ifdef OLED_ENABLE - oled_init(OLED_ROTATION_0); -#endif -#ifdef ST7565_ENABLE - st7565_init(DISPLAY_ROTATION_0); -#endif -#ifdef PS2_MOUSE_ENABLE - ps2_mouse_init(); -#endif -#ifdef BACKLIGHT_ENABLE - backlight_init(); -#endif -#ifdef RGBLIGHT_ENABLE - rgblight_init(); -#endif -#ifdef STENO_ENABLE_ALL - steno_init(); -#endif -#if defined(NKRO_ENABLE) && defined(FORCE_NKRO) - keymap_config.nkro = 1; - eeconfig_update_keymap(keymap_config.raw); -#endif -#ifdef DIP_SWITCH_ENABLE - dip_switch_init(); -#endif -#ifdef SLEEP_LED_ENABLE - sleep_led_init(); -#endif -#ifdef VIRTSER_ENABLE - virtser_init(); -#endif -#ifdef SPLIT_KEYBOARD - split_post_init(); -#endif -#ifdef POINTING_DEVICE_ENABLE - // init after split init - pointing_device_init(); -#endif -#ifdef BLUETOOTH_ENABLE - bluetooth_init(); -#endif - -#if defined(DEBUG_MATRIX_SCAN_RATE) && defined(CONSOLE_ENABLE) - debug_enable = true; -#endif - - keyboard_post_init_kb(); /* Always keep this last */ -} - -/** \brief key_event_task - * - * This function is responsible for calling into other systems when they need to respond to electrical switch press events. - * This is differnet than keycode events as no layer processing, or filtering occurs. - */ -void switch_events(uint8_t row, uint8_t col, bool pressed) { -#if defined(LED_MATRIX_ENABLE) - process_led_matrix(row, col, pressed); -#endif -#if defined(RGB_MATRIX_ENABLE) - process_rgb_matrix(row, col, pressed); -#endif -} - -/** - * @brief Generates a tick event at a maximum rate of 1KHz that drives the - * internal QMK state machine. - */ -static inline void generate_tick_event(void) { - static uint16_t last_tick = 0; - const uint16_t now = timer_read(); - if (TIMER_DIFF_16(now, last_tick) != 0) { - action_exec(MAKE_TICK_EVENT); - last_tick = now; - } -} - -/** - * @brief This task scans the keyboards matrix and processes any key presses - * that occur. - * - * @return true Matrix did change - * @return false Matrix didn't change - */ -static bool matrix_task(void) { - if (!matrix_can_read()) { - generate_tick_event(); - return false; - } - - static matrix_row_t matrix_previous[MATRIX_ROWS]; - - matrix_scan(); - bool matrix_changed = false; - for (uint8_t row = 0; row < MATRIX_ROWS && !matrix_changed; row++) { - matrix_changed |= matrix_previous[row] ^ matrix_get_row(row); - } - - matrix_scan_perf_task(); - - // Short-circuit the complete matrix processing if it is not necessary - if (!matrix_changed) { - generate_tick_event(); - return matrix_changed; - } - - if (debug_config.matrix) { - matrix_print(); - } - - const bool process_keypress = should_process_keypress(); - - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - const matrix_row_t current_row = matrix_get_row(row); - const matrix_row_t row_changes = current_row ^ matrix_previous[row]; - - if (!row_changes || has_ghost_in_row(row, current_row)) { - continue; - } - - matrix_row_t col_mask = 1; - for (uint8_t col = 0; col < MATRIX_COLS; col++, col_mask <<= 1) { - if (row_changes & col_mask) { - const bool key_pressed = current_row & col_mask; - - if (process_keypress) { - action_exec(MAKE_KEYEVENT(row, col, key_pressed)); - } - - switch_events(row, col, key_pressed); - } - } - - matrix_previous[row] = current_row; - } - - return matrix_changed; -} - -/** \brief Tasks previously located in matrix_scan_quantum - * - * TODO: rationalise against keyboard_task and current split role - */ -void quantum_task(void) { -#ifdef SPLIT_KEYBOARD - // some tasks should only run on master - if (!is_keyboard_master()) return; -#endif - -#if defined(AUDIO_ENABLE) && defined(AUDIO_INIT_DELAY) - // There are some tasks that need to be run a little bit - // after keyboard startup, or else they will not work correctly - // because of interaction with the USB device state, which - // may still be in flux... - // - // At the moment the only feature that needs this is the - // startup song. - static bool delayed_tasks_run = false; - static uint16_t delayed_task_timer = 0; - if (!delayed_tasks_run) { - if (!delayed_task_timer) { - delayed_task_timer = timer_read(); - } else if (timer_elapsed(delayed_task_timer) > 300) { - audio_startup(); - delayed_tasks_run = true; - } - } -#endif - -#if defined(AUDIO_ENABLE) && !defined(NO_MUSIC_MODE) - music_task(); -#endif - -#ifdef KEY_OVERRIDE_ENABLE - key_override_task(); -#endif - -#ifdef SEQUENCER_ENABLE - sequencer_task(); -#endif - -#ifdef TAP_DANCE_ENABLE - tap_dance_task(); -#endif - -#ifdef COMBO_ENABLE - combo_task(); -#endif - -#ifdef LEADER_ENABLE - leader_task(); -#endif - -#ifdef WPM_ENABLE - decay_wpm(); -#endif - -#ifdef HAPTIC_ENABLE - haptic_task(); -#endif - -#ifdef DIP_SWITCH_ENABLE - dip_switch_read(false); -#endif - -#ifdef AUTO_SHIFT_ENABLE - autoshift_matrix_scan(); -#endif - -#ifdef CAPS_WORD_ENABLE - caps_word_task(); -#endif - -#ifdef SECURE_ENABLE - secure_task(); -#endif -} - -/** \brief Main task that is repeatedly called as fast as possible. */ -void keyboard_task(void) { - __attribute__((unused)) bool activity_has_occurred = false; - if (matrix_task()) { - last_matrix_activity_trigger(); - activity_has_occurred = true; - } - - quantum_task(); - -#if defined(SPLIT_WATCHDOG_ENABLE) - split_watchdog_task(); -#endif - -#if defined(RGBLIGHT_ENABLE) - rgblight_task(); -#endif - -#ifdef LED_MATRIX_ENABLE - led_matrix_task(); -#endif -#ifdef RGB_MATRIX_ENABLE - rgb_matrix_task(); -#endif - -#if defined(BACKLIGHT_ENABLE) -# if defined(BACKLIGHT_PIN) || defined(BACKLIGHT_PINS) - backlight_task(); -# endif -#endif - -#ifdef ENCODER_ENABLE - if (encoder_read()) { - last_encoder_activity_trigger(); - activity_has_occurred = true; - } -#endif - -#ifdef POINTING_DEVICE_ENABLE - if (pointing_device_task()) { - last_pointing_device_activity_trigger(); - activity_has_occurred = true; - } -#endif - -#ifdef OLED_ENABLE - oled_task(); -# if OLED_TIMEOUT > 0 - // Wake up oled if user is using those fabulous keys or spinning those encoders! - if (activity_has_occurred) oled_on(); -# endif -#endif - -#ifdef ST7565_ENABLE - st7565_task(); -# if ST7565_TIMEOUT > 0 - // Wake up display if user is using those fabulous keys or spinning those encoders! - if (activity_has_occurred) st7565_on(); -# endif -#endif - -#ifdef MOUSEKEY_ENABLE - // mousekey repeat & acceleration - mousekey_task(); -#endif - -#ifdef PS2_MOUSE_ENABLE - ps2_mouse_task(); -#endif - -#ifdef MIDI_ENABLE - midi_task(); -#endif - -#ifdef VELOCIKEY_ENABLE - if (velocikey_enabled()) { - velocikey_decelerate(); - } -#endif - -#ifdef JOYSTICK_ENABLE - joystick_task(); -#endif - -#ifdef BLUETOOTH_ENABLE - bluetooth_task(); -#endif - - led_task(); -} diff --git a/quantum/keyboard.h b/quantum/keyboard.h deleted file mode 100644 index bf1890d10ba6..000000000000 --- a/quantum/keyboard.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2011,2012,2013 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/* key matrix position */ -typedef struct { - uint8_t col; - uint8_t row; -} keypos_t; - -typedef enum keyevent_type_t { TICK_EVENT = 0, KEY_EVENT = 1, ENCODER_CW_EVENT = 2, ENCODER_CCW_EVENT = 3, COMBO_EVENT = 4 } keyevent_type_t; - -/* key event */ -typedef struct { - keypos_t key; - uint16_t time; - keyevent_type_t type; - bool pressed; -} keyevent_t; - -/* equivalent test of keypos_t */ -#define KEYEQ(keya, keyb) ((keya).row == (keyb).row && (keya).col == (keyb).col) - -/* special keypos_t entries */ -#define KEYLOC_ENCODER_CW 253 -#define KEYLOC_ENCODER_CCW 252 - -static inline bool IS_NOEVENT(const keyevent_t event) { - return event.type == TICK_EVENT; -} -static inline bool IS_EVENT(const keyevent_t event) { - return event.type != TICK_EVENT; -} -static inline bool IS_KEYEVENT(const keyevent_t event) { - return event.type == KEY_EVENT; -} -static inline bool IS_COMBOEVENT(const keyevent_t event) { - return event.type == COMBO_EVENT; -} -static inline bool IS_ENCODEREVENT(const keyevent_t event) { - return event.type == ENCODER_CW_EVENT || event.type == ENCODER_CCW_EVENT; -} - -/* Common keypos_t object factory */ -#define MAKE_KEYPOS(row_num, col_num) ((keypos_t){.row = (row_num), .col = (col_num)}) - -/* Common keyevent_t object factory */ -#define MAKE_EVENT(row_num, col_num, press, event_type) ((keyevent_t){.key = MAKE_KEYPOS((row_num), (col_num)), .pressed = (press), .time = timer_read(), .type = (event_type)}) - -/** - * @brief Constructs a key event for a pressed or released key. - */ -#define MAKE_KEYEVENT(row_num, col_num, press) MAKE_EVENT((row_num), (col_num), (press), KEY_EVENT) - -/** - * @brief Constructs a combo event. - */ -#define MAKE_COMBOEVENT(press) MAKE_EVENT(0, 0, (press), COMBO_EVENT) - -/** - * @brief Constructs a internal tick event that is used to drive the internal QMK state machine. - */ -#define MAKE_TICK_EVENT MAKE_EVENT(0, 0, false, TICK_EVENT) - -#ifdef ENCODER_MAP_ENABLE -/* Encoder events */ -# define MAKE_ENCODER_CW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CW, (enc_id), (press), ENCODER_CW_EVENT) -# define MAKE_ENCODER_CCW_EVENT(enc_id, press) MAKE_EVENT(KEYLOC_ENCODER_CCW, (enc_id), (press), ENCODER_CCW_EVENT) -#endif // ENCODER_MAP_ENABLE - -/* it runs once at early stage of startup before keyboard_init. */ -void keyboard_setup(void); -/* it runs once after initializing host side protocol, debug and MCU peripherals. */ -void keyboard_init(void); -/* it runs repeatedly in main loop */ -void keyboard_task(void); -/* it runs whenever code has to behave differently on a slave */ -bool is_keyboard_master(void); -/* it runs whenever code has to behave differently on left vs right split */ -bool is_keyboard_left(void); - -void keyboard_pre_init_kb(void); -void keyboard_pre_init_user(void); -void keyboard_post_init_kb(void); -void keyboard_post_init_user(void); - -void housekeeping_task(void); // To be executed by the main loop in each backend TMK protocol -void housekeeping_task_kb(void); // To be overridden by keyboard-level code -void housekeeping_task_user(void); // To be overridden by user/keymap-level code - -uint32_t last_input_activity_time(void); // Timestamp of the last matrix or encoder or pointing device activity -uint32_t last_input_activity_elapsed(void); // Number of milliseconds since the last matrix or encoder or pointing device activity - -uint32_t last_matrix_activity_time(void); // Timestamp of the last matrix activity -uint32_t last_matrix_activity_elapsed(void); // Number of milliseconds since the last matrix activity - -uint32_t last_encoder_activity_time(void); // Timestamp of the last encoder activity -uint32_t last_encoder_activity_elapsed(void); // Number of milliseconds since the last encoder activity - -uint32_t last_pointing_device_activity_time(void); // Timestamp of the last pointing device activity -uint32_t last_pointing_device_activity_elapsed(void); // Number of milliseconds since the last pointing device activity - -void set_activity_timestamps(uint32_t matrix_timestamp, uint32_t encoder_timestamp, uint32_t pointing_device_timestamp); // Set the timestamps of the last matrix and encoder activity - -uint32_t get_matrix_scan_rate(void); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/keycode.h b/quantum/keycode.h deleted file mode 100644 index df1452d2965c..000000000000 --- a/quantum/keycode.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2011,2012 Jun Wako - -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 . -*/ - -/* - * Keycodes based on HID Keyboard/Keypad Usage Page (0x07) plus media keys from Generic Desktop Page (0x01) and Consumer Page (0x0C) - * - * See https://web.archive.org/web/20060218214400/http://www.usb.org/developers/devclass_docs/Hut1_12.pdf - * or http://www.usb.org/developers/hidpage/Hut1_12v2.pdf (older) - */ - -#pragma once - -/* FIXME: Add doxygen comments here */ - -#define IS_ANY(code) (KC_A <= (code) && (code) <= 0xFF) - -#define IS_MOUSEKEY(code) IS_MOUSE_KEYCODE(code) -#define IS_MOUSEKEY_MOVE(code) (KC_MS_UP <= (code) && (code) <= KC_MS_RIGHT) -#define IS_MOUSEKEY_BUTTON(code) (KC_MS_BTN1 <= (code) && (code) <= KC_MS_BTN8) -#define IS_MOUSEKEY_WHEEL(code) (KC_MS_WH_UP <= (code) && (code) <= KC_MS_WH_RIGHT) -#define IS_MOUSEKEY_ACCEL(code) (KC_MS_ACCEL0 <= (code) && (code) <= KC_MS_ACCEL2) - -#define MOD_BIT(code) (1 << ((code)&0x07)) - -// clang-format off - -// TODO: dd keycodes -#include "keycodes.h" -#include "modifiers.h" diff --git a/quantum/keycode_config.c b/quantum/keycode_config.c deleted file mode 100644 index 9dd7097c861a..000000000000 --- a/quantum/keycode_config.c +++ /dev/null @@ -1,167 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#include "keycode_config.h" - -/** \brief keycode_config - * - * This function is used to check a specific keycode against the bootmagic config, - * and will return the corrected keycode, when appropriate. - */ -__attribute__((weak)) uint16_t keycode_config(uint16_t keycode) { - switch (keycode) { - case KC_CAPS_LOCK: - case KC_LOCKING_CAPS_LOCK: - if (keymap_config.swap_control_capslock || keymap_config.capslock_to_control) { - return KC_LEFT_CTRL; - } else if (keymap_config.swap_escape_capslock) { - return KC_ESCAPE; - } - return keycode; - case KC_LEFT_CTRL: - if (keymap_config.swap_control_capslock) { - return KC_CAPS_LOCK; - } - if (keymap_config.swap_lctl_lgui) { - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_LEFT_GUI; - } - return KC_LEFT_CTRL; - case KC_LEFT_ALT: - if (keymap_config.swap_lalt_lgui) { - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_LEFT_GUI; - } - return KC_LEFT_ALT; - case KC_LEFT_GUI: - if (keymap_config.swap_lalt_lgui) { - return KC_LEFT_ALT; - } - if (keymap_config.swap_lctl_lgui) { - return KC_LEFT_CTRL; - } - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_LEFT_GUI; - case KC_RIGHT_CTRL: - if (keymap_config.swap_rctl_rgui) { - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_RIGHT_GUI; - } - return KC_RIGHT_CTRL; - case KC_RIGHT_ALT: - if (keymap_config.swap_ralt_rgui) { - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_RIGHT_GUI; - } - return KC_RIGHT_ALT; - case KC_RIGHT_GUI: - if (keymap_config.swap_ralt_rgui) { - return KC_RIGHT_ALT; - } - if (keymap_config.swap_rctl_rgui) { - return KC_RIGHT_CTRL; - } - if (keymap_config.no_gui) { - return KC_NO; - } - return KC_RIGHT_GUI; - case KC_GRAVE: - if (keymap_config.swap_grave_esc) { - return KC_ESCAPE; - } - return KC_GRAVE; - case KC_ESCAPE: - if (keymap_config.swap_grave_esc) { - return KC_GRAVE; - } else if (keymap_config.swap_escape_capslock) { - return KC_CAPS_LOCK; - } - return KC_ESCAPE; - case KC_BACKSLASH: - if (keymap_config.swap_backslash_backspace) { - return KC_BACKSPACE; - } - return KC_BACKSLASH; - case KC_BACKSPACE: - if (keymap_config.swap_backslash_backspace) { - return KC_BACKSLASH; - } - return KC_BACKSPACE; - default: - return keycode; - } -} - -/** \brief mod_config - * - * This function checks the mods passed to it against the bootmagic config, - * and will remove or replace mods, based on that. - */ - -__attribute__((weak)) uint8_t mod_config(uint8_t mod) { - if (keymap_config.swap_lalt_lgui) { - if ((mod & MOD_RGUI) == MOD_LGUI) { - mod &= ~MOD_LGUI; - mod |= MOD_LALT; - } else if ((mod & MOD_RALT) == MOD_LALT) { - mod &= ~MOD_LALT; - mod |= MOD_LGUI; - } - } - if (keymap_config.swap_ralt_rgui) { - if ((mod & MOD_RGUI) == MOD_RGUI) { - mod &= ~MOD_RGUI; - mod |= MOD_RALT; - } else if ((mod & MOD_RALT) == MOD_RALT) { - mod &= ~MOD_RALT; - mod |= MOD_RGUI; - } - } - if (keymap_config.swap_lctl_lgui) { - if ((mod & MOD_RGUI) == MOD_LGUI) { - mod &= ~MOD_LGUI; - mod |= MOD_LCTL; - } else if ((mod & MOD_RCTL) == MOD_LCTL) { - mod &= ~MOD_LCTL; - mod |= MOD_LGUI; - } - } - if (keymap_config.swap_rctl_rgui) { - if ((mod & MOD_RGUI) == MOD_RGUI) { - mod &= ~MOD_RGUI; - mod |= MOD_RCTL; - } else if ((mod & MOD_RCTL) == MOD_RCTL) { - mod &= ~MOD_RCTL; - mod |= MOD_RGUI; - } - } - if (keymap_config.no_gui) { - mod &= ~MOD_LGUI; - mod &= ~MOD_RGUI; - } - - return mod; -} diff --git a/quantum/keycode_config.h b/quantum/keycode_config.h deleted file mode 100644 index d1352c302ea0..000000000000 --- a/quantum/keycode_config.h +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#ifdef __cplusplus -# define _Static_assert static_assert -#endif - -#include "eeconfig.h" -#include "keycode.h" -#include "action_code.h" - -uint16_t keycode_config(uint16_t keycode); -uint8_t mod_config(uint8_t mod); - -/* NOTE: Not portable. Bit field order depends on implementation */ -typedef union { - uint16_t raw; - struct { - bool swap_control_capslock : 1; - bool capslock_to_control : 1; - bool swap_lalt_lgui : 1; - bool swap_ralt_rgui : 1; - bool no_gui : 1; - bool swap_grave_esc : 1; - bool swap_backslash_backspace : 1; - bool nkro : 1; - bool swap_lctl_lgui : 1; - bool swap_rctl_rgui : 1; - bool oneshot_enable : 1; - bool swap_escape_capslock : 1; - bool autocorrect_enable : 1; - }; -} keymap_config_t; - -_Static_assert(sizeof(keymap_config_t) == sizeof(uint16_t), "Keycode (magic) EECONFIG out of spec."); - -extern keymap_config_t keymap_config; diff --git a/quantum/keycodes.h b/quantum/keycodes.h deleted file mode 100644 index bbf10da36d97..000000000000 --- a/quantum/keycodes.h +++ /dev/null @@ -1,1422 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -// clang-format off - -enum qk_keycode_ranges { -// Ranges - QK_BASIC = 0x0000, - QK_BASIC_MAX = 0x00FF, - QK_MODS = 0x0100, - QK_MODS_MAX = 0x1FFF, - QK_MOD_TAP = 0x2000, - QK_MOD_TAP_MAX = 0x3FFF, - QK_LAYER_TAP = 0x4000, - QK_LAYER_TAP_MAX = 0x4FFF, - QK_LAYER_MOD = 0x5000, - QK_LAYER_MOD_MAX = 0x51FF, - QK_TO = 0x5200, - QK_TO_MAX = 0x521F, - QK_MOMENTARY = 0x5220, - QK_MOMENTARY_MAX = 0x523F, - QK_DEF_LAYER = 0x5240, - QK_DEF_LAYER_MAX = 0x525F, - QK_TOGGLE_LAYER = 0x5260, - QK_TOGGLE_LAYER_MAX = 0x527F, - QK_ONE_SHOT_LAYER = 0x5280, - QK_ONE_SHOT_LAYER_MAX = 0x529F, - QK_ONE_SHOT_MOD = 0x52A0, - QK_ONE_SHOT_MOD_MAX = 0x52BF, - QK_LAYER_TAP_TOGGLE = 0x52C0, - QK_LAYER_TAP_TOGGLE_MAX = 0x52DF, - QK_SWAP_HANDS = 0x5600, - QK_SWAP_HANDS_MAX = 0x56FF, - QK_TAP_DANCE = 0x5700, - QK_TAP_DANCE_MAX = 0x57FF, - QK_MAGIC = 0x7000, - QK_MAGIC_MAX = 0x70FF, - QK_MIDI = 0x7100, - QK_MIDI_MAX = 0x71FF, - QK_SEQUENCER = 0x7200, - QK_SEQUENCER_MAX = 0x73FF, - QK_JOYSTICK = 0x7400, - QK_JOYSTICK_MAX = 0x743F, - QK_PROGRAMMABLE_BUTTON = 0x7440, - QK_PROGRAMMABLE_BUTTON_MAX = 0x747F, - QK_AUDIO = 0x7480, - QK_AUDIO_MAX = 0x74BF, - QK_STENO = 0x74C0, - QK_STENO_MAX = 0x74FF, - QK_MACRO = 0x7700, - QK_MACRO_MAX = 0x777F, - QK_LIGHTING = 0x7800, - QK_LIGHTING_MAX = 0x78FF, - QK_QUANTUM = 0x7C00, - QK_QUANTUM_MAX = 0x7DFF, - QK_KB = 0x7E00, - QK_KB_MAX = 0x7E3F, - QK_USER = 0x7E40, - QK_USER_MAX = 0x7FFF, - QK_UNICODEMAP = 0x8000, - QK_UNICODEMAP_MAX = 0xBFFF, - QK_UNICODE = 0x8000, - QK_UNICODE_MAX = 0xFFFF, - QK_UNICODEMAP_PAIR = 0xC000, - QK_UNICODEMAP_PAIR_MAX = 0xFFFF, -}; - -enum qk_keycode_defines { -// Keycodes - KC_NO = 0x0000, - KC_TRANSPARENT = 0x0001, - KC_A = 0x0004, - KC_B = 0x0005, - KC_C = 0x0006, - KC_D = 0x0007, - KC_E = 0x0008, - KC_F = 0x0009, - KC_G = 0x000A, - KC_H = 0x000B, - KC_I = 0x000C, - KC_J = 0x000D, - KC_K = 0x000E, - KC_L = 0x000F, - KC_M = 0x0010, - KC_N = 0x0011, - KC_O = 0x0012, - KC_P = 0x0013, - KC_Q = 0x0014, - KC_R = 0x0015, - KC_S = 0x0016, - KC_T = 0x0017, - KC_U = 0x0018, - KC_V = 0x0019, - KC_W = 0x001A, - KC_X = 0x001B, - KC_Y = 0x001C, - KC_Z = 0x001D, - KC_1 = 0x001E, - KC_2 = 0x001F, - KC_3 = 0x0020, - KC_4 = 0x0021, - KC_5 = 0x0022, - KC_6 = 0x0023, - KC_7 = 0x0024, - KC_8 = 0x0025, - KC_9 = 0x0026, - KC_0 = 0x0027, - KC_ENTER = 0x0028, - KC_ESCAPE = 0x0029, - KC_BACKSPACE = 0x002A, - KC_TAB = 0x002B, - KC_SPACE = 0x002C, - KC_MINUS = 0x002D, - KC_EQUAL = 0x002E, - KC_LEFT_BRACKET = 0x002F, - KC_RIGHT_BRACKET = 0x0030, - KC_BACKSLASH = 0x0031, - KC_NONUS_HASH = 0x0032, - KC_SEMICOLON = 0x0033, - KC_QUOTE = 0x0034, - KC_GRAVE = 0x0035, - KC_COMMA = 0x0036, - KC_DOT = 0x0037, - KC_SLASH = 0x0038, - KC_CAPS_LOCK = 0x0039, - KC_F1 = 0x003A, - KC_F2 = 0x003B, - KC_F3 = 0x003C, - KC_F4 = 0x003D, - KC_F5 = 0x003E, - KC_F6 = 0x003F, - KC_F7 = 0x0040, - KC_F8 = 0x0041, - KC_F9 = 0x0042, - KC_F10 = 0x0043, - KC_F11 = 0x0044, - KC_F12 = 0x0045, - KC_PRINT_SCREEN = 0x0046, - KC_SCROLL_LOCK = 0x0047, - KC_PAUSE = 0x0048, - KC_INSERT = 0x0049, - KC_HOME = 0x004A, - KC_PAGE_UP = 0x004B, - KC_DELETE = 0x004C, - KC_END = 0x004D, - KC_PAGE_DOWN = 0x004E, - KC_RIGHT = 0x004F, - KC_LEFT = 0x0050, - KC_DOWN = 0x0051, - KC_UP = 0x0052, - KC_NUM_LOCK = 0x0053, - KC_KP_SLASH = 0x0054, - KC_KP_ASTERISK = 0x0055, - KC_KP_MINUS = 0x0056, - KC_KP_PLUS = 0x0057, - KC_KP_ENTER = 0x0058, - KC_KP_1 = 0x0059, - KC_KP_2 = 0x005A, - KC_KP_3 = 0x005B, - KC_KP_4 = 0x005C, - KC_KP_5 = 0x005D, - KC_KP_6 = 0x005E, - KC_KP_7 = 0x005F, - KC_KP_8 = 0x0060, - KC_KP_9 = 0x0061, - KC_KP_0 = 0x0062, - KC_KP_DOT = 0x0063, - KC_NONUS_BACKSLASH = 0x0064, - KC_APPLICATION = 0x0065, - KC_KB_POWER = 0x0066, - KC_KP_EQUAL = 0x0067, - KC_F13 = 0x0068, - KC_F14 = 0x0069, - KC_F15 = 0x006A, - KC_F16 = 0x006B, - KC_F17 = 0x006C, - KC_F18 = 0x006D, - KC_F19 = 0x006E, - KC_F20 = 0x006F, - KC_F21 = 0x0070, - KC_F22 = 0x0071, - KC_F23 = 0x0072, - KC_F24 = 0x0073, - KC_EXECUTE = 0x0074, - KC_HELP = 0x0075, - KC_MENU = 0x0076, - KC_SELECT = 0x0077, - KC_STOP = 0x0078, - KC_AGAIN = 0x0079, - KC_UNDO = 0x007A, - KC_CUT = 0x007B, - KC_COPY = 0x007C, - KC_PASTE = 0x007D, - KC_FIND = 0x007E, - KC_KB_MUTE = 0x007F, - KC_KB_VOLUME_UP = 0x0080, - KC_KB_VOLUME_DOWN = 0x0081, - KC_LOCKING_CAPS_LOCK = 0x0082, - KC_LOCKING_NUM_LOCK = 0x0083, - KC_LOCKING_SCROLL_LOCK = 0x0084, - KC_KP_COMMA = 0x0085, - KC_KP_EQUAL_AS400 = 0x0086, - KC_INTERNATIONAL_1 = 0x0087, - KC_INTERNATIONAL_2 = 0x0088, - KC_INTERNATIONAL_3 = 0x0089, - KC_INTERNATIONAL_4 = 0x008A, - KC_INTERNATIONAL_5 = 0x008B, - KC_INTERNATIONAL_6 = 0x008C, - KC_INTERNATIONAL_7 = 0x008D, - KC_INTERNATIONAL_8 = 0x008E, - KC_INTERNATIONAL_9 = 0x008F, - KC_LANGUAGE_1 = 0x0090, - KC_LANGUAGE_2 = 0x0091, - KC_LANGUAGE_3 = 0x0092, - KC_LANGUAGE_4 = 0x0093, - KC_LANGUAGE_5 = 0x0094, - KC_LANGUAGE_6 = 0x0095, - KC_LANGUAGE_7 = 0x0096, - KC_LANGUAGE_8 = 0x0097, - KC_LANGUAGE_9 = 0x0098, - KC_ALTERNATE_ERASE = 0x0099, - KC_SYSTEM_REQUEST = 0x009A, - KC_CANCEL = 0x009B, - KC_CLEAR = 0x009C, - KC_PRIOR = 0x009D, - KC_RETURN = 0x009E, - KC_SEPARATOR = 0x009F, - KC_OUT = 0x00A0, - KC_OPER = 0x00A1, - KC_CLEAR_AGAIN = 0x00A2, - KC_CRSEL = 0x00A3, - KC_EXSEL = 0x00A4, - KC_SYSTEM_POWER = 0x00A5, - KC_SYSTEM_SLEEP = 0x00A6, - KC_SYSTEM_WAKE = 0x00A7, - KC_AUDIO_MUTE = 0x00A8, - KC_AUDIO_VOL_UP = 0x00A9, - KC_AUDIO_VOL_DOWN = 0x00AA, - KC_MEDIA_NEXT_TRACK = 0x00AB, - KC_MEDIA_PREV_TRACK = 0x00AC, - KC_MEDIA_STOP = 0x00AD, - KC_MEDIA_PLAY_PAUSE = 0x00AE, - KC_MEDIA_SELECT = 0x00AF, - KC_MEDIA_EJECT = 0x00B0, - KC_MAIL = 0x00B1, - KC_CALCULATOR = 0x00B2, - KC_MY_COMPUTER = 0x00B3, - KC_WWW_SEARCH = 0x00B4, - KC_WWW_HOME = 0x00B5, - KC_WWW_BACK = 0x00B6, - KC_WWW_FORWARD = 0x00B7, - KC_WWW_STOP = 0x00B8, - KC_WWW_REFRESH = 0x00B9, - KC_WWW_FAVORITES = 0x00BA, - KC_MEDIA_FAST_FORWARD = 0x00BB, - KC_MEDIA_REWIND = 0x00BC, - KC_BRIGHTNESS_UP = 0x00BD, - KC_BRIGHTNESS_DOWN = 0x00BE, - KC_CONTROL_PANEL = 0x00BF, - KC_ASSISTANT = 0x00C0, - KC_MISSION_CONTROL = 0x00C1, - KC_LAUNCHPAD = 0x00C2, - KC_MS_UP = 0x00CD, - KC_MS_DOWN = 0x00CE, - KC_MS_LEFT = 0x00CF, - KC_MS_RIGHT = 0x00D0, - KC_MS_BTN1 = 0x00D1, - KC_MS_BTN2 = 0x00D2, - KC_MS_BTN3 = 0x00D3, - KC_MS_BTN4 = 0x00D4, - KC_MS_BTN5 = 0x00D5, - KC_MS_BTN6 = 0x00D6, - KC_MS_BTN7 = 0x00D7, - KC_MS_BTN8 = 0x00D8, - KC_MS_WH_UP = 0x00D9, - KC_MS_WH_DOWN = 0x00DA, - KC_MS_WH_LEFT = 0x00DB, - KC_MS_WH_RIGHT = 0x00DC, - KC_MS_ACCEL0 = 0x00DD, - KC_MS_ACCEL1 = 0x00DE, - KC_MS_ACCEL2 = 0x00DF, - KC_LEFT_CTRL = 0x00E0, - KC_LEFT_SHIFT = 0x00E1, - KC_LEFT_ALT = 0x00E2, - KC_LEFT_GUI = 0x00E3, - KC_RIGHT_CTRL = 0x00E4, - KC_RIGHT_SHIFT = 0x00E5, - KC_RIGHT_ALT = 0x00E6, - KC_RIGHT_GUI = 0x00E7, - QK_SWAP_HANDS_TOGGLE = 0x56F0, - QK_SWAP_HANDS_TAP_TOGGLE = 0x56F1, - QK_SWAP_HANDS_MOMENTARY_ON = 0x56F2, - QK_SWAP_HANDS_MOMENTARY_OFF = 0x56F3, - QK_SWAP_HANDS_OFF = 0x56F4, - QK_SWAP_HANDS_ON = 0x56F5, - QK_SWAP_HANDS_ONE_SHOT = 0x56F6, - QK_MAGIC_SWAP_CONTROL_CAPS_LOCK = 0x7000, - QK_MAGIC_UNSWAP_CONTROL_CAPS_LOCK = 0x7001, - QK_MAGIC_TOGGLE_CONTROL_CAPS_LOCK = 0x7002, - QK_MAGIC_CAPS_LOCK_AS_CONTROL_OFF = 0x7003, - QK_MAGIC_CAPS_LOCK_AS_CONTROL_ON = 0x7004, - QK_MAGIC_SWAP_LALT_LGUI = 0x7005, - QK_MAGIC_UNSWAP_LALT_LGUI = 0x7006, - QK_MAGIC_SWAP_RALT_RGUI = 0x7007, - QK_MAGIC_UNSWAP_RALT_RGUI = 0x7008, - QK_MAGIC_GUI_ON = 0x7009, - QK_MAGIC_GUI_OFF = 0x700A, - QK_MAGIC_TOGGLE_GUI = 0x700B, - QK_MAGIC_SWAP_GRAVE_ESC = 0x700C, - QK_MAGIC_UNSWAP_GRAVE_ESC = 0x700D, - QK_MAGIC_SWAP_BACKSLASH_BACKSPACE = 0x700E, - QK_MAGIC_UNSWAP_BACKSLASH_BACKSPACE = 0x700F, - QK_MAGIC_TOGGLE_BACKSLASH_BACKSPACE = 0x7010, - QK_MAGIC_NKRO_ON = 0x7011, - QK_MAGIC_NKRO_OFF = 0x7012, - QK_MAGIC_TOGGLE_NKRO = 0x7013, - QK_MAGIC_SWAP_ALT_GUI = 0x7014, - QK_MAGIC_UNSWAP_ALT_GUI = 0x7015, - QK_MAGIC_TOGGLE_ALT_GUI = 0x7016, - QK_MAGIC_SWAP_LCTL_LGUI = 0x7017, - QK_MAGIC_UNSWAP_LCTL_LGUI = 0x7018, - QK_MAGIC_SWAP_RCTL_RGUI = 0x7019, - QK_MAGIC_UNSWAP_RCTL_RGUI = 0x701A, - QK_MAGIC_SWAP_CTL_GUI = 0x701B, - QK_MAGIC_UNSWAP_CTL_GUI = 0x701C, - QK_MAGIC_TOGGLE_CTL_GUI = 0x701D, - QK_MAGIC_EE_HANDS_LEFT = 0x701E, - QK_MAGIC_EE_HANDS_RIGHT = 0x701F, - QK_MAGIC_SWAP_ESCAPE_CAPS_LOCK = 0x7020, - QK_MAGIC_UNSWAP_ESCAPE_CAPS_LOCK = 0x7021, - QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK = 0x7022, - QK_MIDI_ON = 0x7100, - QK_MIDI_OFF = 0x7101, - QK_MIDI_TOGGLE = 0x7102, - QK_MIDI_NOTE_C_0 = 0x7103, - QK_MIDI_NOTE_C_SHARP_0 = 0x7104, - QK_MIDI_NOTE_D_0 = 0x7105, - QK_MIDI_NOTE_D_SHARP_0 = 0x7106, - QK_MIDI_NOTE_E_0 = 0x7107, - QK_MIDI_NOTE_F_0 = 0x7108, - QK_MIDI_NOTE_F_SHARP_0 = 0x7109, - QK_MIDI_NOTE_G_0 = 0x710A, - QK_MIDI_NOTE_G_SHARP_0 = 0x710B, - QK_MIDI_NOTE_A_0 = 0x710C, - QK_MIDI_NOTE_A_SHARP_0 = 0x710D, - QK_MIDI_NOTE_B_0 = 0x710E, - QK_MIDI_NOTE_C_1 = 0x710F, - QK_MIDI_NOTE_C_SHARP_1 = 0x7110, - QK_MIDI_NOTE_D_1 = 0x7111, - QK_MIDI_NOTE_D_SHARP_1 = 0x7112, - QK_MIDI_NOTE_E_1 = 0x7113, - QK_MIDI_NOTE_F_1 = 0x7114, - QK_MIDI_NOTE_F_SHARP_1 = 0x7115, - QK_MIDI_NOTE_G_1 = 0x7116, - QK_MIDI_NOTE_G_SHARP_1 = 0x7117, - QK_MIDI_NOTE_A_1 = 0x7118, - QK_MIDI_NOTE_A_SHARP_1 = 0x7119, - QK_MIDI_NOTE_B_1 = 0x711A, - QK_MIDI_NOTE_C_2 = 0x711B, - QK_MIDI_NOTE_C_SHARP_2 = 0x711C, - QK_MIDI_NOTE_D_2 = 0x711D, - QK_MIDI_NOTE_D_SHARP_2 = 0x711E, - QK_MIDI_NOTE_E_2 = 0x711F, - QK_MIDI_NOTE_F_2 = 0x7120, - QK_MIDI_NOTE_F_SHARP_2 = 0x7121, - QK_MIDI_NOTE_G_2 = 0x7122, - QK_MIDI_NOTE_G_SHARP_2 = 0x7123, - QK_MIDI_NOTE_A_2 = 0x7124, - QK_MIDI_NOTE_A_SHARP_2 = 0x7125, - QK_MIDI_NOTE_B_2 = 0x7126, - QK_MIDI_NOTE_C_3 = 0x7127, - QK_MIDI_NOTE_C_SHARP_3 = 0x7128, - QK_MIDI_NOTE_D_3 = 0x7129, - QK_MIDI_NOTE_D_SHARP_3 = 0x712A, - QK_MIDI_NOTE_E_3 = 0x712B, - QK_MIDI_NOTE_F_3 = 0x712C, - QK_MIDI_NOTE_F_SHARP_3 = 0x712D, - QK_MIDI_NOTE_G_3 = 0x712E, - QK_MIDI_NOTE_G_SHARP_3 = 0x712F, - QK_MIDI_NOTE_A_3 = 0x7130, - QK_MIDI_NOTE_A_SHARP_3 = 0x7131, - QK_MIDI_NOTE_B_3 = 0x7132, - QK_MIDI_NOTE_C_4 = 0x7133, - QK_MIDI_NOTE_C_SHARP_4 = 0x7134, - QK_MIDI_NOTE_D_4 = 0x7135, - QK_MIDI_NOTE_D_SHARP_4 = 0x7136, - QK_MIDI_NOTE_E_4 = 0x7137, - QK_MIDI_NOTE_F_4 = 0x7138, - QK_MIDI_NOTE_F_SHARP_4 = 0x7139, - QK_MIDI_NOTE_G_4 = 0x713A, - QK_MIDI_NOTE_G_SHARP_4 = 0x713B, - QK_MIDI_NOTE_A_4 = 0x713C, - QK_MIDI_NOTE_A_SHARP_4 = 0x713D, - QK_MIDI_NOTE_B_4 = 0x713E, - QK_MIDI_NOTE_C_5 = 0x713F, - QK_MIDI_NOTE_C_SHARP_5 = 0x7140, - QK_MIDI_NOTE_D_5 = 0x7141, - QK_MIDI_NOTE_D_SHARP_5 = 0x7142, - QK_MIDI_NOTE_E_5 = 0x7143, - QK_MIDI_NOTE_F_5 = 0x7144, - QK_MIDI_NOTE_F_SHARP_5 = 0x7145, - QK_MIDI_NOTE_G_5 = 0x7146, - QK_MIDI_NOTE_G_SHARP_5 = 0x7147, - QK_MIDI_NOTE_A_5 = 0x7148, - QK_MIDI_NOTE_A_SHARP_5 = 0x7149, - QK_MIDI_NOTE_B_5 = 0x714A, - QK_MIDI_OCTAVE_N2 = 0x714B, - QK_MIDI_OCTAVE_N1 = 0x714C, - QK_MIDI_OCTAVE_0 = 0x714D, - QK_MIDI_OCTAVE_1 = 0x714E, - QK_MIDI_OCTAVE_2 = 0x714F, - QK_MIDI_OCTAVE_3 = 0x7150, - QK_MIDI_OCTAVE_4 = 0x7151, - QK_MIDI_OCTAVE_5 = 0x7152, - QK_MIDI_OCTAVE_6 = 0x7153, - QK_MIDI_OCTAVE_7 = 0x7154, - QK_MIDI_OCTAVE_DOWN = 0x7155, - QK_MIDI_OCTAVE_UP = 0x7156, - QK_MIDI_TRANSPOSE_N6 = 0x7157, - QK_MIDI_TRANSPOSE_N5 = 0x7158, - QK_MIDI_TRANSPOSE_N4 = 0x7159, - QK_MIDI_TRANSPOSE_N3 = 0x715A, - QK_MIDI_TRANSPOSE_N2 = 0x715B, - QK_MIDI_TRANSPOSE_N1 = 0x715C, - QK_MIDI_TRANSPOSE_0 = 0x715D, - QK_MIDI_TRANSPOSE_1 = 0x715E, - QK_MIDI_TRANSPOSE_2 = 0x715F, - QK_MIDI_TRANSPOSE_3 = 0x7160, - QK_MIDI_TRANSPOSE_4 = 0x7161, - QK_MIDI_TRANSPOSE_5 = 0x7162, - QK_MIDI_TRANSPOSE_6 = 0x7163, - QK_MIDI_TRANSPOSE_DOWN = 0x7164, - QK_MIDI_TRANSPOSE_UP = 0x7165, - QK_MIDI_VELOCITY_0 = 0x7166, - QK_MIDI_VELOCITY_1 = 0x7167, - QK_MIDI_VELOCITY_2 = 0x7168, - QK_MIDI_VELOCITY_3 = 0x7169, - QK_MIDI_VELOCITY_4 = 0x716A, - QK_MIDI_VELOCITY_5 = 0x716B, - QK_MIDI_VELOCITY_6 = 0x716C, - QK_MIDI_VELOCITY_7 = 0x716D, - QK_MIDI_VELOCITY_8 = 0x716E, - QK_MIDI_VELOCITY_9 = 0x716F, - QK_MIDI_VELOCITY_10 = 0x7170, - QK_MIDI_VELOCITY_DOWN = 0x7171, - QK_MIDI_VELOCITY_UP = 0x7172, - QK_MIDI_CHANNEL_1 = 0x7173, - QK_MIDI_CHANNEL_2 = 0x7174, - QK_MIDI_CHANNEL_3 = 0x7175, - QK_MIDI_CHANNEL_4 = 0x7176, - QK_MIDI_CHANNEL_5 = 0x7177, - QK_MIDI_CHANNEL_6 = 0x7178, - QK_MIDI_CHANNEL_7 = 0x7179, - QK_MIDI_CHANNEL_8 = 0x717A, - QK_MIDI_CHANNEL_9 = 0x717B, - QK_MIDI_CHANNEL_10 = 0x717C, - QK_MIDI_CHANNEL_11 = 0x717D, - QK_MIDI_CHANNEL_12 = 0x717E, - QK_MIDI_CHANNEL_13 = 0x717F, - QK_MIDI_CHANNEL_14 = 0x7180, - QK_MIDI_CHANNEL_15 = 0x7181, - QK_MIDI_CHANNEL_16 = 0x7182, - QK_MIDI_CHANNEL_DOWN = 0x7183, - QK_MIDI_CHANNEL_UP = 0x7184, - QK_MIDI_ALL_NOTES_OFF = 0x7185, - QK_MIDI_SUSTAIN = 0x7186, - QK_MIDI_PORTAMENTO = 0x7187, - QK_MIDI_SOSTENUTO = 0x7188, - QK_MIDI_SOFT = 0x7189, - QK_MIDI_LEGATO = 0x718A, - QK_MIDI_MODULATION = 0x718B, - QK_MIDI_MODULATION_SPEED_DOWN = 0x718C, - QK_MIDI_MODULATION_SPEED_UP = 0x718D, - QK_MIDI_PITCH_BEND_DOWN = 0x718E, - QK_MIDI_PITCH_BEND_UP = 0x718F, - QK_SEQUENCER_ON = 0x7200, - QK_SEQUENCER_OFF = 0x7201, - QK_SEQUENCER_TOGGLE = 0x7202, - QK_SEQUENCER_TEMPO_DOWN = 0x7203, - QK_SEQUENCER_TEMPO_UP = 0x7204, - QK_SEQUENCER_RESOLUTION_DOWN = 0x7205, - QK_SEQUENCER_RESOLUTION_UP = 0x7206, - QK_SEQUENCER_STEPS_ALL = 0x7207, - QK_SEQUENCER_STEPS_CLEAR = 0x7208, - QK_JOYSTICK_BUTTON_0 = 0x7400, - QK_JOYSTICK_BUTTON_1 = 0x7401, - QK_JOYSTICK_BUTTON_2 = 0x7402, - QK_JOYSTICK_BUTTON_3 = 0x7403, - QK_JOYSTICK_BUTTON_4 = 0x7404, - QK_JOYSTICK_BUTTON_5 = 0x7405, - QK_JOYSTICK_BUTTON_6 = 0x7406, - QK_JOYSTICK_BUTTON_7 = 0x7407, - QK_JOYSTICK_BUTTON_8 = 0x7408, - QK_JOYSTICK_BUTTON_9 = 0x7409, - QK_JOYSTICK_BUTTON_10 = 0x740A, - QK_JOYSTICK_BUTTON_11 = 0x740B, - QK_JOYSTICK_BUTTON_12 = 0x740C, - QK_JOYSTICK_BUTTON_13 = 0x740D, - QK_JOYSTICK_BUTTON_14 = 0x740E, - QK_JOYSTICK_BUTTON_15 = 0x740F, - QK_JOYSTICK_BUTTON_16 = 0x7410, - QK_JOYSTICK_BUTTON_17 = 0x7411, - QK_JOYSTICK_BUTTON_18 = 0x7412, - QK_JOYSTICK_BUTTON_19 = 0x7413, - QK_JOYSTICK_BUTTON_20 = 0x7414, - QK_JOYSTICK_BUTTON_21 = 0x7415, - QK_JOYSTICK_BUTTON_22 = 0x7416, - QK_JOYSTICK_BUTTON_23 = 0x7417, - QK_JOYSTICK_BUTTON_24 = 0x7418, - QK_JOYSTICK_BUTTON_25 = 0x7419, - QK_JOYSTICK_BUTTON_26 = 0x741A, - QK_JOYSTICK_BUTTON_27 = 0x741B, - QK_JOYSTICK_BUTTON_28 = 0x741C, - QK_JOYSTICK_BUTTON_29 = 0x741D, - QK_JOYSTICK_BUTTON_30 = 0x741E, - QK_JOYSTICK_BUTTON_31 = 0x741F, - QK_PROGRAMMABLE_BUTTON_1 = 0x7440, - QK_PROGRAMMABLE_BUTTON_2 = 0x7441, - QK_PROGRAMMABLE_BUTTON_3 = 0x7442, - QK_PROGRAMMABLE_BUTTON_4 = 0x7443, - QK_PROGRAMMABLE_BUTTON_5 = 0x7444, - QK_PROGRAMMABLE_BUTTON_6 = 0x7445, - QK_PROGRAMMABLE_BUTTON_7 = 0x7446, - QK_PROGRAMMABLE_BUTTON_8 = 0x7447, - QK_PROGRAMMABLE_BUTTON_9 = 0x7448, - QK_PROGRAMMABLE_BUTTON_10 = 0x7449, - QK_PROGRAMMABLE_BUTTON_11 = 0x744A, - QK_PROGRAMMABLE_BUTTON_12 = 0x744B, - QK_PROGRAMMABLE_BUTTON_13 = 0x744C, - QK_PROGRAMMABLE_BUTTON_14 = 0x744D, - QK_PROGRAMMABLE_BUTTON_15 = 0x744E, - QK_PROGRAMMABLE_BUTTON_16 = 0x744F, - QK_PROGRAMMABLE_BUTTON_17 = 0x7450, - QK_PROGRAMMABLE_BUTTON_18 = 0x7451, - QK_PROGRAMMABLE_BUTTON_19 = 0x7452, - QK_PROGRAMMABLE_BUTTON_20 = 0x7453, - QK_PROGRAMMABLE_BUTTON_21 = 0x7454, - QK_PROGRAMMABLE_BUTTON_22 = 0x7455, - QK_PROGRAMMABLE_BUTTON_23 = 0x7456, - QK_PROGRAMMABLE_BUTTON_24 = 0x7457, - QK_PROGRAMMABLE_BUTTON_25 = 0x7458, - QK_PROGRAMMABLE_BUTTON_26 = 0x7459, - QK_PROGRAMMABLE_BUTTON_27 = 0x745A, - QK_PROGRAMMABLE_BUTTON_28 = 0x745B, - QK_PROGRAMMABLE_BUTTON_29 = 0x745C, - QK_PROGRAMMABLE_BUTTON_30 = 0x745D, - QK_PROGRAMMABLE_BUTTON_31 = 0x745E, - QK_PROGRAMMABLE_BUTTON_32 = 0x745F, - QK_AUDIO_ON = 0x7480, - QK_AUDIO_OFF = 0x7481, - QK_AUDIO_TOGGLE = 0x7482, - QK_AUDIO_CLICKY_TOGGLE = 0x748A, - QK_AUDIO_CLICKY_ON = 0x748B, - QK_AUDIO_CLICKY_OFF = 0x748C, - QK_AUDIO_CLICKY_UP = 0x748D, - QK_AUDIO_CLICKY_DOWN = 0x748E, - QK_AUDIO_CLICKY_RESET = 0x748F, - QK_MUSIC_ON = 0x7490, - QK_MUSIC_OFF = 0x7491, - QK_MUSIC_TOGGLE = 0x7492, - QK_MUSIC_MODE_NEXT = 0x7493, - QK_AUDIO_VOICE_NEXT = 0x7494, - QK_AUDIO_VOICE_PREVIOUS = 0x7495, - QK_STENO_BOLT = 0x74F0, - QK_STENO_GEMINI = 0x74F1, - QK_STENO_COMB = 0x74F2, - QK_STENO_COMB_MAX = 0x74FC, - QK_MACRO_0 = 0x7700, - QK_MACRO_1 = 0x7701, - QK_MACRO_2 = 0x7702, - QK_MACRO_3 = 0x7703, - QK_MACRO_4 = 0x7704, - QK_MACRO_5 = 0x7705, - QK_MACRO_6 = 0x7706, - QK_MACRO_7 = 0x7707, - QK_MACRO_8 = 0x7708, - QK_MACRO_9 = 0x7709, - QK_MACRO_10 = 0x770A, - QK_MACRO_11 = 0x770B, - QK_MACRO_12 = 0x770C, - QK_MACRO_13 = 0x770D, - QK_MACRO_14 = 0x770E, - QK_MACRO_15 = 0x770F, - QK_MACRO_16 = 0x7710, - QK_MACRO_17 = 0x7711, - QK_MACRO_18 = 0x7712, - QK_MACRO_19 = 0x7713, - QK_MACRO_20 = 0x7714, - QK_MACRO_21 = 0x7715, - QK_MACRO_22 = 0x7716, - QK_MACRO_23 = 0x7717, - QK_MACRO_24 = 0x7718, - QK_MACRO_25 = 0x7719, - QK_MACRO_26 = 0x771A, - QK_MACRO_27 = 0x771B, - QK_MACRO_28 = 0x771C, - QK_MACRO_29 = 0x771D, - QK_MACRO_30 = 0x771E, - QK_MACRO_31 = 0x771F, - QK_BACKLIGHT_ON = 0x7800, - QK_BACKLIGHT_OFF = 0x7801, - QK_BACKLIGHT_TOGGLE = 0x7802, - QK_BACKLIGHT_DOWN = 0x7803, - QK_BACKLIGHT_UP = 0x7804, - QK_BACKLIGHT_STEP = 0x7805, - QK_BACKLIGHT_TOGGLE_BREATHING = 0x7806, - RGB_TOG = 0x7820, - RGB_MODE_FORWARD = 0x7821, - RGB_MODE_REVERSE = 0x7822, - RGB_HUI = 0x7823, - RGB_HUD = 0x7824, - RGB_SAI = 0x7825, - RGB_SAD = 0x7826, - RGB_VAI = 0x7827, - RGB_VAD = 0x7828, - RGB_SPI = 0x7829, - RGB_SPD = 0x782A, - RGB_MODE_PLAIN = 0x782B, - RGB_MODE_BREATHE = 0x782C, - RGB_MODE_RAINBOW = 0x782D, - RGB_MODE_SWIRL = 0x782E, - RGB_MODE_SNAKE = 0x782F, - RGB_MODE_KNIGHT = 0x7830, - RGB_MODE_XMAS = 0x7831, - RGB_MODE_GRADIENT = 0x7832, - RGB_MODE_RGBTEST = 0x7833, - RGB_MODE_TWINKLE = 0x7834, - QK_BOOTLOADER = 0x7C00, - QK_REBOOT = 0x7C01, - QK_DEBUG_TOGGLE = 0x7C02, - QK_CLEAR_EEPROM = 0x7C03, - QK_MAKE = 0x7C04, - QK_AUTO_SHIFT_DOWN = 0x7C10, - QK_AUTO_SHIFT_UP = 0x7C11, - QK_AUTO_SHIFT_REPORT = 0x7C12, - QK_AUTO_SHIFT_ON = 0x7C13, - QK_AUTO_SHIFT_OFF = 0x7C14, - QK_AUTO_SHIFT_TOGGLE = 0x7C15, - QK_GRAVE_ESCAPE = 0x7C16, - QK_VELOCIKEY_TOGGLE = 0x7C17, - QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN = 0x7C18, - QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE = 0x7C19, - QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN = 0x7C1A, - QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE = 0x7C1B, - QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN = 0x7C1C, - QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE = 0x7C1D, - QK_SPACE_CADET_RIGHT_SHIFT_ENTER = 0x7C1E, - QK_OUTPUT_AUTO = 0x7C20, - QK_OUTPUT_USB = 0x7C21, - QK_OUTPUT_BLUETOOTH = 0x7C22, - QK_UNICODE_MODE_NEXT = 0x7C30, - QK_UNICODE_MODE_PREVIOUS = 0x7C31, - QK_UNICODE_MODE_MACOS = 0x7C32, - QK_UNICODE_MODE_LINUX = 0x7C33, - QK_UNICODE_MODE_WINDOWS = 0x7C34, - QK_UNICODE_MODE_BSD = 0x7C35, - QK_UNICODE_MODE_WINCOMPOSE = 0x7C36, - QK_UNICODE_MODE_EMACS = 0x7C37, - QK_HAPTIC_ON = 0x7C40, - QK_HAPTIC_OFF = 0x7C41, - QK_HAPTIC_TOGGLE = 0x7C42, - QK_HAPTIC_RESET = 0x7C43, - QK_HAPTIC_FEEDBACK_TOGGLE = 0x7C44, - QK_HAPTIC_BUZZ_TOGGLE = 0x7C45, - QK_HAPTIC_MODE_NEXT = 0x7C46, - QK_HAPTIC_MODE_PREVIOUS = 0x7C47, - QK_HAPTIC_CONTINUOUS_TOGGLE = 0x7C48, - QK_HAPTIC_CONTINUOUS_UP = 0x7C49, - QK_HAPTIC_CONTINUOUS_DOWN = 0x7C4A, - QK_HAPTIC_DWELL_UP = 0x7C4B, - QK_HAPTIC_DWELL_DOWN = 0x7C4C, - QK_COMBO_ON = 0x7C50, - QK_COMBO_OFF = 0x7C51, - QK_COMBO_TOGGLE = 0x7C52, - QK_DYNAMIC_MACRO_RECORD_START_1 = 0x7C53, - QK_DYNAMIC_MACRO_RECORD_START_2 = 0x7C54, - QK_DYNAMIC_MACRO_RECORD_STOP = 0x7C55, - QK_DYNAMIC_MACRO_PLAY_1 = 0x7C56, - QK_DYNAMIC_MACRO_PLAY_2 = 0x7C57, - QK_LEADER = 0x7C58, - QK_LOCK = 0x7C59, - QK_ONE_SHOT_ON = 0x7C5A, - QK_ONE_SHOT_OFF = 0x7C5B, - QK_ONE_SHOT_TOGGLE = 0x7C5C, - QK_KEY_OVERRIDE_TOGGLE = 0x7C5D, - QK_KEY_OVERRIDE_ON = 0x7C5E, - QK_KEY_OVERRIDE_OFF = 0x7C5F, - QK_SECURE_LOCK = 0x7C60, - QK_SECURE_UNLOCK = 0x7C61, - QK_SECURE_TOGGLE = 0x7C62, - QK_SECURE_REQUEST = 0x7C63, - QK_DYNAMIC_TAPPING_TERM_PRINT = 0x7C70, - QK_DYNAMIC_TAPPING_TERM_UP = 0x7C71, - QK_DYNAMIC_TAPPING_TERM_DOWN = 0x7C72, - QK_CAPS_WORD_TOGGLE = 0x7C73, - QK_AUTOCORRECT_ON = 0x7C74, - QK_AUTOCORRECT_OFF = 0x7C75, - QK_AUTOCORRECT_TOGGLE = 0x7C76, - QK_TRI_LAYER_LOWER = 0x7C77, - QK_TRI_LAYER_UPPER = 0x7C78, - QK_REPEAT_KEY = 0x7C79, - QK_ALT_REPEAT_KEY = 0x7C7A, - QK_KB_0 = 0x7E00, - QK_KB_1 = 0x7E01, - QK_KB_2 = 0x7E02, - QK_KB_3 = 0x7E03, - QK_KB_4 = 0x7E04, - QK_KB_5 = 0x7E05, - QK_KB_6 = 0x7E06, - QK_KB_7 = 0x7E07, - QK_KB_8 = 0x7E08, - QK_KB_9 = 0x7E09, - QK_KB_10 = 0x7E0A, - QK_KB_11 = 0x7E0B, - QK_KB_12 = 0x7E0C, - QK_KB_13 = 0x7E0D, - QK_KB_14 = 0x7E0E, - QK_KB_15 = 0x7E0F, - QK_KB_16 = 0x7E10, - QK_KB_17 = 0x7E11, - QK_KB_18 = 0x7E12, - QK_KB_19 = 0x7E13, - QK_KB_20 = 0x7E14, - QK_KB_21 = 0x7E15, - QK_KB_22 = 0x7E16, - QK_KB_23 = 0x7E17, - QK_KB_24 = 0x7E18, - QK_KB_25 = 0x7E19, - QK_KB_26 = 0x7E1A, - QK_KB_27 = 0x7E1B, - QK_KB_28 = 0x7E1C, - QK_KB_29 = 0x7E1D, - QK_KB_30 = 0x7E1E, - QK_KB_31 = 0x7E1F, - QK_USER_0 = 0x7E40, - QK_USER_1 = 0x7E41, - QK_USER_2 = 0x7E42, - QK_USER_3 = 0x7E43, - QK_USER_4 = 0x7E44, - QK_USER_5 = 0x7E45, - QK_USER_6 = 0x7E46, - QK_USER_7 = 0x7E47, - QK_USER_8 = 0x7E48, - QK_USER_9 = 0x7E49, - QK_USER_10 = 0x7E4A, - QK_USER_11 = 0x7E4B, - QK_USER_12 = 0x7E4C, - QK_USER_13 = 0x7E4D, - QK_USER_14 = 0x7E4E, - QK_USER_15 = 0x7E4F, - QK_USER_16 = 0x7E50, - QK_USER_17 = 0x7E51, - QK_USER_18 = 0x7E52, - QK_USER_19 = 0x7E53, - QK_USER_20 = 0x7E54, - QK_USER_21 = 0x7E55, - QK_USER_22 = 0x7E56, - QK_USER_23 = 0x7E57, - QK_USER_24 = 0x7E58, - QK_USER_25 = 0x7E59, - QK_USER_26 = 0x7E5A, - QK_USER_27 = 0x7E5B, - QK_USER_28 = 0x7E5C, - QK_USER_29 = 0x7E5D, - QK_USER_30 = 0x7E5E, - QK_USER_31 = 0x7E5F, - -// Alias - XXXXXXX = KC_NO, - _______ = KC_TRANSPARENT, - KC_TRNS = KC_TRANSPARENT, - KC_ENT = KC_ENTER, - KC_ESC = KC_ESCAPE, - KC_BSPC = KC_BACKSPACE, - KC_SPC = KC_SPACE, - KC_MINS = KC_MINUS, - KC_EQL = KC_EQUAL, - KC_LBRC = KC_LEFT_BRACKET, - KC_RBRC = KC_RIGHT_BRACKET, - KC_BSLS = KC_BACKSLASH, - KC_NUHS = KC_NONUS_HASH, - KC_SCLN = KC_SEMICOLON, - KC_QUOT = KC_QUOTE, - KC_GRV = KC_GRAVE, - KC_COMM = KC_COMMA, - KC_SLSH = KC_SLASH, - KC_CAPS = KC_CAPS_LOCK, - KC_PSCR = KC_PRINT_SCREEN, - KC_SCRL = KC_SCROLL_LOCK, - KC_BRMD = KC_SCROLL_LOCK, - KC_PAUS = KC_PAUSE, - KC_BRK = KC_PAUSE, - KC_BRMU = KC_PAUSE, - KC_INS = KC_INSERT, - KC_PGUP = KC_PAGE_UP, - KC_DEL = KC_DELETE, - KC_PGDN = KC_PAGE_DOWN, - KC_RGHT = KC_RIGHT, - KC_NUM = KC_NUM_LOCK, - KC_PSLS = KC_KP_SLASH, - KC_PAST = KC_KP_ASTERISK, - KC_PMNS = KC_KP_MINUS, - KC_PPLS = KC_KP_PLUS, - KC_PENT = KC_KP_ENTER, - KC_P1 = KC_KP_1, - KC_P2 = KC_KP_2, - KC_P3 = KC_KP_3, - KC_P4 = KC_KP_4, - KC_P5 = KC_KP_5, - KC_P6 = KC_KP_6, - KC_P7 = KC_KP_7, - KC_P8 = KC_KP_8, - KC_P9 = KC_KP_9, - KC_P0 = KC_KP_0, - KC_PDOT = KC_KP_DOT, - KC_NUBS = KC_NONUS_BACKSLASH, - KC_APP = KC_APPLICATION, - KC_PEQL = KC_KP_EQUAL, - KC_EXEC = KC_EXECUTE, - KC_SLCT = KC_SELECT, - KC_AGIN = KC_AGAIN, - KC_PSTE = KC_PASTE, - KC_LCAP = KC_LOCKING_CAPS_LOCK, - KC_LNUM = KC_LOCKING_NUM_LOCK, - KC_LSCR = KC_LOCKING_SCROLL_LOCK, - KC_PCMM = KC_KP_COMMA, - KC_INT1 = KC_INTERNATIONAL_1, - KC_INT2 = KC_INTERNATIONAL_2, - KC_INT3 = KC_INTERNATIONAL_3, - KC_INT4 = KC_INTERNATIONAL_4, - KC_INT5 = KC_INTERNATIONAL_5, - KC_INT6 = KC_INTERNATIONAL_6, - KC_INT7 = KC_INTERNATIONAL_7, - KC_INT8 = KC_INTERNATIONAL_8, - KC_INT9 = KC_INTERNATIONAL_9, - KC_LNG1 = KC_LANGUAGE_1, - KC_LNG2 = KC_LANGUAGE_2, - KC_LNG3 = KC_LANGUAGE_3, - KC_LNG4 = KC_LANGUAGE_4, - KC_LNG5 = KC_LANGUAGE_5, - KC_LNG6 = KC_LANGUAGE_6, - KC_LNG7 = KC_LANGUAGE_7, - KC_LNG8 = KC_LANGUAGE_8, - KC_LNG9 = KC_LANGUAGE_9, - KC_ERAS = KC_ALTERNATE_ERASE, - KC_SYRQ = KC_SYSTEM_REQUEST, - KC_CNCL = KC_CANCEL, - KC_CLR = KC_CLEAR, - KC_PRIR = KC_PRIOR, - KC_RETN = KC_RETURN, - KC_SEPR = KC_SEPARATOR, - KC_CLAG = KC_CLEAR_AGAIN, - KC_CRSL = KC_CRSEL, - KC_EXSL = KC_EXSEL, - KC_PWR = KC_SYSTEM_POWER, - KC_SLEP = KC_SYSTEM_SLEEP, - KC_WAKE = KC_SYSTEM_WAKE, - KC_MUTE = KC_AUDIO_MUTE, - KC_VOLU = KC_AUDIO_VOL_UP, - KC_VOLD = KC_AUDIO_VOL_DOWN, - KC_MNXT = KC_MEDIA_NEXT_TRACK, - KC_MPRV = KC_MEDIA_PREV_TRACK, - KC_MSTP = KC_MEDIA_STOP, - KC_MPLY = KC_MEDIA_PLAY_PAUSE, - KC_MSEL = KC_MEDIA_SELECT, - KC_EJCT = KC_MEDIA_EJECT, - KC_CALC = KC_CALCULATOR, - KC_MYCM = KC_MY_COMPUTER, - KC_WSCH = KC_WWW_SEARCH, - KC_WHOM = KC_WWW_HOME, - KC_WBAK = KC_WWW_BACK, - KC_WFWD = KC_WWW_FORWARD, - KC_WSTP = KC_WWW_STOP, - KC_WREF = KC_WWW_REFRESH, - KC_WFAV = KC_WWW_FAVORITES, - KC_MFFD = KC_MEDIA_FAST_FORWARD, - KC_MRWD = KC_MEDIA_REWIND, - KC_BRIU = KC_BRIGHTNESS_UP, - KC_BRID = KC_BRIGHTNESS_DOWN, - KC_CPNL = KC_CONTROL_PANEL, - KC_ASST = KC_ASSISTANT, - KC_MCTL = KC_MISSION_CONTROL, - KC_LPAD = KC_LAUNCHPAD, - KC_MS_U = KC_MS_UP, - KC_MS_D = KC_MS_DOWN, - KC_MS_L = KC_MS_LEFT, - KC_MS_R = KC_MS_RIGHT, - KC_BTN1 = KC_MS_BTN1, - KC_BTN2 = KC_MS_BTN2, - KC_BTN3 = KC_MS_BTN3, - KC_BTN4 = KC_MS_BTN4, - KC_BTN5 = KC_MS_BTN5, - KC_BTN6 = KC_MS_BTN6, - KC_BTN7 = KC_MS_BTN7, - KC_BTN8 = KC_MS_BTN8, - KC_WH_U = KC_MS_WH_UP, - KC_WH_D = KC_MS_WH_DOWN, - KC_WH_L = KC_MS_WH_LEFT, - KC_WH_R = KC_MS_WH_RIGHT, - KC_ACL0 = KC_MS_ACCEL0, - KC_ACL1 = KC_MS_ACCEL1, - KC_ACL2 = KC_MS_ACCEL2, - KC_LCTL = KC_LEFT_CTRL, - KC_LSFT = KC_LEFT_SHIFT, - KC_LALT = KC_LEFT_ALT, - KC_LOPT = KC_LEFT_ALT, - KC_LGUI = KC_LEFT_GUI, - KC_LCMD = KC_LEFT_GUI, - KC_LWIN = KC_LEFT_GUI, - KC_RCTL = KC_RIGHT_CTRL, - KC_RSFT = KC_RIGHT_SHIFT, - KC_RALT = KC_RIGHT_ALT, - KC_ROPT = KC_RIGHT_ALT, - KC_ALGR = KC_RIGHT_ALT, - KC_RGUI = KC_RIGHT_GUI, - KC_RCMD = KC_RIGHT_GUI, - KC_RWIN = KC_RIGHT_GUI, - SH_TOGG = QK_SWAP_HANDS_TOGGLE, - SH_TT = QK_SWAP_HANDS_TAP_TOGGLE, - SH_MON = QK_SWAP_HANDS_MOMENTARY_ON, - SH_MOFF = QK_SWAP_HANDS_MOMENTARY_OFF, - SH_OFF = QK_SWAP_HANDS_OFF, - SH_ON = QK_SWAP_HANDS_ON, - SH_OS = QK_SWAP_HANDS_ONE_SHOT, - CL_SWAP = QK_MAGIC_SWAP_CONTROL_CAPS_LOCK, - CL_NORM = QK_MAGIC_UNSWAP_CONTROL_CAPS_LOCK, - CL_TOGG = QK_MAGIC_TOGGLE_CONTROL_CAPS_LOCK, - CL_CAPS = QK_MAGIC_CAPS_LOCK_AS_CONTROL_OFF, - CL_CTRL = QK_MAGIC_CAPS_LOCK_AS_CONTROL_ON, - AG_LSWP = QK_MAGIC_SWAP_LALT_LGUI, - AG_LNRM = QK_MAGIC_UNSWAP_LALT_LGUI, - AG_RSWP = QK_MAGIC_SWAP_RALT_RGUI, - AG_RNRM = QK_MAGIC_UNSWAP_RALT_RGUI, - GU_ON = QK_MAGIC_GUI_ON, - GU_OFF = QK_MAGIC_GUI_OFF, - GU_TOGG = QK_MAGIC_TOGGLE_GUI, - GE_SWAP = QK_MAGIC_SWAP_GRAVE_ESC, - GE_NORM = QK_MAGIC_UNSWAP_GRAVE_ESC, - BS_SWAP = QK_MAGIC_SWAP_BACKSLASH_BACKSPACE, - BS_NORM = QK_MAGIC_UNSWAP_BACKSLASH_BACKSPACE, - BS_TOGG = QK_MAGIC_TOGGLE_BACKSLASH_BACKSPACE, - NK_ON = QK_MAGIC_NKRO_ON, - NK_OFF = QK_MAGIC_NKRO_OFF, - NK_TOGG = QK_MAGIC_TOGGLE_NKRO, - AG_SWAP = QK_MAGIC_SWAP_ALT_GUI, - AG_NORM = QK_MAGIC_UNSWAP_ALT_GUI, - AG_TOGG = QK_MAGIC_TOGGLE_ALT_GUI, - CG_LSWP = QK_MAGIC_SWAP_LCTL_LGUI, - CG_LNRM = QK_MAGIC_UNSWAP_LCTL_LGUI, - CG_RSWP = QK_MAGIC_SWAP_RCTL_RGUI, - CG_RNRM = QK_MAGIC_UNSWAP_RCTL_RGUI, - CG_SWAP = QK_MAGIC_SWAP_CTL_GUI, - CG_NORM = QK_MAGIC_UNSWAP_CTL_GUI, - CG_TOGG = QK_MAGIC_TOGGLE_CTL_GUI, - EH_LEFT = QK_MAGIC_EE_HANDS_LEFT, - EH_RGHT = QK_MAGIC_EE_HANDS_RIGHT, - EC_SWAP = QK_MAGIC_SWAP_ESCAPE_CAPS_LOCK, - EC_NORM = QK_MAGIC_UNSWAP_ESCAPE_CAPS_LOCK, - EC_TOGG = QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK, - MI_ON = QK_MIDI_ON, - MI_OFF = QK_MIDI_OFF, - MI_TOGG = QK_MIDI_TOGGLE, - MI_C = QK_MIDI_NOTE_C_0, - MI_Cs = QK_MIDI_NOTE_C_SHARP_0, - MI_Db = QK_MIDI_NOTE_C_SHARP_0, - MI_D = QK_MIDI_NOTE_D_0, - MI_Ds = QK_MIDI_NOTE_D_SHARP_0, - MI_Eb = QK_MIDI_NOTE_D_SHARP_0, - MI_E = QK_MIDI_NOTE_E_0, - MI_F = QK_MIDI_NOTE_F_0, - MI_Fs = QK_MIDI_NOTE_F_SHARP_0, - MI_Gb = QK_MIDI_NOTE_F_SHARP_0, - MI_G = QK_MIDI_NOTE_G_0, - MI_Gs = QK_MIDI_NOTE_G_SHARP_0, - MI_Ab = QK_MIDI_NOTE_G_SHARP_0, - MI_A = QK_MIDI_NOTE_A_0, - MI_As = QK_MIDI_NOTE_A_SHARP_0, - MI_Bb = QK_MIDI_NOTE_A_SHARP_0, - MI_B = QK_MIDI_NOTE_B_0, - MI_C1 = QK_MIDI_NOTE_C_1, - MI_Cs1 = QK_MIDI_NOTE_C_SHARP_1, - MI_Db1 = QK_MIDI_NOTE_C_SHARP_1, - MI_D1 = QK_MIDI_NOTE_D_1, - MI_Ds1 = QK_MIDI_NOTE_D_SHARP_1, - MI_Eb1 = QK_MIDI_NOTE_D_SHARP_1, - MI_E1 = QK_MIDI_NOTE_E_1, - MI_F1 = QK_MIDI_NOTE_F_1, - MI_Fs1 = QK_MIDI_NOTE_F_SHARP_1, - MI_Gb1 = QK_MIDI_NOTE_F_SHARP_1, - MI_G1 = QK_MIDI_NOTE_G_1, - MI_Gs1 = QK_MIDI_NOTE_G_SHARP_1, - MI_Ab1 = QK_MIDI_NOTE_G_SHARP_1, - MI_A1 = QK_MIDI_NOTE_A_1, - MI_As1 = QK_MIDI_NOTE_A_SHARP_1, - MI_Bb1 = QK_MIDI_NOTE_A_SHARP_1, - MI_B1 = QK_MIDI_NOTE_B_1, - MI_C2 = QK_MIDI_NOTE_C_2, - MI_Cs2 = QK_MIDI_NOTE_C_SHARP_2, - MI_Db2 = QK_MIDI_NOTE_C_SHARP_2, - MI_D2 = QK_MIDI_NOTE_D_2, - MI_Ds2 = QK_MIDI_NOTE_D_SHARP_2, - MI_Eb2 = QK_MIDI_NOTE_D_SHARP_2, - MI_E2 = QK_MIDI_NOTE_E_2, - MI_F2 = QK_MIDI_NOTE_F_2, - MI_Fs2 = QK_MIDI_NOTE_F_SHARP_2, - MI_Gb2 = QK_MIDI_NOTE_F_SHARP_2, - MI_G2 = QK_MIDI_NOTE_G_2, - MI_Gs2 = QK_MIDI_NOTE_G_SHARP_2, - MI_Ab2 = QK_MIDI_NOTE_G_SHARP_2, - MI_A2 = QK_MIDI_NOTE_A_2, - MI_As2 = QK_MIDI_NOTE_A_SHARP_2, - MI_Bb2 = QK_MIDI_NOTE_A_SHARP_2, - MI_B2 = QK_MIDI_NOTE_B_2, - MI_C3 = QK_MIDI_NOTE_C_3, - MI_Cs3 = QK_MIDI_NOTE_C_SHARP_3, - MI_Db3 = QK_MIDI_NOTE_C_SHARP_3, - MI_D3 = QK_MIDI_NOTE_D_3, - MI_Ds3 = QK_MIDI_NOTE_D_SHARP_3, - MI_Eb3 = QK_MIDI_NOTE_D_SHARP_3, - MI_E3 = QK_MIDI_NOTE_E_3, - MI_F3 = QK_MIDI_NOTE_F_3, - MI_Fs3 = QK_MIDI_NOTE_F_SHARP_3, - MI_Gb3 = QK_MIDI_NOTE_F_SHARP_3, - MI_G3 = QK_MIDI_NOTE_G_3, - MI_Gs3 = QK_MIDI_NOTE_G_SHARP_3, - MI_Ab3 = QK_MIDI_NOTE_G_SHARP_3, - MI_A3 = QK_MIDI_NOTE_A_3, - MI_As3 = QK_MIDI_NOTE_A_SHARP_3, - MI_Bb3 = QK_MIDI_NOTE_A_SHARP_3, - MI_B3 = QK_MIDI_NOTE_B_3, - MI_C4 = QK_MIDI_NOTE_C_4, - MI_Cs4 = QK_MIDI_NOTE_C_SHARP_4, - MI_Db4 = QK_MIDI_NOTE_C_SHARP_4, - MI_D4 = QK_MIDI_NOTE_D_4, - MI_Ds4 = QK_MIDI_NOTE_D_SHARP_4, - MI_Eb4 = QK_MIDI_NOTE_D_SHARP_4, - MI_E4 = QK_MIDI_NOTE_E_4, - MI_F4 = QK_MIDI_NOTE_F_4, - MI_Fs4 = QK_MIDI_NOTE_F_SHARP_4, - MI_Gb4 = QK_MIDI_NOTE_F_SHARP_4, - MI_G4 = QK_MIDI_NOTE_G_4, - MI_Gs4 = QK_MIDI_NOTE_G_SHARP_4, - MI_Ab4 = QK_MIDI_NOTE_G_SHARP_4, - MI_A4 = QK_MIDI_NOTE_A_4, - MI_As4 = QK_MIDI_NOTE_A_SHARP_4, - MI_Bb4 = QK_MIDI_NOTE_A_SHARP_4, - MI_B4 = QK_MIDI_NOTE_B_4, - MI_C5 = QK_MIDI_NOTE_C_5, - MI_Cs5 = QK_MIDI_NOTE_C_SHARP_5, - MI_Db5 = QK_MIDI_NOTE_C_SHARP_5, - MI_D5 = QK_MIDI_NOTE_D_5, - MI_Ds5 = QK_MIDI_NOTE_D_SHARP_5, - MI_Eb5 = QK_MIDI_NOTE_D_SHARP_5, - MI_E5 = QK_MIDI_NOTE_E_5, - MI_F5 = QK_MIDI_NOTE_F_5, - MI_Fs5 = QK_MIDI_NOTE_F_SHARP_5, - MI_Gb5 = QK_MIDI_NOTE_F_SHARP_5, - MI_G5 = QK_MIDI_NOTE_G_5, - MI_Gs5 = QK_MIDI_NOTE_G_SHARP_5, - MI_Ab5 = QK_MIDI_NOTE_G_SHARP_5, - MI_A5 = QK_MIDI_NOTE_A_5, - MI_As5 = QK_MIDI_NOTE_A_SHARP_5, - MI_Bb5 = QK_MIDI_NOTE_A_SHARP_5, - MI_B5 = QK_MIDI_NOTE_B_5, - MI_OCN2 = QK_MIDI_OCTAVE_N2, - MI_OCN1 = QK_MIDI_OCTAVE_N1, - MI_OC0 = QK_MIDI_OCTAVE_0, - MI_OC1 = QK_MIDI_OCTAVE_1, - MI_OC2 = QK_MIDI_OCTAVE_2, - MI_OC3 = QK_MIDI_OCTAVE_3, - MI_OC4 = QK_MIDI_OCTAVE_4, - MI_OC5 = QK_MIDI_OCTAVE_5, - MI_OC6 = QK_MIDI_OCTAVE_6, - MI_OC7 = QK_MIDI_OCTAVE_7, - MI_OCTD = QK_MIDI_OCTAVE_DOWN, - MI_OCTU = QK_MIDI_OCTAVE_UP, - MI_TRN6 = QK_MIDI_TRANSPOSE_N6, - MI_TRN5 = QK_MIDI_TRANSPOSE_N5, - MI_TRN4 = QK_MIDI_TRANSPOSE_N4, - MI_TRN3 = QK_MIDI_TRANSPOSE_N3, - MI_TRN2 = QK_MIDI_TRANSPOSE_N2, - MI_TRN1 = QK_MIDI_TRANSPOSE_N1, - MI_TR0 = QK_MIDI_TRANSPOSE_0, - MI_TR1 = QK_MIDI_TRANSPOSE_1, - MI_TR2 = QK_MIDI_TRANSPOSE_2, - MI_TR3 = QK_MIDI_TRANSPOSE_3, - MI_TR4 = QK_MIDI_TRANSPOSE_4, - MI_TR5 = QK_MIDI_TRANSPOSE_5, - MI_TR6 = QK_MIDI_TRANSPOSE_6, - MI_TRSD = QK_MIDI_TRANSPOSE_DOWN, - MI_TRSU = QK_MIDI_TRANSPOSE_UP, - MI_VL0 = QK_MIDI_VELOCITY_0, - MI_VL1 = QK_MIDI_VELOCITY_1, - MI_VL2 = QK_MIDI_VELOCITY_2, - MI_VL3 = QK_MIDI_VELOCITY_3, - MI_VL4 = QK_MIDI_VELOCITY_4, - MI_VL5 = QK_MIDI_VELOCITY_5, - MI_VL6 = QK_MIDI_VELOCITY_6, - MI_VL7 = QK_MIDI_VELOCITY_7, - MI_VL8 = QK_MIDI_VELOCITY_8, - MI_VL9 = QK_MIDI_VELOCITY_9, - MI_VL10 = QK_MIDI_VELOCITY_10, - MI_VELD = QK_MIDI_VELOCITY_DOWN, - MI_VELU = QK_MIDI_VELOCITY_UP, - MI_CH1 = QK_MIDI_CHANNEL_1, - MI_CH2 = QK_MIDI_CHANNEL_2, - MI_CH3 = QK_MIDI_CHANNEL_3, - MI_CH4 = QK_MIDI_CHANNEL_4, - MI_CH5 = QK_MIDI_CHANNEL_5, - MI_CH6 = QK_MIDI_CHANNEL_6, - MI_CH7 = QK_MIDI_CHANNEL_7, - MI_CH8 = QK_MIDI_CHANNEL_8, - MI_CH9 = QK_MIDI_CHANNEL_9, - MI_CH10 = QK_MIDI_CHANNEL_10, - MI_CH11 = QK_MIDI_CHANNEL_11, - MI_CH12 = QK_MIDI_CHANNEL_12, - MI_CH13 = QK_MIDI_CHANNEL_13, - MI_CH14 = QK_MIDI_CHANNEL_14, - MI_CH15 = QK_MIDI_CHANNEL_15, - MI_CH16 = QK_MIDI_CHANNEL_16, - MI_CHND = QK_MIDI_CHANNEL_DOWN, - MI_CHNU = QK_MIDI_CHANNEL_UP, - MI_AOFF = QK_MIDI_ALL_NOTES_OFF, - MI_SUST = QK_MIDI_SUSTAIN, - MI_PORT = QK_MIDI_PORTAMENTO, - MI_SOST = QK_MIDI_SOSTENUTO, - MI_SOFT = QK_MIDI_SOFT, - MI_LEG = QK_MIDI_LEGATO, - MI_MOD = QK_MIDI_MODULATION, - MI_MODD = QK_MIDI_MODULATION_SPEED_DOWN, - MI_MODU = QK_MIDI_MODULATION_SPEED_UP, - MI_BNDD = QK_MIDI_PITCH_BEND_DOWN, - MI_BNDU = QK_MIDI_PITCH_BEND_UP, - SQ_ON = QK_SEQUENCER_ON, - SQ_OFF = QK_SEQUENCER_OFF, - SQ_TOGG = QK_SEQUENCER_TOGGLE, - SQ_TMPD = QK_SEQUENCER_TEMPO_DOWN, - SQ_TMPU = QK_SEQUENCER_TEMPO_UP, - SQ_RESD = QK_SEQUENCER_RESOLUTION_DOWN, - SQ_RESU = QK_SEQUENCER_RESOLUTION_UP, - SQ_SALL = QK_SEQUENCER_STEPS_ALL, - SQ_SCLR = QK_SEQUENCER_STEPS_CLEAR, - JS_0 = QK_JOYSTICK_BUTTON_0, - JS_1 = QK_JOYSTICK_BUTTON_1, - JS_2 = QK_JOYSTICK_BUTTON_2, - JS_3 = QK_JOYSTICK_BUTTON_3, - JS_4 = QK_JOYSTICK_BUTTON_4, - JS_5 = QK_JOYSTICK_BUTTON_5, - JS_6 = QK_JOYSTICK_BUTTON_6, - JS_7 = QK_JOYSTICK_BUTTON_7, - JS_8 = QK_JOYSTICK_BUTTON_8, - JS_9 = QK_JOYSTICK_BUTTON_9, - JS_10 = QK_JOYSTICK_BUTTON_10, - JS_11 = QK_JOYSTICK_BUTTON_11, - JS_12 = QK_JOYSTICK_BUTTON_12, - JS_13 = QK_JOYSTICK_BUTTON_13, - JS_14 = QK_JOYSTICK_BUTTON_14, - JS_15 = QK_JOYSTICK_BUTTON_15, - JS_16 = QK_JOYSTICK_BUTTON_16, - JS_17 = QK_JOYSTICK_BUTTON_17, - JS_18 = QK_JOYSTICK_BUTTON_18, - JS_19 = QK_JOYSTICK_BUTTON_19, - JS_20 = QK_JOYSTICK_BUTTON_20, - JS_21 = QK_JOYSTICK_BUTTON_21, - JS_22 = QK_JOYSTICK_BUTTON_22, - JS_23 = QK_JOYSTICK_BUTTON_23, - JS_24 = QK_JOYSTICK_BUTTON_24, - JS_25 = QK_JOYSTICK_BUTTON_25, - JS_26 = QK_JOYSTICK_BUTTON_26, - JS_27 = QK_JOYSTICK_BUTTON_27, - JS_28 = QK_JOYSTICK_BUTTON_28, - JS_29 = QK_JOYSTICK_BUTTON_29, - JS_30 = QK_JOYSTICK_BUTTON_30, - JS_31 = QK_JOYSTICK_BUTTON_31, - PB_1 = QK_PROGRAMMABLE_BUTTON_1, - PB_2 = QK_PROGRAMMABLE_BUTTON_2, - PB_3 = QK_PROGRAMMABLE_BUTTON_3, - PB_4 = QK_PROGRAMMABLE_BUTTON_4, - PB_5 = QK_PROGRAMMABLE_BUTTON_5, - PB_6 = QK_PROGRAMMABLE_BUTTON_6, - PB_7 = QK_PROGRAMMABLE_BUTTON_7, - PB_8 = QK_PROGRAMMABLE_BUTTON_8, - PB_9 = QK_PROGRAMMABLE_BUTTON_9, - PB_10 = QK_PROGRAMMABLE_BUTTON_10, - PB_11 = QK_PROGRAMMABLE_BUTTON_11, - PB_12 = QK_PROGRAMMABLE_BUTTON_12, - PB_13 = QK_PROGRAMMABLE_BUTTON_13, - PB_14 = QK_PROGRAMMABLE_BUTTON_14, - PB_15 = QK_PROGRAMMABLE_BUTTON_15, - PB_16 = QK_PROGRAMMABLE_BUTTON_16, - PB_17 = QK_PROGRAMMABLE_BUTTON_17, - PB_18 = QK_PROGRAMMABLE_BUTTON_18, - PB_19 = QK_PROGRAMMABLE_BUTTON_19, - PB_20 = QK_PROGRAMMABLE_BUTTON_20, - PB_21 = QK_PROGRAMMABLE_BUTTON_21, - PB_22 = QK_PROGRAMMABLE_BUTTON_22, - PB_23 = QK_PROGRAMMABLE_BUTTON_23, - PB_24 = QK_PROGRAMMABLE_BUTTON_24, - PB_25 = QK_PROGRAMMABLE_BUTTON_25, - PB_26 = QK_PROGRAMMABLE_BUTTON_26, - PB_27 = QK_PROGRAMMABLE_BUTTON_27, - PB_28 = QK_PROGRAMMABLE_BUTTON_28, - PB_29 = QK_PROGRAMMABLE_BUTTON_29, - PB_30 = QK_PROGRAMMABLE_BUTTON_30, - PB_31 = QK_PROGRAMMABLE_BUTTON_31, - PB_32 = QK_PROGRAMMABLE_BUTTON_32, - AU_ON = QK_AUDIO_ON, - AU_OFF = QK_AUDIO_OFF, - AU_TOGG = QK_AUDIO_TOGGLE, - CK_TOGG = QK_AUDIO_CLICKY_TOGGLE, - CK_ON = QK_AUDIO_CLICKY_ON, - CK_OFF = QK_AUDIO_CLICKY_OFF, - CK_UP = QK_AUDIO_CLICKY_UP, - CK_DOWN = QK_AUDIO_CLICKY_DOWN, - CK_RST = QK_AUDIO_CLICKY_RESET, - MU_ON = QK_MUSIC_ON, - MU_OFF = QK_MUSIC_OFF, - MU_TOGG = QK_MUSIC_TOGGLE, - MU_NEXT = QK_MUSIC_MODE_NEXT, - AU_NEXT = QK_AUDIO_VOICE_NEXT, - AU_PREV = QK_AUDIO_VOICE_PREVIOUS, - MC_0 = QK_MACRO_0, - MC_1 = QK_MACRO_1, - MC_2 = QK_MACRO_2, - MC_3 = QK_MACRO_3, - MC_4 = QK_MACRO_4, - MC_5 = QK_MACRO_5, - MC_6 = QK_MACRO_6, - MC_7 = QK_MACRO_7, - MC_8 = QK_MACRO_8, - MC_9 = QK_MACRO_9, - MC_10 = QK_MACRO_10, - MC_11 = QK_MACRO_11, - MC_12 = QK_MACRO_12, - MC_13 = QK_MACRO_13, - MC_14 = QK_MACRO_14, - MC_15 = QK_MACRO_15, - MC_16 = QK_MACRO_16, - MC_17 = QK_MACRO_17, - MC_18 = QK_MACRO_18, - MC_19 = QK_MACRO_19, - MC_20 = QK_MACRO_20, - MC_21 = QK_MACRO_21, - MC_22 = QK_MACRO_22, - MC_23 = QK_MACRO_23, - MC_24 = QK_MACRO_24, - MC_25 = QK_MACRO_25, - MC_26 = QK_MACRO_26, - MC_27 = QK_MACRO_27, - MC_28 = QK_MACRO_28, - MC_29 = QK_MACRO_29, - MC_30 = QK_MACRO_30, - MC_31 = QK_MACRO_31, - BL_ON = QK_BACKLIGHT_ON, - BL_OFF = QK_BACKLIGHT_OFF, - BL_TOGG = QK_BACKLIGHT_TOGGLE, - BL_DOWN = QK_BACKLIGHT_DOWN, - BL_UP = QK_BACKLIGHT_UP, - BL_STEP = QK_BACKLIGHT_STEP, - BL_BRTG = QK_BACKLIGHT_TOGGLE_BREATHING, - RGB_MOD = RGB_MODE_FORWARD, - RGB_RMOD = RGB_MODE_REVERSE, - RGB_M_P = RGB_MODE_PLAIN, - RGB_M_B = RGB_MODE_BREATHE, - RGB_M_R = RGB_MODE_RAINBOW, - RGB_M_SW = RGB_MODE_SWIRL, - RGB_M_SN = RGB_MODE_SNAKE, - RGB_M_K = RGB_MODE_KNIGHT, - RGB_M_X = RGB_MODE_XMAS, - RGB_M_G = RGB_MODE_GRADIENT, - RGB_M_T = RGB_MODE_RGBTEST, - RGB_M_TW = RGB_MODE_TWINKLE, - QK_BOOT = QK_BOOTLOADER, - QK_RBT = QK_REBOOT, - DB_TOGG = QK_DEBUG_TOGGLE, - EE_CLR = QK_CLEAR_EEPROM, - AS_DOWN = QK_AUTO_SHIFT_DOWN, - AS_UP = QK_AUTO_SHIFT_UP, - AS_RPT = QK_AUTO_SHIFT_REPORT, - AS_ON = QK_AUTO_SHIFT_ON, - AS_OFF = QK_AUTO_SHIFT_OFF, - AS_TOGG = QK_AUTO_SHIFT_TOGGLE, - QK_GESC = QK_GRAVE_ESCAPE, - VK_TOGG = QK_VELOCIKEY_TOGGLE, - SC_LCPO = QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN, - SC_RCPC = QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE, - SC_LSPO = QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN, - SC_RSPC = QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE, - SC_LAPO = QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN, - SC_RAPC = QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE, - SC_SENT = QK_SPACE_CADET_RIGHT_SHIFT_ENTER, - OU_AUTO = QK_OUTPUT_AUTO, - OU_USB = QK_OUTPUT_USB, - OU_BT = QK_OUTPUT_BLUETOOTH, - UC_NEXT = QK_UNICODE_MODE_NEXT, - UC_PREV = QK_UNICODE_MODE_PREVIOUS, - UC_MAC = QK_UNICODE_MODE_MACOS, - UC_LINX = QK_UNICODE_MODE_LINUX, - UC_WIN = QK_UNICODE_MODE_WINDOWS, - UC_BSD = QK_UNICODE_MODE_BSD, - UC_WINC = QK_UNICODE_MODE_WINCOMPOSE, - UC_EMAC = QK_UNICODE_MODE_EMACS, - HF_ON = QK_HAPTIC_ON, - HF_OFF = QK_HAPTIC_OFF, - HF_TOGG = QK_HAPTIC_TOGGLE, - HF_RST = QK_HAPTIC_RESET, - HF_FDBK = QK_HAPTIC_FEEDBACK_TOGGLE, - HF_BUZZ = QK_HAPTIC_BUZZ_TOGGLE, - HF_NEXT = QK_HAPTIC_MODE_NEXT, - HF_PREV = QK_HAPTIC_MODE_PREVIOUS, - HF_CONT = QK_HAPTIC_CONTINUOUS_TOGGLE, - HF_CONU = QK_HAPTIC_CONTINUOUS_UP, - HF_COND = QK_HAPTIC_CONTINUOUS_DOWN, - HF_DWLU = QK_HAPTIC_DWELL_UP, - HF_DWLD = QK_HAPTIC_DWELL_DOWN, - CM_ON = QK_COMBO_ON, - CM_OFF = QK_COMBO_OFF, - CM_TOGG = QK_COMBO_TOGGLE, - DM_REC1 = QK_DYNAMIC_MACRO_RECORD_START_1, - DM_REC2 = QK_DYNAMIC_MACRO_RECORD_START_2, - DM_RSTP = QK_DYNAMIC_MACRO_RECORD_STOP, - DM_PLY1 = QK_DYNAMIC_MACRO_PLAY_1, - DM_PLY2 = QK_DYNAMIC_MACRO_PLAY_2, - QK_LEAD = QK_LEADER, - OS_ON = QK_ONE_SHOT_ON, - OS_OFF = QK_ONE_SHOT_OFF, - OS_TOGG = QK_ONE_SHOT_TOGGLE, - KO_TOGG = QK_KEY_OVERRIDE_TOGGLE, - KO_ON = QK_KEY_OVERRIDE_ON, - KO_OFF = QK_KEY_OVERRIDE_OFF, - SE_LOCK = QK_SECURE_LOCK, - SE_UNLK = QK_SECURE_UNLOCK, - SE_TOGG = QK_SECURE_TOGGLE, - SE_REQ = QK_SECURE_REQUEST, - DT_PRNT = QK_DYNAMIC_TAPPING_TERM_PRINT, - DT_UP = QK_DYNAMIC_TAPPING_TERM_UP, - DT_DOWN = QK_DYNAMIC_TAPPING_TERM_DOWN, - CW_TOGG = QK_CAPS_WORD_TOGGLE, - AC_ON = QK_AUTOCORRECT_ON, - AC_OFF = QK_AUTOCORRECT_OFF, - AC_TOGG = QK_AUTOCORRECT_TOGGLE, - TL_LOWR = QK_TRI_LAYER_LOWER, - TL_UPPR = QK_TRI_LAYER_UPPER, - QK_REP = QK_REPEAT_KEY, - QK_AREP = QK_ALT_REPEAT_KEY, -}; - -// Range Helpers -#define IS_QK_BASIC(code) ((code) >= QK_BASIC && (code) <= QK_BASIC_MAX) -#define IS_QK_MODS(code) ((code) >= QK_MODS && (code) <= QK_MODS_MAX) -#define IS_QK_MOD_TAP(code) ((code) >= QK_MOD_TAP && (code) <= QK_MOD_TAP_MAX) -#define IS_QK_LAYER_TAP(code) ((code) >= QK_LAYER_TAP && (code) <= QK_LAYER_TAP_MAX) -#define IS_QK_LAYER_MOD(code) ((code) >= QK_LAYER_MOD && (code) <= QK_LAYER_MOD_MAX) -#define IS_QK_TO(code) ((code) >= QK_TO && (code) <= QK_TO_MAX) -#define IS_QK_MOMENTARY(code) ((code) >= QK_MOMENTARY && (code) <= QK_MOMENTARY_MAX) -#define IS_QK_DEF_LAYER(code) ((code) >= QK_DEF_LAYER && (code) <= QK_DEF_LAYER_MAX) -#define IS_QK_TOGGLE_LAYER(code) ((code) >= QK_TOGGLE_LAYER && (code) <= QK_TOGGLE_LAYER_MAX) -#define IS_QK_ONE_SHOT_LAYER(code) ((code) >= QK_ONE_SHOT_LAYER && (code) <= QK_ONE_SHOT_LAYER_MAX) -#define IS_QK_ONE_SHOT_MOD(code) ((code) >= QK_ONE_SHOT_MOD && (code) <= QK_ONE_SHOT_MOD_MAX) -#define IS_QK_LAYER_TAP_TOGGLE(code) ((code) >= QK_LAYER_TAP_TOGGLE && (code) <= QK_LAYER_TAP_TOGGLE_MAX) -#define IS_QK_SWAP_HANDS(code) ((code) >= QK_SWAP_HANDS && (code) <= QK_SWAP_HANDS_MAX) -#define IS_QK_TAP_DANCE(code) ((code) >= QK_TAP_DANCE && (code) <= QK_TAP_DANCE_MAX) -#define IS_QK_MAGIC(code) ((code) >= QK_MAGIC && (code) <= QK_MAGIC_MAX) -#define IS_QK_MIDI(code) ((code) >= QK_MIDI && (code) <= QK_MIDI_MAX) -#define IS_QK_SEQUENCER(code) ((code) >= QK_SEQUENCER && (code) <= QK_SEQUENCER_MAX) -#define IS_QK_JOYSTICK(code) ((code) >= QK_JOYSTICK && (code) <= QK_JOYSTICK_MAX) -#define IS_QK_PROGRAMMABLE_BUTTON(code) ((code) >= QK_PROGRAMMABLE_BUTTON && (code) <= QK_PROGRAMMABLE_BUTTON_MAX) -#define IS_QK_AUDIO(code) ((code) >= QK_AUDIO && (code) <= QK_AUDIO_MAX) -#define IS_QK_STENO(code) ((code) >= QK_STENO && (code) <= QK_STENO_MAX) -#define IS_QK_MACRO(code) ((code) >= QK_MACRO && (code) <= QK_MACRO_MAX) -#define IS_QK_LIGHTING(code) ((code) >= QK_LIGHTING && (code) <= QK_LIGHTING_MAX) -#define IS_QK_QUANTUM(code) ((code) >= QK_QUANTUM && (code) <= QK_QUANTUM_MAX) -#define IS_QK_KB(code) ((code) >= QK_KB && (code) <= QK_KB_MAX) -#define IS_QK_USER(code) ((code) >= QK_USER && (code) <= QK_USER_MAX) -#define IS_QK_UNICODEMAP(code) ((code) >= QK_UNICODEMAP && (code) <= QK_UNICODEMAP_MAX) -#define IS_QK_UNICODE(code) ((code) >= QK_UNICODE && (code) <= QK_UNICODE_MAX) -#define IS_QK_UNICODEMAP_PAIR(code) ((code) >= QK_UNICODEMAP_PAIR && (code) <= QK_UNICODEMAP_PAIR_MAX) - -// Group Helpers -#define IS_INTERNAL_KEYCODE(code) ((code) >= KC_NO && (code) <= KC_TRANSPARENT) -#define IS_BASIC_KEYCODE(code) ((code) >= KC_A && (code) <= KC_EXSEL) -#define IS_SYSTEM_KEYCODE(code) ((code) >= KC_SYSTEM_POWER && (code) <= KC_SYSTEM_WAKE) -#define IS_CONSUMER_KEYCODE(code) ((code) >= KC_AUDIO_MUTE && (code) <= KC_LAUNCHPAD) -#define IS_MOUSE_KEYCODE(code) ((code) >= KC_MS_UP && (code) <= KC_MS_ACCEL2) -#define IS_MODIFIER_KEYCODE(code) ((code) >= KC_LEFT_CTRL && (code) <= KC_RIGHT_GUI) -#define IS_SWAP_HANDS_KEYCODE(code) ((code) >= QK_SWAP_HANDS_TOGGLE && (code) <= QK_SWAP_HANDS_ONE_SHOT) -#define IS_MAGIC_KEYCODE(code) ((code) >= QK_MAGIC_SWAP_CONTROL_CAPS_LOCK && (code) <= QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK) -#define IS_MIDI_KEYCODE(code) ((code) >= QK_MIDI_ON && (code) <= QK_MIDI_PITCH_BEND_UP) -#define IS_SEQUENCER_KEYCODE(code) ((code) >= QK_SEQUENCER_ON && (code) <= QK_SEQUENCER_STEPS_CLEAR) -#define IS_JOYSTICK_KEYCODE(code) ((code) >= QK_JOYSTICK_BUTTON_0 && (code) <= QK_JOYSTICK_BUTTON_31) -#define IS_PROGRAMMABLE_BUTTON_KEYCODE(code) ((code) >= QK_PROGRAMMABLE_BUTTON_1 && (code) <= QK_PROGRAMMABLE_BUTTON_32) -#define IS_AUDIO_KEYCODE(code) ((code) >= QK_AUDIO_ON && (code) <= QK_AUDIO_VOICE_PREVIOUS) -#define IS_STENO_KEYCODE(code) ((code) >= QK_STENO_BOLT && (code) <= QK_STENO_COMB_MAX) -#define IS_MACRO_KEYCODE(code) ((code) >= QK_MACRO_0 && (code) <= QK_MACRO_31) -#define IS_BACKLIGHT_KEYCODE(code) ((code) >= QK_BACKLIGHT_ON && (code) <= QK_BACKLIGHT_TOGGLE_BREATHING) -#define IS_RGB_KEYCODE(code) ((code) >= RGB_TOG && (code) <= RGB_MODE_TWINKLE) -#define IS_QUANTUM_KEYCODE(code) ((code) >= QK_BOOTLOADER && (code) <= QK_ALT_REPEAT_KEY) -#define IS_KB_KEYCODE(code) ((code) >= QK_KB_0 && (code) <= QK_KB_31) -#define IS_USER_KEYCODE(code) ((code) >= QK_USER_0 && (code) <= QK_USER_31) diff --git a/quantum/keymap_common.c b/quantum/keymap_common.c deleted file mode 100644 index 0492e6fd1c3f..000000000000 --- a/quantum/keymap_common.c +++ /dev/null @@ -1,203 +0,0 @@ -/* -Copyright 2012-2017 Jun Wako - -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 . -*/ - -#include "keymap_common.h" -#include "keymap_introspection.h" -#include "report.h" -#include "keycode.h" -#include "action_layer.h" -#include "action.h" -#include "debug.h" -#include "quantum.h" - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef MIDI_ENABLE -# include "process_midi.h" -#endif - -extern keymap_config_t keymap_config; - -#include - -/* converts key to action */ -action_t action_for_key(uint8_t layer, keypos_t key) { - // 16bit keycodes - important - uint16_t keycode = keymap_key_to_keycode(layer, key); - return action_for_keycode(keycode); -}; - -action_t action_for_keycode(uint16_t keycode) { - // keycode remapping - keycode = keycode_config(keycode); - - action_t action = {}; - uint8_t action_layer, mod; - - (void)action_layer; - (void)mod; - - switch (keycode) { - case KC_A ... KC_EXSEL: - case KC_LEFT_CTRL ... KC_RIGHT_GUI: - action.code = ACTION_KEY(keycode); - break; -#ifdef EXTRAKEY_ENABLE - case KC_SYSTEM_POWER ... KC_SYSTEM_WAKE: - action.code = ACTION_USAGE_SYSTEM(KEYCODE2SYSTEM(keycode)); - break; - case KC_AUDIO_MUTE ... KC_LAUNCHPAD: - action.code = ACTION_USAGE_CONSUMER(KEYCODE2CONSUMER(keycode)); - break; -#endif - case KC_MS_UP ... KC_MS_ACCEL2: - action.code = ACTION_MOUSEKEY(keycode); - break; - case KC_TRANSPARENT: - action.code = ACTION_TRANSPARENT; - break; - case QK_MODS ... QK_MODS_MAX:; - // Has a modifier - // Split it up -#ifdef LEGACY_MAGIC_HANDLING - action.code = ACTION_MODS_KEY(QK_MODS_GET_MODS(keycode), QK_MODS_GET_BASIC_KEYCODE(keycode)); // adds modifier to key -#else // LEGACY_MAGIC_HANDLING - action.code = ACTION_MODS_KEY(mod_config(QK_MODS_GET_MODS(keycode)), keycode_config(QK_MODS_GET_BASIC_KEYCODE(keycode))); // adds modifier to key -#endif // LEGACY_MAGIC_HANDLING - break; - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: -#if !defined(NO_ACTION_LAYER) && !defined(NO_ACTION_TAPPING) -# ifdef LEGACY_MAGIC_HANDLING - action.code = ACTION_LAYER_TAP_KEY(QK_LAYER_TAP_GET_LAYER(keycode), QK_LAYER_TAP_GET_TAP_KEYCODE(keycode)); -# else // LEGACY_MAGIC_HANDLING - action.code = ACTION_LAYER_TAP_KEY(QK_LAYER_TAP_GET_LAYER(keycode), keycode_config(QK_LAYER_TAP_GET_TAP_KEYCODE(keycode))); -# endif // LEGACY_MAGIC_HANDLING -#else - // pass through keycode_config again, since it previously missed it - // and then only send as ACTION_KEY to bypass most of action.c handling - action.code = ACTION_KEY(keycode_config(QK_LAYER_TAP_GET_TAP_KEYCODE(keycode))); -#endif - break; -#ifndef NO_ACTION_LAYER - case QK_TO ... QK_TO_MAX:; - // Layer set "GOTO" - action_layer = QK_TO_GET_LAYER(keycode); - action.code = ACTION_LAYER_GOTO(action_layer); - break; - case QK_MOMENTARY ... QK_MOMENTARY_MAX:; - // Momentary action_layer - action_layer = QK_MOMENTARY_GET_LAYER(keycode); - action.code = ACTION_LAYER_MOMENTARY(action_layer); - break; - case QK_DEF_LAYER ... QK_DEF_LAYER_MAX:; - // Set default action_layer - action_layer = QK_DEF_LAYER_GET_LAYER(keycode); - action.code = ACTION_DEFAULT_LAYER_SET(action_layer); - break; - case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX:; - // Set toggle - action_layer = QK_TOGGLE_LAYER_GET_LAYER(keycode); - action.code = ACTION_LAYER_TOGGLE(action_layer); - break; -#endif -#ifndef NO_ACTION_ONESHOT - case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX:; - // OSL(action_layer) - One-shot action_layer - action_layer = QK_ONE_SHOT_LAYER_GET_LAYER(keycode); - action.code = ACTION_LAYER_ONESHOT(action_layer); - break; -#endif // NO_ACTION_ONESHOT - case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX:; - // OSM(mod) - One-shot mod - mod = mod_config(QK_ONE_SHOT_MOD_GET_MODS(keycode)); -#if defined(NO_ACTION_TAPPING) || defined(NO_ACTION_ONESHOT) - action.code = ACTION_MODS(mod); -#else // defined(NO_ACTION_TAPPING) || defined(NO_ACTION_ONESHOT) - action.code = ACTION_MODS_ONESHOT(mod); -#endif // defined(NO_ACTION_TAPPING) || defined(NO_ACTION_ONESHOT) - break; -#ifndef NO_ACTION_LAYER - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: -# ifndef NO_ACTION_TAPPING - action.code = ACTION_LAYER_TAP_TOGGLE(QK_LAYER_TAP_TOGGLE_GET_LAYER(keycode)); -# else // NO_ACTION_TAPPING -# ifdef NO_ACTION_TAPPING_TAP_TOGGLE_MO - action.code = ACTION_LAYER_MOMENTARY(QK_LAYER_TAP_TOGGLE_GET_LAYER(keycode)); -# else // NO_ACTION_TAPPING_TAP_TOGGLE_MO - action.code = ACTION_LAYER_TOGGLE(QK_LAYER_TAP_TOGGLE_GET_LAYER(keycode)); -# endif // NO_ACTION_TAPPING_TAP_TOGGLE_MO -# endif // NO_ACTION_TAPPING - break; - case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: - mod = mod_config(QK_LAYER_MOD_GET_MODS(keycode)); - action_layer = QK_LAYER_MOD_GET_LAYER(keycode); - action.code = ACTION_LAYER_MODS(action_layer, (mod & 0x10) ? mod << 4 : mod); - break; -#endif // NO_ACTION_LAYER - case QK_MOD_TAP ... QK_MOD_TAP_MAX: -#ifndef NO_ACTION_TAPPING - mod = mod_config(QK_MOD_TAP_GET_MODS(keycode)); -# ifdef LEGACY_MAGIC_HANDLING - action.code = ACTION_MODS_TAP_KEY(mod, QK_MOD_TAP_GET_TAP_KEYCODE(keycode)); -# else // LEGACY_MAGIC_HANDLING - action.code = ACTION_MODS_TAP_KEY(mod, keycode_config(QK_MOD_TAP_GET_TAP_KEYCODE(keycode))); -# endif // LEGACY_MAGIC_HANDLING -#else // NO_ACTION_TAPPING -# ifdef NO_ACTION_TAPPING_MODTAP_MODS - // pass through mod_config again, since it previously missed it - // and then only send as ACTION_KEY to bypass most of action.c handling - action.code = ACTION_MODS(mod_config(QK_MOD_TAP_GET_MODS(keycode))); -# else // NO_ACTION_TAPPING_MODTAP_MODS - // pass through keycode_config again, since it previously missed it - // and then only send as ACTION_KEY to bypass most of action.c handling - action.code = ACTION_KEY(keycode_config(QK_MOD_TAP_GET_TAP_KEYCODE(keycode))); -# endif // NO_ACTION_TAPPING_MODTAP_MODS -#endif // NO_ACTION_TAPPING - break; -#ifdef SWAP_HANDS_ENABLE - case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: -# ifdef LEGACY_MAGIC_HANDLING - action.code = ACTION(ACT_SWAP_HANDS, QK_SWAP_HANDS_GET_TAP_KEYCODE(keycode)); -# else // LEGACY_MAGIC_HANDLING - action.code = ACTION(ACT_SWAP_HANDS, keycode_config(QK_SWAP_HANDS_GET_TAP_KEYCODE(keycode))); -# endif // LEGACY_MAGIC_HANDLING - break; -#endif - - default: - action.code = ACTION_NO; - break; - } - return action; -} - -// translates key to keycode -__attribute__((weak)) uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key) { - if (key.row < MATRIX_ROWS && key.col < MATRIX_COLS) { - return keycode_at_keymap_location(layer, key.row, key.col); - } -#ifdef ENCODER_MAP_ENABLE - else if (key.row == KEYLOC_ENCODER_CW && key.col < NUM_ENCODERS) { - return keycode_at_encodermap_location(layer, key.col, true); - } else if (key.row == KEYLOC_ENCODER_CCW && key.col < NUM_ENCODERS) { - return keycode_at_encodermap_location(layer, key.col, false); - } -#endif // ENCODER_MAP_ENABLE - return KC_NO; -} diff --git a/quantum/keymap_common.h b/quantum/keymap_common.h deleted file mode 100644 index fca4fc9ba334..000000000000 --- a/quantum/keymap_common.h +++ /dev/null @@ -1,10 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "keyboard.h" - -// translates key to keycode -uint16_t keymap_key_to_keycode(uint8_t layer, keypos_t key); diff --git a/quantum/keymap_extras/keymap_belgian.h b/quantum/keymap_extras/keymap_belgian.h deleted file mode 100644 index 6851c6b4e82e..000000000000 --- a/quantum/keymap_extras/keymap_belgian.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define BE_SUP2 KC_GRV // ² -#define BE_AMPR KC_1 // & -#define BE_EACU KC_2 // é -#define BE_DQUO KC_3 // " -#define BE_QUOT KC_4 // ' -#define BE_LPRN KC_5 // ( -#define BE_SECT KC_6 // § -#define BE_EGRV KC_7 // è -#define BE_EXLM KC_8 // ! -#define BE_CCED KC_9 // ç -#define BE_AGRV KC_0 // à -#define BE_RPRN KC_MINS // ) -#define BE_MINS KC_EQL // - -#define BE_A KC_Q // A -#define BE_Z KC_W // Z -#define BE_E KC_E // E -#define BE_R KC_R // R -#define BE_T KC_T // T -#define BE_Y KC_Y // Y -#define BE_U KC_U // U -#define BE_I KC_I // I -#define BE_O KC_O // O -#define BE_P KC_P // P -#define BE_DCIR KC_LBRC // ^ (dead) -#define BE_DLR KC_RBRC // $ -#define BE_Q KC_A // Q -#define BE_S KC_S // S -#define BE_D KC_D // D -#define BE_F KC_F // F -#define BE_G KC_G // G -#define BE_H KC_H // H -#define BE_J KC_J // J -#define BE_K KC_K // K -#define BE_L KC_L // L -#define BE_M KC_SCLN // M -#define BE_UGRV KC_QUOT // ù -#define BE_MICR KC_NUHS // µ -#define BE_LABK KC_NUBS // < -#define BE_W KC_Z // W -#define BE_X KC_X // X -#define BE_C KC_C // C -#define BE_V KC_V // V -#define BE_B KC_B // B -#define BE_N KC_N // N -#define BE_COMM KC_M // , -#define BE_SCLN KC_COMM // ; -#define BE_COLN KC_DOT // : -#define BE_EQL KC_SLSH // = -#define BE_SUP3 S(BE_SUP2) // ³ -#define BE_1 S(BE_AMPR) // 1 -#define BE_2 S(BE_EACU) // 2 -#define BE_3 S(BE_DQUO) // 3 -#define BE_4 S(BE_QUOT) // 4 -#define BE_5 S(BE_LPRN) // 5 -#define BE_6 S(BE_SECT) // 6 -#define BE_7 S(BE_EGRV) // 7 -#define BE_8 S(BE_EXLM) // 8 -#define BE_9 S(BE_CCED) // 9 -#define BE_0 S(BE_AGRV) // 0 -#define BE_DEG S(BE_RPRN) // ° -#define BE_UNDS S(BE_MINS) // _ -#define BE_DIAE S(BE_DCIR) // ¨ (dead) -#define BE_ASTR S(BE_DLR) // * -#define BE_PERC S(BE_UGRV) // % -#define BE_PND S(BE_MICR) // £ -#define BE_RABK S(BE_LABK) // > -#define BE_QUES S(BE_COMM) // ? -#define BE_DOT S(BE_SCLN) // . -#define BE_SLSH S(BE_COLN) // / -#define BE_PLUS S(BE_EQL) // + -#define BE_PIPE ALGR(BE_AMPR) // | -#define BE_AT ALGR(BE_EACU) // @ -#define BE_HASH ALGR(BE_DQUO) // # -#define BE_CIRC ALGR(BE_SECT) // ^ -#define BE_LCBR ALGR(BE_CCED) // { -#define BE_RCBR ALGR(BE_AGRV) // } -#define BE_EURO ALGR(BE_E) // € -#define BE_LBRC ALGR(BE_DCIR) // [ -#define BE_RBRC ALGR(BE_DLR) // ] -#define BE_ACUT ALGR(BE_UGRV) // ´ (dead) -#define BE_GRV ALGR(BE_MICR) // ` (dead) -#define BE_BSLS ALGR(BE_LABK) // (backslash) -#define BE_TILD ALGR(BE_EQL) // ~ - diff --git a/quantum/keymap_extras/keymap_bepo.h b/quantum/keymap_extras/keymap_bepo.h deleted file mode 100644 index 448727deceac..000000000000 --- a/quantum/keymap_extras/keymap_bepo.h +++ /dev/null @@ -1,175 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define BP_DLR KC_GRV // $ -#define BP_DQUO KC_1 // " -#define BP_LDAQ KC_2 // « -#define BP_RDAQ KC_3 // » -#define BP_LPRN KC_4 // ( -#define BP_RPRN KC_5 // ) -#define BP_AT KC_6 // @ -#define BP_PLUS KC_7 // + -#define BP_MINS KC_8 // - -#define BP_SLSH KC_9 // / -#define BP_ASTR KC_0 // * -#define BP_EQL KC_MINS // = -#define BP_PERC KC_EQL // % -#define BP_B KC_Q // B -#define BP_EACU KC_W // É -#define BP_P KC_E // P -#define BP_O KC_R // O -#define BP_EGRV KC_T // È -#define BP_DCIR KC_Y // ^ (dead) -#define BP_V KC_U // V -#define BP_D KC_I // D -#define BP_L KC_O // L -#define BP_J KC_P // J -#define BP_Z KC_LBRC // Z -#define BP_W KC_RBRC // W -#define BP_A KC_A // A -#define BP_U KC_S // U -#define BP_I KC_D // I -#define BP_E KC_F // E -#define BP_COMM KC_G // , -#define BP_C KC_H // C -#define BP_T KC_J // T -#define BP_S KC_K // S -#define BP_R KC_L // R -#define BP_N KC_SCLN // N -#define BP_M KC_QUOT // M -#define BP_CCED KC_BSLS // Ç -#define BP_ECIR KC_NUBS // Ê -#define BP_AGRV KC_Z // À -#define BP_Y KC_X // Y -#define BP_X KC_C // X -#define BP_DOT KC_V // . -#define BP_K KC_B // K -#define BP_QUOT KC_N // ' -#define BP_Q KC_M // Q -#define BP_G KC_COMM // G -#define BP_H KC_DOT // H -#define BP_F KC_SLSH // F -#define BP_HASH S(BP_DLR) // # -#define BP_1 S(BP_DQUO) // 1 -#define BP_2 S(BP_LDAQ) // 2 -#define BP_3 S(BP_RDAQ) // 3 -#define BP_4 S(BP_LPRN) // 4 -#define BP_5 S(BP_RPRN) // 5 -#define BP_6 S(BP_AT) // 6 -#define BP_7 S(BP_PLUS) // 7 -#define BP_8 S(BP_MINS) // 8 -#define BP_9 S(BP_SLSH) // 9 -#define BP_0 S(BP_ASTR) // 0 -#define BP_DEG S(BP_EQL) // ° -#define BP_GRV S(BP_PERC) // ` -#define BP_EXLM S(BP_DCIR) // ! -#define BP_SCLN S(BP_COMM) // ; -#define BP_COLN S(BP_DOT) // : -#define BP_QUES S(BP_QUOT) // ? -#define BP_NBSP S(KC_SPC) // (non-breaking space) -#define BP_NDSH ALGR(BP_DLR) // – -#define BP_MDSH ALGR(BP_DQUO) // — -#define BP_LABK ALGR(BP_LDAQ) // < -#define BP_RABK ALGR(BP_RDAQ) // > -#define BP_LBRC ALGR(BP_LPRN) // [ -#define BP_RBRC ALGR(BP_RPRN) // ] -#define BP_CIRC ALGR(BP_AT) // ^ -#define BP_PLMN ALGR(BP_PLUS) // ± -#define BP_MMNS ALGR(BP_MINS) // − -#define BP_DIV ALGR(BP_SLSH) // ÷ -#define BP_MUL ALGR(BP_ASTR) // × -#define BP_NEQL ALGR(BP_EQL) // ≠ -#define BP_PERM ALGR(BP_PERC) // ‰ -#define BP_PIPE ALGR(BP_B) // | -#define BP_ACUT ALGR(BP_EACU) // ´ (dead) -#define BP_AMPR ALGR(BP_P) // & -#define BP_OE ALGR(BP_O) // Œ -#define BP_DGRV ALGR(BP_EGRV) // ` (dead) -#define BP_IEXL ALGR(BP_DCIR) // ¡ -#define BP_CARN ALGR(BP_V) // ˇ (dead) -#define BP_ETH ALGR(BP_D) // Ð -#define BP_DSLS ALGR(BP_L) // / (dead) -#define BP_IJ ALGR(BP_J) // IJ -#define BP_SCHW ALGR(BP_Z) // Ə -#define BP_BREV ALGR(BP_W) // ˘ (dead) -#define BP_AE ALGR(BP_A) // Æ -#define BP_UGRV ALGR(BP_U) // Ù -#define BP_DIAE ALGR(BP_I) // ¨ (dead) -#define BP_EURO ALGR(BP_E) // € -#define BP_COPY ALGR(BP_C) // © -#define BP_THRN ALGR(BP_T) // Þ -#define BP_SS ALGR(BP_S) // ẞ -#define BP_REGD ALGR(BP_R) // ® -#define BP_DTIL ALGR(BP_N) // ~ (dead) -#define BP_MACR ALGR(BP_M) // ¯ (dead) -#define BP_CEDL ALGR(BP_CCED) // ¸ (dead) -#define BP_BSLS ALGR(BP_AGRV) // (backslash) -#define BP_LCBR ALGR(BP_Y) // { -#define BP_RCBR ALGR(BP_X) // } -#define BP_ELLP ALGR(BP_DOT) // … -#define BP_TILD ALGR(BP_K) // ~ -#define BP_IQUE ALGR(BP_QUES) // ¿ -#define BP_RNGA ALGR(BP_Q) // ° (dead) -#define BP_DGRK ALGR(BP_G) // µ (dead Greek key) -#define BP_DAGG ALGR(BP_H) // † -#define BP_OGON ALGR(BP_F) // ˛ (dead) -#define BP_UNDS ALGR(KC_SPC) // _ -#define BP_PARA S(ALGR(BP_DLR)) // ¶ -#define BP_DLQU S(ALGR(BP_DQUO)) // „ -#define BP_LDQU S(ALGR(BP_LDAQ)) // “ -#define BP_RDQU S(ALGR(BP_RDAQ)) // ” -#define BP_LEQL S(ALGR(BP_LPRN)) // ≤ -#define BP_GEQL S(ALGR(BP_RPRN)) // ≥ -#define BP_NOT S(ALGR(BP_PLUS)) // ¬ -#define BP_QRTR S(ALGR(BP_MINS)) // ¼ -#define BP_HALF S(ALGR(BP_SLSH)) // ½ -#define BP_TQTR S(ALGR(BP_ASTR)) // ¾ -#define BP_PRIM S(ALGR(BP_EQL)) // ′ -#define BP_DPRM S(ALGR(BP_PERC)) // ″ -#define BP_BRKP S(ALGR(BP_B)) // ¦ -#define BP_DACU S(ALGR(BP_EACU)) // ˝ (dead) -#define BP_SECT S(ALGR(BP_P)) // § -#define BP_DOTA S(ALGR(BP_I)) // ˙ (dead) -#define BP_CURR S(ALGR(BP_E)) // ¤ (dead) -#define BP_HORN S(ALGR(BP_COMM)) // ̛ (dead) -#define BP_LNGS S(ALGR(BP_C)) // ſ -#define BP_TM S(ALGR(BP_R)) // ™ -#define BP_MORD S(ALGR(BP_M)) // º -#define BP_DCMM S(ALGR(BP_CCED)) // , (dead) -#define BP_LSQU S(ALGR(BP_Y)) // ‘ -#define BP_RSQU S(ALGR(BP_X)) // ’ -#define BP_MDDT S(ALGR(BP_DOT)) // · -#define BP_KEYB S(ALGR(BP_K)) // ⌨ -#define BP_HOKA S(ALGR(BP_QUOT)) // ̉ (dead) -#define BP_DOTB S(ALGR(BP_Q)) // ̣ (dead) -#define BP_DDAG S(ALGR(BP_H)) // ‡ -#define BP_FORD S(ALGR(BP_F)) // ª -#define BP_NNBS S(ALGR(KC_SPC)) // (narrow non-breaking space) - diff --git a/quantum/keymap_extras/keymap_brazilian_abnt2.h b/quantum/keymap_extras/keymap_brazilian_abnt2.h deleted file mode 100644 index 8fac7666c2ac..000000000000 --- a/quantum/keymap_extras/keymap_brazilian_abnt2.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define BR_QUOT KC_GRV // ' -#define BR_1 KC_1 // 1 -#define BR_2 KC_2 // 2 -#define BR_3 KC_3 // 3 -#define BR_4 KC_4 // 4 -#define BR_5 KC_5 // 5 -#define BR_6 KC_6 // 6 -#define BR_7 KC_7 // 7 -#define BR_8 KC_8 // 8 -#define BR_9 KC_9 // 9 -#define BR_0 KC_0 // 0 -#define BR_MINS KC_MINS // - -#define BR_EQL KC_EQL // = -#define BR_Q KC_Q // Q -#define BR_W KC_W // W -#define BR_E KC_E // E -#define BR_R KC_R // R -#define BR_T KC_T // T -#define BR_Y KC_Y // Y -#define BR_U KC_U // U -#define BR_I KC_I // I -#define BR_O KC_O // O -#define BR_P KC_P // P -#define BR_ACUT KC_LBRC // ´ (dead) -#define BR_LBRC KC_RBRC // [ -#define BR_A KC_A // A -#define BR_S KC_S // S -#define BR_D KC_D // D -#define BR_F KC_F // F -#define BR_G KC_G // G -#define BR_H KC_H // H -#define BR_J KC_J // J -#define BR_K KC_K // K -#define BR_L KC_L // L -#define BR_CCED KC_SCLN // Ç -#define BR_TILD KC_QUOT // ~ (dead) -#define BR_RBRC KC_BSLS // ] -#define BR_BSLS KC_NUBS // (backslash) -#define BR_Z KC_Z // Z -#define BR_X KC_X // X -#define BR_C KC_C // C -#define BR_V KC_V // V -#define BR_B KC_B // B -#define BR_N KC_N // N -#define BR_M KC_M // M -#define BR_COMM KC_COMM // , -#define BR_DOT KC_DOT // . -#define BR_SCLN KC_SLSH // ; -#define BR_SLSH KC_INT1 // / -#define BR_PDOT KC_PCMM // . -#define BR_PCMM KC_PDOT // , -#define BR_DQUO S(BR_QUOT) // " -#define BR_EXLM S(BR_1) // ! -#define BR_AT S(BR_2) // @ -#define BR_HASH S(BR_3) // # -#define BR_DLR S(BR_4) // $ -#define BR_PERC S(BR_5) // % -#define BR_DIAE S(BR_6) // ¨ (dead) -#define BR_AMPR S(BR_7) // & -#define BR_ASTR S(BR_8) // * -#define BR_LPRN S(BR_9) // ( -#define BR_RPRN S(BR_0) // ) -#define BR_UNDS S(BR_MINS) // _ -#define BR_PLUS S(BR_EQL) // + -#define BR_GRV S(BR_ACUT) // ` (dead) -#define BR_LCBR S(BR_LBRC) // { -#define BR_CIRC S(BR_TILD) // ^ (dead) -#define BR_RCBR S(BR_RBRC) // } -#define BR_PIPE S(BR_BSLS) // | -#define BR_LABK S(BR_COMM) // < -#define BR_RABK S(BR_DOT) // > -#define BR_COLN S(BR_SCLN) // : -#define BR_QUES S(BR_SLSH) // ? -#define BR_SUP1 ALGR(BR_1) // ¹ -#define BR_SUP2 ALGR(BR_2) // ² -#define BR_SUP3 ALGR(BR_3) // ³ -#define BR_PND ALGR(BR_4) // £ -#define BR_CENT ALGR(BR_5) // ¢ -#define BR_NOT ALGR(BR_6) // ¬ -#define BR_SECT ALGR(BR_EQL) // § -#define BR_DEG ALGR(BR_E) // ° -#define BR_FORD ALGR(BR_LBRC) // ª -#define BR_MORD ALGR(BR_RBRC) // º -#define BR_CRUZ ALGR(BR_C) // ₢ - diff --git a/quantum/keymap_extras/keymap_canadian_multilingual.h b/quantum/keymap_extras/keymap_canadian_multilingual.h deleted file mode 100644 index 5b9b03babb1d..000000000000 --- a/quantum/keymap_extras/keymap_canadian_multilingual.h +++ /dev/null @@ -1,174 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define CA_SLSH KC_GRV // / -#define CA_1 KC_1 // 1 -#define CA_2 KC_2 // 2 -#define CA_3 KC_3 // 3 -#define CA_4 KC_4 // 4 -#define CA_5 KC_5 // 5 -#define CA_6 KC_6 // 6 -#define CA_7 KC_7 // 7 -#define CA_8 KC_8 // 8 -#define CA_9 KC_9 // 9 -#define CA_0 KC_0 // 0 -#define CA_MINS KC_MINS // - -#define CA_EQL KC_EQL // = -#define CA_Q KC_Q // Q -#define CA_W KC_W // W -#define CA_E KC_E // E -#define CA_R KC_R // R -#define CA_T KC_T // T -#define CA_Y KC_Y // Y -#define CA_U KC_U // U -#define CA_I KC_I // I -#define CA_O KC_O // O -#define CA_P KC_P // P -#define CA_CIRC KC_LBRC // ^ (dead) -#define CA_CCED KC_RBRC // Ç -#define CA_A KC_A // A -#define CA_S KC_S // S -#define CA_D KC_D // D -#define CA_F KC_F // F -#define CA_G KC_G // G -#define CA_H KC_H // H -#define CA_J KC_J // J -#define CA_K KC_K // K -#define CA_L KC_L // L -#define CA_SCLN KC_SCLN // ; -#define CA_EGRV KC_QUOT // É -#define CA_AGRV KC_NUHS // À -#define CA_UGRV KC_NUBS // Ù -#define CA_Z KC_Z // Z -#define CA_X KC_X // X -#define CA_C KC_C // C -#define CA_V KC_V // V -#define CA_B KC_B // B -#define CA_N KC_N // N -#define CA_M KC_M // M -#define CA_COMM KC_COMM // , -#define CA_DOT KC_DOT // . -#define CA_EACU KC_SLSH // É -#define CA_BSLS S(CA_SLSH) // (backslash) -#define CA_EXLM S(CA_1) // ! -#define CA_AT S(CA_2) // @ -#define CA_HASH S(CA_3) // # -#define CA_DLR S(CA_4) // $ -#define CA_PERC S(CA_5) // % -#define CA_QUES S(CA_6) // ? -#define CA_AMPR S(CA_7) // & -#define CA_ASTR S(CA_8) // * -#define CA_LPRN S(CA_9) // ( -#define CA_RPRN S(CA_0) // ) -#define CA_UNDS S(CA_MINS) // _ -#define CA_PLUS S(CA_EQL) // + -#define CA_DIAE S(CA_CIRC) // ¨ (dead) -#define CA_COLN S(CA_SCLN) // : -#define CA_QUOT S(CA_COMM) // ' -#define CA_DQUO S(CA_DOT) // " -#define CA_PIPE ALGR(CA_SLSH) // | -#define CA_CURR ALGR(CA_4) // ¤ -#define CA_LCBR ALGR(CA_7) // { -#define CA_RCBR ALGR(CA_8) // } -#define CA_LBRC ALGR(CA_9) // [ -#define CA_RBRC ALGR(CA_0) // ] -#define CA_NOT ALGR(CA_EQL) // ¬ -#define CA_EURO ALGR(CA_E) // € -#define CA_GRV ALGR(CA_CIRC) // ` (dead) -#define CA_DTIL ALGR(CA_CCED) // ~ (dead) -#define CA_DEG ALGR(CA_SCLN) // ° -#define CA_LDAQ ALGR(CA_Z) // « -#define CA_RDAQ ALGR(CA_X) // » -#define CA_LABK ALGR(CA_COMM) // < -#define CA_RABK ALGR(CA_DOT) // > -#define CA_SUP1 RCTL(CA_1) // ¹ -#define CA_SUP2 RCTL(CA_2) // ² -#define CA_SUP3 RCTL(CA_3) // ³ -#define CA_QRTR RCTL(CA_4) // ¼ -#define CA_HALF RCTL(CA_5) // ½ -#define CA_TQTR RCTL(CA_6) // ¾ -#define CA_CEDL RCTL(CA_EQL) // ¸ (dead) -#define CA_OMEG RCTL(CA_Q) // Ω -#define CA_LSTR RCTL(CA_W) // Ł -#define CA_OE RCTL(CA_E) // Œ -#define CA_PARA RCTL(CA_R) // ¶ -#define CA_TSTR RCTL(CA_T) // Ŧ -#define CA_LARR RCTL(CA_Y) // ← -#define CA_DARR RCTL(CA_U) // ↓ -#define CA_RARR RCTL(CA_I) // → -#define CA_OSTR RCTL(CA_O) // Ø -#define CA_THRN RCTL(CA_P) // Þ -#define CA_TILD RCTL(CA_CCED) // ~ -#define CA_AE RCTL(CA_A) // Æ -#define CA_SS RCTL(CA_S) // ß -#define CA_ETH RCTL(CA_D) // Ð -#define CA_ENG RCTL(CA_G) // Ŋ -#define CA_HSTR RCTL(CA_H) // Ħ -#define CA_IJ RCTL(CA_J) // IJ -#define CA_KRA RCTL(CA_K) // ĸ -#define CA_LMDT RCTL(CA_L) // Ŀ -#define CA_ACUT RCTL(CA_SCLN) // ´ (dead) -#define CA_CENT RCTL(CA_C) // ¢ -#define CA_LDQU RCTL(CA_V) // “ -#define CA_RDQU RCTL(CA_B) // ” -#define CA_APSN RCTL(CA_N) // ʼn -#define CA_MICR RCTL(CA_M) // μ -#define CA_HRZB RCTL(CA_COMM) // ― -#define CA_DOTA RCTL(CA_DOT) // ˙ (dead) -#define CA_SHYP RCTL(S(CA_SLSH)) // ­ (soft hyphen) -#define CA_IEXL RCTL(S(CA_1)) // ¡ -#define CA_PND RCTL(S(CA_3)) // £ -#define CA_TEIG RCTL(S(CA_5)) // ⅜ -#define CA_FEIG RCTL(S(CA_6)) // ⅝ -#define CA_SEIG RCTL(S(CA_7)) // ⅞ -#define CA_TM RCTL(S(CA_8)) // ™ -#define CA_PLMN RCTL(S(CA_9)) // ± -#define CA_IQUE RCTL(S(CA_MINS)) // ¿ -#define CA_OGON RCTL(S(CA_EQL)) // ˛ (dead) -#define CA_REGD RCTL(S(CA_R)) // ® -#define CA_YEN RCTL(S(CA_Y)) // ¥ -#define CA_UARR RCTL(S(CA_U)) // ↑ -#define CA_DLSI RCTL(S(CA_I)) // ı -#define CA_RNGA RCTL(S(CA_CIRC)) // ° (dead) -#define CA_MACR RCTL(S(CA_CCED)) // ¯ (dead) -#define CA_SECT RCTL(S(CA_S)) // § -#define CA_FORD RCTL(S(CA_F)) // ª -#define CA_DACU RCTL(S(CA_SCLN)) // ˝ (dead) -#define CA_CARN RCTL(S(CA_EGRV)) // ˇ (dead) -#define CA_BREV RCTL(S(CA_AGRV)) // ˘ (dead) -#define CA_BRKP RCTL(S(CA_UGRV)) // ¦ -#define CA_COPY RCTL(S(CA_C)) // © -#define CA_LSQU RCTL(S(CA_V)) // ‘ -#define CA_RSQU RCTL(S(CA_B)) // ’ -#define CA_ENOT RCTL(S(CA_N)) // ♪ -#define CA_MORD RCTL(S(CA_M)) // º -#define CA_MUL RCTL(S(CA_COMM)) // × -#define CA_DIV RCTL(S(CA_DOT)) // ÷ - diff --git a/quantum/keymap_extras/keymap_colemak.h b/quantum/keymap_extras/keymap_colemak.h deleted file mode 100644 index d63309f010b6..000000000000 --- a/quantum/keymap_extras/keymap_colemak.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define CM_GRV KC_GRV // ` -#define CM_1 KC_1 // 1 -#define CM_2 KC_2 // 2 -#define CM_3 KC_3 // 3 -#define CM_4 KC_4 // 4 -#define CM_5 KC_5 // 5 -#define CM_6 KC_6 // 6 -#define CM_7 KC_7 // 7 -#define CM_8 KC_8 // 8 -#define CM_9 KC_9 // 9 -#define CM_0 KC_0 // 0 -#define CM_MINS KC_MINS // - -#define CM_EQL KC_EQL // = -#define CM_Q KC_Q // Q -#define CM_W KC_W // W -#define CM_F KC_E // F -#define CM_P KC_R // P -#define CM_G KC_T // G -#define CM_J KC_Y // J -#define CM_L KC_U // L -#define CM_U KC_I // U -#define CM_Y KC_O // Y -#define CM_SCLN KC_P // ; -#define CM_LBRC KC_LBRC // [ -#define CM_RBRC KC_RBRC // ] -#define CM_BSLS KC_BSLS // (backslash) -#define CM_A KC_A // A -#define CM_R KC_S // R -#define CM_S KC_D // S -#define CM_T KC_F // T -#define CM_D KC_G // D -#define CM_H KC_H // H -#define CM_N KC_J // N -#define CM_E KC_K // E -#define CM_I KC_L // I -#define CM_O KC_SCLN // O -#define CM_QUOT KC_QUOT // ' -#define CM_Z KC_Z // Z -#define CM_X KC_X // X -#define CM_C KC_C // C -#define CM_V KC_V // V -#define CM_B KC_B // B -#define CM_K KC_N // K -#define CM_M KC_M // M -#define CM_COMM KC_COMM // , -#define CM_DOT KC_DOT // . -#define CM_SLSH KC_SLSH // / -#define CM_TILD S(CM_GRV) // ~ -#define CM_EXLM S(CM_1) // ! -#define CM_AT S(CM_2) // @ -#define CM_HASH S(CM_3) // # -#define CM_DLR S(CM_4) // $ -#define CM_PERC S(CM_5) // % -#define CM_CIRC S(CM_6) // ^ -#define CM_AMPR S(CM_7) // & -#define CM_ASTR S(CM_8) // * -#define CM_LPRN S(CM_9) // ( -#define CM_RPRN S(CM_0) // ) -#define CM_UNDS S(CM_MINS) // _ -#define CM_PLUS S(CM_EQL) // + -#define CM_COLN S(CM_SCLN) // : -#define CM_LCBR S(CM_LBRC) // { -#define CM_RCBR S(CM_RBRC) // } -#define CM_PIPE S(CM_BSLS) // | -#define CM_DQUO S(CM_QUOT) // " -#define CM_LABK S(CM_COMM) // < -#define CM_RABK S(CM_DOT) // > -#define CM_QUES S(CM_SLSH) // ? - diff --git a/quantum/keymap_extras/keymap_croatian.h b/quantum/keymap_extras/keymap_croatian.h deleted file mode 100644 index 3e7c681ced91..000000000000 --- a/quantum/keymap_extras/keymap_croatian.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define HR_CEDL KC_GRV // ¸ (dead) -#define HR_1 KC_1 // 1 -#define HR_2 KC_2 // 2 -#define HR_3 KC_3 // 3 -#define HR_4 KC_4 // 4 -#define HR_5 KC_5 // 5 -#define HR_6 KC_6 // 6 -#define HR_7 KC_7 // 7 -#define HR_8 KC_8 // 8 -#define HR_9 KC_9 // 9 -#define HR_0 KC_0 // 0 -#define HR_QUOT KC_MINS // ' -#define HR_PLUS KC_EQL // + -#define HR_Q KC_Q // Q -#define HR_W KC_W // W -#define HR_E KC_E // E -#define HR_R KC_R // R -#define HR_T KC_T // T -#define HR_Z KC_Y // Z -#define HR_U KC_U // U -#define HR_I KC_I // I -#define HR_O KC_O // O -#define HR_P KC_P // P -#define HR_SCAR KC_LBRC // Š -#define HR_DSTR KC_RBRC // Đ -#define HR_A KC_A // A -#define HR_S KC_S // S -#define HR_D KC_D // D -#define HR_F KC_F // F -#define HR_G KC_G // G -#define HR_H KC_H // H -#define HR_J KC_J // J -#define HR_K KC_K // K -#define HR_L KC_L // L -#define HR_CCAR KC_SCLN // Č -#define HR_CACU KC_QUOT // Ć -#define HR_ZCAR KC_NUHS // Ž -#define HR_LABK KC_NUBS // < -#define HR_Y KC_Z // Y -#define HR_X KC_X // X -#define HR_C KC_C // C -#define HR_V KC_V // V -#define HR_B KC_B // B -#define HR_N KC_N // N -#define HR_M KC_M // M -#define HR_COMM KC_COMM // , -#define HR_DOT KC_DOT // . -#define HR_MINS KC_SLSH // - -#define HR_DIAE S(HR_CEDL) // ¨ (dead) -#define HR_EXLM S(HR_1) // ! -#define HR_DQUO S(HR_2) // " -#define HR_HASH S(HR_3) // # -#define HR_DLR S(HR_4) // $ -#define HR_PERC S(HR_5) // % -#define HR_AMPR S(HR_6) // & -#define HR_SLSH S(HR_7) // / -#define HR_LPRN S(HR_8) // ( -#define HR_RPRN S(HR_9) // ) -#define HR_EQL S(HR_0) // = -#define HR_QUES S(HR_QUOT) // ? -#define HR_ASTR S(HR_PLUS) // * -#define HR_RABK S(HR_LABK) // > -#define HR_SCLN S(HR_COMM) // ; -#define HR_COLN S(HR_DOT) // : -#define HR_UNDS S(HR_MINS) // _ -#define HR_TILD ALGR(HR_1) // ~ -#define HR_CARN ALGR(HR_2) // ˇ (dead) -#define HR_CIRC ALGR(HR_3) // ^ (dead) -#define HR_BREV ALGR(HR_4) // ˘ (dead) -#define HR_RNGA ALGR(HR_5) // ° (dead) -#define HR_OGON ALGR(HR_6) // ˛ (dead) -#define HR_GRV ALGR(HR_7) // ` -#define HR_DOTA ALGR(HR_8) // ˙ (dead) -#define HR_ACUT ALGR(HR_9) // ´ (dead) -#define HR_DACU ALGR(HR_0) // ˝ (dead) -#define HR_BSLS ALGR(HR_Q) // (backslash) -#define HR_PIPE ALGR(HR_W) // | -#define HR_EURO ALGR(HR_E) // € -#define HR_DIV ALGR(HR_SCAR) // ÷ -#define HR_MUL ALGR(HR_DSTR) // × -#define HR_LBRC ALGR(HR_F) // [ -#define HR_RBRC ALGR(HR_G) // ] -#define HR_LLST ALGR(HR_K) // ł -#define HR_CLST ALGR(HR_L) // Ł -#define HR_SS ALGR(HR_CACU) // ß -#define HR_CURR ALGR(HR_ZCAR) // ¤ -#define HR_AT ALGR(HR_V) // @ -#define HR_LCBR ALGR(HR_B) // { -#define HR_RCBR ALGR(HR_N) // } -#define HR_SECT ALGR(HR_M) // § - diff --git a/quantum/keymap_extras/keymap_czech.h b/quantum/keymap_extras/keymap_czech.h deleted file mode 100644 index 351c51ad411b..000000000000 --- a/quantum/keymap_extras/keymap_czech.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define CZ_SCLN KC_GRV // ; -#define CZ_PLUS KC_1 // + -#define CZ_ECAR KC_2 // ě -#define CZ_SCAR KC_3 // š -#define CZ_CCAR KC_4 // č -#define CZ_RCAR KC_5 // ř -#define CZ_ZCAR KC_6 // ž -#define CZ_YACU KC_7 // ý -#define CZ_AACU KC_8 // á -#define CZ_IACU KC_9 // í -#define CZ_EACU KC_0 // é -#define CZ_EQL KC_MINS // = -#define CZ_ACUT KC_EQL // ´ (dead) -#define CZ_Q KC_Q // Q -#define CZ_W KC_W // W -#define CZ_E KC_E // E -#define CZ_R KC_R // R -#define CZ_T KC_T // T -#define CZ_Z KC_Y // Z -#define CZ_U KC_U // U -#define CZ_I KC_I // I -#define CZ_O KC_O // O -#define CZ_P KC_P // P -#define CZ_UACU KC_LBRC // ú -#define CZ_RPRN KC_RBRC // ) -#define CZ_A KC_A // A -#define CZ_S KC_S // S -#define CZ_D KC_D // D -#define CZ_F KC_F // F -#define CZ_G KC_G // G -#define CZ_H KC_H // H -#define CZ_J KC_J // J -#define CZ_K KC_K // K -#define CZ_L KC_L // L -#define CZ_URNG KC_SCLN // ů -#define CZ_SECT KC_QUOT // § -#define CZ_DIAE KC_NUHS // ¨ (dead) -#define CZ_BSLS KC_NUBS // (backslash) -#define CZ_Y KC_Z // Y -#define CZ_X KC_X // X -#define CZ_C KC_C // C -#define CZ_V KC_V // V -#define CZ_B KC_B // B -#define CZ_N KC_N // N -#define CZ_M KC_M // M -#define CZ_COMM KC_COMM // , -#define CZ_DOT KC_DOT // . -#define CZ_MINS KC_SLSH // - -#define CZ_RNGA S(CZ_SCLN) // ° (dead) -#define CZ_1 S(CZ_PLUS) // 1 -#define CZ_2 S(CZ_ECAR) // 2 -#define CZ_3 S(CZ_SCAR) // 3 -#define CZ_4 S(CZ_CCAR) // 4 -#define CZ_5 S(CZ_RCAR) // 5 -#define CZ_6 S(CZ_ZCAR) // 6 -#define CZ_7 S(CZ_YACU) // 7 -#define CZ_8 S(CZ_AACU) // 8 -#define CZ_9 S(CZ_IACU) // 9 -#define CZ_0 S(CZ_EACU) // 0 -#define CZ_PERC S(CZ_EQL) // % -#define CZ_CARN S(CZ_ACUT) // ˇ (dead) -#define CZ_SLSH S(CZ_UACU) // / -#define CZ_LPRN S(CZ_RPRN) // ( -#define CZ_DQUO S(CZ_URNG) // " -#define CZ_EXLM S(CZ_SECT) // ! -#define CZ_QUOT S(CZ_DIAE) // ' -#define CZ_PIPE S(CZ_BSLS) // | -#define CZ_QUES S(CZ_COMM) // ? -#define CZ_COLN S(CZ_DOT) // : -#define CZ_UNDS S(CZ_MINS) // _ -#define CZ_TILD ALGR(CZ_PLUS) // ~ -#define CZ_CIRC ALGR(CZ_SCAR) // ^ (dead) -#define CZ_BREV ALGR(CZ_CCAR) // ˘ (dead) -#define CZ_OGON ALGR(CZ_ZCAR) // ˛ (dead) -#define CZ_GRV ALGR(CZ_YACU) // ` (dead) -#define CZ_DOTA ALGR(CZ_AACU) // ˙ (dead) -#define CZ_DACU ALGR(CZ_EACU) // ˝ (dead) -#define CZ_CEDL ALGR(CZ_ACUT) // ¸ (dead) -#define CZ_EURO ALGR(CZ_E) // € -#define CZ_DIV ALGR(CZ_UACU) // ÷ -#define CZ_MUL ALGR(CZ_RPRN) // × -#define CZ_LDST ALGR(CZ_S) // đ -#define CZ_CDST ALGR(CZ_D) // Đ -#define CZ_LBRC ALGR(CZ_F) // [ -#define CZ_RBRC ALGR(CZ_G) // ] -#define CZ_LLST ALGR(CZ_K) // ł -#define CZ_CLST ALGR(CZ_L) // Ł -#define CZ_DLR ALGR(CZ_URNG) // $ -#define CZ_SS ALGR(CZ_SECT) // ß -#define CZ_CURR ALGR(CZ_DIAE) // ¤ -#define CZ_HASH ALGR(CZ_X) // # -#define CZ_AMPR ALGR(CZ_C) // & -#define CZ_AT ALGR(CZ_V) // @ -#define CZ_LCBR ALGR(CZ_B) // { -#define CZ_RCBR ALGR(CZ_N) // } -#define CZ_LABK ALGR(CZ_COMM) // < -#define CZ_RABK ALGR(CZ_DOT) // > -#define CZ_ASTR ALGR(CZ_MINS) // * - diff --git a/quantum/keymap_extras/keymap_danish.h b/quantum/keymap_extras/keymap_danish.h deleted file mode 100644 index cea9444896b3..000000000000 --- a/quantum/keymap_extras/keymap_danish.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DK_HALF KC_GRV // ½ -#define DK_1 KC_1 // 1 -#define DK_2 KC_2 // 2 -#define DK_3 KC_3 // 3 -#define DK_4 KC_4 // 4 -#define DK_5 KC_5 // 5 -#define DK_6 KC_6 // 6 -#define DK_7 KC_7 // 7 -#define DK_8 KC_8 // 8 -#define DK_9 KC_9 // 9 -#define DK_0 KC_0 // 0 -#define DK_PLUS KC_MINS // + -#define DK_ACUT KC_EQL // ´ (dead) -#define DK_Q KC_Q // Q -#define DK_W KC_W // W -#define DK_E KC_E // E -#define DK_R KC_R // R -#define DK_T KC_T // T -#define DK_Y KC_Y // Y -#define DK_U KC_U // U -#define DK_I KC_I // I -#define DK_O KC_O // O -#define DK_P KC_P // P -#define DK_ARNG KC_LBRC // Å -#define DK_DIAE KC_RBRC // ¨ (dead) -#define DK_A KC_A // A -#define DK_S KC_S // S -#define DK_D KC_D // D -#define DK_F KC_F // F -#define DK_G KC_G // G -#define DK_H KC_H // H -#define DK_J KC_J // J -#define DK_K KC_K // K -#define DK_L KC_L // L -#define DK_AE KC_SCLN // Æ -#define DK_OSTR KC_QUOT // Ø -#define DK_QUOT KC_NUHS // ' -#define DK_LABK KC_NUBS // < -#define DK_Z KC_Z // Z -#define DK_X KC_X // X -#define DK_C KC_C // C -#define DK_V KC_V // V -#define DK_B KC_B // B -#define DK_N KC_N // N -#define DK_M KC_M // M -#define DK_COMM KC_COMM // , -#define DK_DOT KC_DOT // . -#define DK_MINS KC_SLSH // - -#define DK_SECT S(DK_HALF) // § -#define DK_EXLM S(DK_1) // ! -#define DK_DQUO S(DK_2) // " -#define DK_HASH S(DK_3) // # -#define DK_CURR S(DK_4) // ¤ -#define DK_PERC S(DK_5) // % -#define DK_AMPR S(DK_6) // & -#define DK_SLSH S(DK_7) // / -#define DK_LPRN S(DK_8) // ( -#define DK_RPRN S(DK_9) // ) -#define DK_EQL S(DK_0) // = -#define DK_QUES S(DK_PLUS) // ? -#define DK_GRV S(DK_ACUT) // ` (dead) -#define DK_CIRC S(DK_DIAE) // ^ (dead) -#define DK_ASTR S(DK_QUOT) // * -#define DK_RABK S(DK_LABK) // > -#define DK_SCLN S(DK_COMM) // ; -#define DK_COLN S(DK_DOT) // : -#define DK_UNDS S(DK_MINS) // _ -#define DK_AT ALGR(DK_2) // @ -#define DK_PND ALGR(DK_3) // £ -#define DK_DLR ALGR(DK_4) // $ -#define DK_EURO ALGR(DK_5) // € -#define DK_LCBR ALGR(DK_7) // { -#define DK_LBRC ALGR(DK_8) // [ -#define DK_RBRC ALGR(DK_9) // ] -#define DK_RCBR ALGR(DK_0) // } -#define DK_PIPE ALGR(DK_ACUT) // | -#define DK_TILD ALGR(DK_DIAE) // ~ (dead) -#define DK_BSLS ALGR(DK_LABK) // (backslash) -#define DK_MICR ALGR(DK_M) // µ - diff --git a/quantum/keymap_extras/keymap_dvorak.h b/quantum/keymap_extras/keymap_dvorak.h deleted file mode 100644 index 9205a72057f5..000000000000 --- a/quantum/keymap_extras/keymap_dvorak.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DV_GRV KC_GRV // ` -#define DV_1 KC_1 // 1 -#define DV_2 KC_2 // 2 -#define DV_3 KC_3 // 3 -#define DV_4 KC_4 // 4 -#define DV_5 KC_5 // 5 -#define DV_6 KC_6 // 6 -#define DV_7 KC_7 // 7 -#define DV_8 KC_8 // 8 -#define DV_9 KC_9 // 9 -#define DV_0 KC_0 // 0 -#define DV_LBRC KC_MINS // [ -#define DV_RBRC KC_EQL // ] -#define DV_QUOT KC_Q // ' -#define DV_COMM KC_W // , -#define DV_DOT KC_E // . -#define DV_P KC_R // P -#define DV_Y KC_T // Y -#define DV_F KC_Y // F -#define DV_G KC_U // G -#define DV_C KC_I // C -#define DV_R KC_O // R -#define DV_L KC_P // L -#define DV_SLSH KC_LBRC // / -#define DV_EQL KC_RBRC // = -#define DV_BSLS KC_BSLS // (backslash) -#define DV_A KC_A // A -#define DV_O KC_S // O -#define DV_E KC_D // E -#define DV_U KC_F // U -#define DV_I KC_G // I -#define DV_D KC_H // D -#define DV_H KC_J // H -#define DV_T KC_K // T -#define DV_N KC_L // N -#define DV_S KC_SCLN // S -#define DV_MINS KC_QUOT // - -#define DV_SCLN KC_Z // ; -#define DV_Q KC_X // Q -#define DV_J KC_C // J -#define DV_K KC_V // K -#define DV_X KC_B // X -#define DV_B KC_N // B -#define DV_M KC_M // M -#define DV_W KC_COMM // W -#define DV_V KC_DOT // V -#define DV_Z KC_SLSH // Z -#define DV_TILD S(DV_GRV) // ~ -#define DV_EXLM S(DV_1) // ! -#define DV_AT S(DV_2) // @ -#define DV_HASH S(DV_3) // # -#define DV_DLR S(DV_4) // $ -#define DV_PERC S(DV_5) // % -#define DV_CIRC S(DV_6) // ^ -#define DV_AMPR S(DV_7) // & -#define DV_ASTR S(DV_8) // * -#define DV_LPRN S(DV_9) // ( -#define DV_RPRN S(DV_0) // ) -#define DV_LCBR S(DV_LBRC) // { -#define DV_RCBR S(DV_RBRC) // } -#define DV_DQUO S(DV_QUOT) // " -#define DV_LABK S(DV_COMM) // < -#define DV_RABK S(DV_DOT) // > -#define DV_QUES S(DV_SLSH) // ? -#define DV_PLUS S(DV_EQL) // + -#define DV_PIPE S(DV_BSLS) // | -#define DV_UNDS S(DV_MINS) // _ -#define DV_COLN S(DV_SCLN) // : - diff --git a/quantum/keymap_extras/keymap_dvorak_fr.h b/quantum/keymap_extras/keymap_dvorak_fr.h deleted file mode 100644 index b206767614e9..000000000000 --- a/quantum/keymap_extras/keymap_dvorak_fr.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DV_LDAQ KC_GRV // « -#define DV_RDAQ KC_1 // » -#define DV_SLSH KC_2 // / -#define DV_MINS KC_3 // - -#define DV_EGRV KC_4 // è -#define DV_BSLS KC_5 // (backslash) -#define DV_CIRC KC_6 // ^ (dead) -#define DV_LPRN KC_7 // ( -#define DV_GRV KC_8 // ` (dead) -#define DV_RPRN KC_9 // ) -#define DV_UNDS KC_0 // _ -#define DV_LBRC KC_MINS // [ -#define DV_RBRC KC_EQL // ] -#define DV_COLN KC_Q // : -#define DV_QUOT KC_W // ' -#define DV_EACU KC_E // é -#define DV_G KC_R // G -#define DV_DOT KC_T // . -#define DV_H KC_Y // H -#define DV_V KC_U // V -#define DV_C KC_I // C -#define DV_M KC_O // M -#define DV_K KC_P // K -#define DV_Z KC_LBRC // Z -#define DV_DIAE KC_RBRC // ¨ (dead) -#define DV_O KC_A // O -#define DV_A KC_S // A -#define DV_U KC_D // U -#define DV_E KC_F // E -#define DV_B KC_G // B -#define DV_F KC_H // F -#define DV_S KC_J // S -#define DV_T KC_K // T -#define DV_N KC_L // N -#define DV_D KC_SCLN // D -#define DV_W KC_QUOT // W -#define DV_TILD KC_NUHS // ~ (dead) -#define DV_AGRV KC_NUBS // à -#define DV_SCLN KC_Z // ; -#define DV_Q KC_X // Q -#define DV_COMM KC_C // , -#define DV_I KC_V // I -#define DV_Y KC_B // Y -#define DV_X KC_N // X -#define DV_R KC_M // R -#define DV_L KC_COMM // L -#define DV_P KC_DOT // P -#define DV_J KC_SLSH // J -#define DV_ASTR S(DV_LDAQ) // * -#define DV_1 S(DV_RDAQ) // 1 -#define DV_2 S(DV_SLSH) // 2 -#define DV_3 S(DV_MINS) // 3 -#define DV_4 S(DV_EGRV) // 4 -#define DV_5 S(DV_BSLS) // 5 -#define DV_6 S(DV_CIRC) // 6 -#define DV_7 S(DV_LPRN) // 7 -#define DV_8 S(DV_GRV) // 8 -#define DV_9 S(DV_RPRN) // 9 -#define DV_0 S(DV_UNDS) // 0 -#define DV_PLUS S(DV_LBRC) // + -#define DV_PERC S(DV_RBRC) // % -#define DV_QUES S(DV_COLN) // ? -#define DV_LABK S(DV_QUOT) // < -#define DV_RABK S(DV_EACU) // > -#define DV_EXLM S(DV_DOT) // ! -#define DV_EQL S(DV_DIAE) // = -#define DV_HASH S(DV_TILD) // # -#define DV_CCED S(DV_AGRV) // ç -#define DV_PIPE S(DV_SCLN) // | -#define DV_AT S(DV_COMM) // @ - diff --git a/quantum/keymap_extras/keymap_dvorak_programmer.h b/quantum/keymap_extras/keymap_dvorak_programmer.h deleted file mode 100644 index 19187ed13b09..000000000000 --- a/quantum/keymap_extras/keymap_dvorak_programmer.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DP_DLR KC_GRV // $ -#define DP_AMPR KC_1 // & -#define DP_LBRC KC_2 // [ -#define DP_LCBR KC_3 // { -#define DP_RCBR KC_4 // } -#define DP_LPRN KC_5 // ( -#define DP_EQL KC_6 // = -#define DP_ASTR KC_7 // * -#define DP_RPRN KC_8 // ) -#define DP_PLUS KC_9 // + -#define DP_RBRC KC_0 // ] -#define DP_EXLM KC_MINS // ! -#define DP_HASH KC_EQL // # -#define DP_SCLN KC_Q // ; -#define DP_COMM KC_W // , -#define DP_DOT KC_E // . -#define DP_P KC_R // P -#define DP_Y KC_T // Y -#define DP_F KC_Y // F -#define DP_G KC_U // G -#define DP_C KC_I // C -#define DP_R KC_O // R -#define DP_L KC_P // L -#define DP_SLSH KC_LBRC // / -#define DP_AT KC_RBRC // @ -#define DP_BSLS KC_BSLS // (backslash) -#define DP_A KC_A // A -#define DP_O KC_S // O -#define DP_E KC_D // E -#define DP_U KC_F // U -#define DP_I KC_G // I -#define DP_D KC_H // D -#define DP_H KC_J // H -#define DP_T KC_K // T -#define DP_N KC_L // N -#define DP_S KC_SCLN // S -#define DP_MINS KC_QUOT // - -#define DP_QUOT KC_Z // ' -#define DP_Q KC_X // Q -#define DP_J KC_C // J -#define DP_K KC_V // K -#define DP_X KC_B // X -#define DP_B KC_N // B -#define DP_M KC_M // M -#define DP_W KC_COMM // W -#define DP_V KC_DOT // V -#define DP_Z KC_SLSH // Z -#define DP_TILD S(DP_DLR) // ~ -#define DP_PERC S(DP_AMPR) // % -#define DP_7 S(DP_LBRC) // 7 -#define DP_5 S(DP_LCBR) // 5 -#define DP_3 S(DP_RCBR) // 3 -#define DP_1 S(DP_LPRN) // 1 -#define DP_9 S(DP_EQL) // 9 -#define DP_0 S(DP_ASTR) // 0 -#define DP_2 S(DP_RPRN) // 2 -#define DP_4 S(DP_PLUS) // 4 -#define DP_6 S(DP_RBRC) // 6 -#define DP_8 S(DP_EXLM) // 8 -#define DP_GRV S(DP_HASH) // ` -#define DP_COLN S(DP_SCLN) // : -#define DP_LABK S(DP_COMM) // < -#define DP_RABK S(DP_DOT) // > -#define DP_QUES S(DP_SLSH) // ? -#define DP_CIRC S(DP_AT) // ^ -#define DP_PIPE S(DP_BSLS) // | -#define DP_UNDS S(DP_MINS) // _ -#define DP_DQUO S(DP_QUOT) // " - diff --git a/quantum/keymap_extras/keymap_estonian.h b/quantum/keymap_extras/keymap_estonian.h deleted file mode 100644 index ea9c56c12ac5..000000000000 --- a/quantum/keymap_extras/keymap_estonian.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define EE_CARN KC_GRV // ˇ (dead) -#define EE_1 KC_1 // 1 -#define EE_2 KC_2 // 2 -#define EE_3 KC_3 // 3 -#define EE_4 KC_4 // 4 -#define EE_5 KC_5 // 5 -#define EE_6 KC_6 // 6 -#define EE_7 KC_7 // 7 -#define EE_8 KC_8 // 8 -#define EE_9 KC_9 // 9 -#define EE_0 KC_0 // 0 -#define EE_PLUS KC_MINS // + -#define EE_ACUT KC_EQL // ´ (dead) -#define EE_Q KC_Q // Q -#define EE_W KC_W // W -#define EE_E KC_E // E -#define EE_R KC_R // R -#define EE_T KC_T // T -#define EE_Y KC_Y // Y -#define EE_U KC_U // U -#define EE_I KC_I // I -#define EE_O KC_O // O -#define EE_P KC_P // P -#define EE_UDIA KC_LBRC // Ü -#define EE_OTIL KC_RBRC // Õ -#define EE_A KC_A // A -#define EE_S KC_S // S -#define EE_D KC_D // D -#define EE_F KC_F // F -#define EE_G KC_G // G -#define EE_H KC_H // H -#define EE_J KC_J // J -#define EE_K KC_K // K -#define EE_L KC_L // L -#define EE_ODIA KC_SCLN // Ö -#define EE_ADIA KC_QUOT // Ä -#define EE_QUOT KC_NUHS // ' -#define EE_LABK KC_NUBS // < -#define EE_Z KC_Z // Z -#define EE_X KC_X // X -#define EE_C KC_C // C -#define EE_V KC_V // V -#define EE_B KC_B // B -#define EE_N KC_N // N -#define EE_M KC_M // M -#define EE_COMM KC_COMM // , -#define EE_DOT KC_DOT // . -#define EE_MINS KC_SLSH // - -#define EE_TILD S(EE_CARN) // ~ (dead) -#define EE_EXLM S(EE_1) // ! -#define EE_DQUO S(EE_2) // " -#define EE_HASH S(EE_3) // # -#define EE_CURR S(EE_4) // ¤ -#define EE_PERC S(EE_5) // % -#define EE_AMPR S(EE_6) // & -#define EE_SLSH S(EE_7) // / -#define EE_LPRN S(EE_8) // ( -#define EE_RPRN S(EE_9) // ) -#define EE_EQL S(EE_0) // = -#define EE_QUES S(EE_PLUS) // ? -#define EE_GRV S(EE_ACUT) // ` (dead) -#define EE_ASTR S(EE_QUOT) // * -#define EE_RABK S(EE_LABK) // > -#define EE_SCLN S(EE_COMM) // ; -#define EE_COLN S(EE_DOT) // : -#define EE_UNDS S(EE_MINS) // _ -#define EE_AT ALGR(EE_2) // @ -#define EE_PND ALGR(EE_3) // £ -#define EE_DLR ALGR(EE_4) // $ -#define EE_EURO ALGR(EE_5) // € -#define EE_LCBR ALGR(EE_7) // { -#define EE_LBRC ALGR(EE_8) // [ -#define EE_RBRC ALGR(EE_9) // ] -#define EE_RCBR ALGR(EE_0) // } -#define EE_BSLS ALGR(EE_PLUS) // (backslash) -#define EE_SECT ALGR(EE_OTIL) // § -#define EE_SCAR ALGR(EE_S) // š -#define EE_CIRC ALGR(EE_ADIA) // ^ (dead) -#define EE_HALF ALGR(EE_QUOT) // ½ -#define EE_PIPE ALGR(EE_LABK) // | -#define EE_ZCAR ALGR(EE_Z) // ž - diff --git a/quantum/keymap_extras/keymap_finnish.h b/quantum/keymap_extras/keymap_finnish.h deleted file mode 100644 index c0dc1af81ec2..000000000000 --- a/quantum/keymap_extras/keymap_finnish.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define FI_SECT KC_GRV // § -#define FI_1 KC_1 // 1 -#define FI_2 KC_2 // 2 -#define FI_3 KC_3 // 3 -#define FI_4 KC_4 // 4 -#define FI_5 KC_5 // 5 -#define FI_6 KC_6 // 6 -#define FI_7 KC_7 // 7 -#define FI_8 KC_8 // 8 -#define FI_9 KC_9 // 9 -#define FI_0 KC_0 // 0 -#define FI_PLUS KC_MINS // + -#define FI_ACUT KC_EQL // ´ (dead) -#define FI_Q KC_Q // Q -#define FI_W KC_W // W -#define FI_E KC_E // E -#define FI_R KC_R // R -#define FI_T KC_T // T -#define FI_Y KC_Y // Y -#define FI_U KC_U // U -#define FI_I KC_I // I -#define FI_O KC_O // O -#define FI_P KC_P // P -#define FI_ARNG KC_LBRC // Å -#define FI_DIAE KC_RBRC // ¨ (dead) -#define FI_A KC_A // A -#define FI_S KC_S // S -#define FI_D KC_D // D -#define FI_F KC_F // F -#define FI_G KC_G // G -#define FI_H KC_H // H -#define FI_J KC_J // J -#define FI_K KC_K // K -#define FI_L KC_L // L -#define FI_ODIA KC_SCLN // Ö -#define FI_ADIA KC_QUOT // Ä -#define FI_QUOT KC_NUHS // ' -#define FI_LABK KC_NUBS // < -#define FI_Z KC_Z // Z -#define FI_X KC_X // X -#define FI_C KC_C // C -#define FI_V KC_V // V -#define FI_B KC_B // B -#define FI_N KC_N // N -#define FI_M KC_M // M -#define FI_COMM KC_COMM // , -#define FI_DOT KC_DOT // . -#define FI_MINS KC_SLSH // - -#define FI_HALF S(FI_SECT) // ½ -#define FI_EXLM S(FI_1) // ! -#define FI_DQUO S(FI_2) // " -#define FI_HASH S(FI_3) // # -#define FI_CURR S(FI_4) // ¤ -#define FI_PERC S(FI_5) // % -#define FI_AMPR S(FI_6) // & -#define FI_SLSH S(FI_7) // / -#define FI_LPRN S(FI_8) // ( -#define FI_RPRN S(FI_9) // ) -#define FI_EQL S(FI_0) // = -#define FI_QUES S(FI_PLUS) // ? -#define FI_GRV S(FI_ACUT) // ` (dead) -#define FI_CIRC S(FI_DIAE) // ^ (dead) -#define FI_ASTR S(FI_QUOT) // * -#define FI_RABK S(FI_LABK) // > -#define FI_SCLN S(FI_COMM) // ; -#define FI_COLN S(FI_DOT) // : -#define FI_UNDS S(FI_MINS) // _ -#define FI_AT ALGR(FI_2) // @ -#define FI_PND ALGR(FI_3) // £ -#define FI_DLR ALGR(FI_4) // $ -#define FI_EURO ALGR(FI_5) // € -#define FI_LCBR ALGR(FI_7) // { -#define FI_LBRC ALGR(FI_8) // [ -#define FI_RBRC ALGR(FI_9) // ] -#define FI_RCBR ALGR(FI_0) // } -#define FI_BSLS ALGR(FI_PLUS) // (backslash) -#define FI_TILD ALGR(FI_DIAE) // ~ (dead) -#define FI_PIPE ALGR(FI_LABK) // | -#define FI_MICR ALGR(FI_M) // µ - diff --git a/quantum/keymap_extras/keymap_french.h b/quantum/keymap_extras/keymap_french.h deleted file mode 100644 index 03dbb7bc40d0..000000000000 --- a/quantum/keymap_extras/keymap_french.h +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define FR_SUP2 KC_GRV // ² -#define FR_AMPR KC_1 // & -#define FR_EACU KC_2 // é -#define FR_DQUO KC_3 // " -#define FR_QUOT KC_4 // ' -#define FR_LPRN KC_5 // ( -#define FR_MINS KC_6 // - -#define FR_EGRV KC_7 // è -#define FR_UNDS KC_8 // _ -#define FR_CCED KC_9 // ç -#define FR_AGRV KC_0 // à -#define FR_RPRN KC_MINS // ) -#define FR_EQL KC_EQL // = -#define FR_A KC_Q // A -#define FR_Z KC_W // Z -#define FR_E KC_E // E -#define FR_R KC_R // R -#define FR_T KC_T // T -#define FR_Y KC_Y // Y -#define FR_U KC_U // U -#define FR_I KC_I // I -#define FR_O KC_O // O -#define FR_P KC_P // P -#define FR_CIRC KC_LBRC // ^ (dead) -#define FR_DLR KC_RBRC // $ -#define FR_Q KC_A // Q -#define FR_S KC_S // S -#define FR_D KC_D // D -#define FR_F KC_F // F -#define FR_G KC_G // G -#define FR_H KC_H // H -#define FR_J KC_J // J -#define FR_K KC_K // K -#define FR_L KC_L // L -#define FR_M KC_SCLN // M -#define FR_UGRV KC_QUOT // ù -#define FR_ASTR KC_NUHS // * -#define FR_LABK KC_NUBS // < -#define FR_W KC_Z // W -#define FR_X KC_X // X -#define FR_C KC_C // C -#define FR_V KC_V // V -#define FR_B KC_B // B -#define FR_N KC_N // N -#define FR_COMM KC_M // , -#define FR_SCLN KC_COMM // ; -#define FR_COLN KC_DOT // : -#define FR_EXLM KC_SLSH // ! -#define FR_1 S(FR_AMPR) // 1 -#define FR_2 S(FR_EACU) // 2 -#define FR_3 S(FR_DQUO) // 3 -#define FR_4 S(FR_QUOT) // 4 -#define FR_5 S(FR_LPRN) // 5 -#define FR_6 S(FR_MINS) // 6 -#define FR_7 S(FR_EGRV) // 7 -#define FR_8 S(FR_UNDS) // 8 -#define FR_9 S(FR_CCED) // 9 -#define FR_0 S(FR_AGRV) // 0 -#define FR_DEG S(FR_RPRN) // ° -#define FR_PLUS S(FR_EQL) // + -#define FR_DIAE S(FR_CIRC) // ¨ (dead) -#define FR_PND S(FR_DLR) // £ -#define FR_PERC S(FR_UGRV) // % -#define FR_MICR S(FR_ASTR) // µ -#define FR_RABK S(FR_LABK) // > -#define FR_QUES S(FR_COMM) // ? -#define FR_DOT S(FR_SCLN) // . -#define FR_SLSH S(FR_COLN) // / -#define FR_SECT S(FR_EXLM) // § -#define FR_TILD ALGR(FR_EACU) // ~ (dead) -#define FR_HASH ALGR(FR_DQUO) // # -#define FR_LCBR ALGR(FR_QUOT) // { -#define FR_LBRC ALGR(FR_LPRN) // [ -#define FR_PIPE ALGR(FR_MINS) // | -#define FR_GRV ALGR(FR_EGRV) // ` (dead) -#define FR_BSLS ALGR(FR_UNDS) // (backslash) -#define FR_AT ALGR(FR_AGRV) // @ -#define FR_RBRC ALGR(FR_RPRN) // ] -#define FR_RCBR ALGR(FR_EQL) // } -#define FR_EURO ALGR(KC_E) // € -#define FR_CURR ALGR(FR_DLR) // ¤ - diff --git a/quantum/keymap_extras/keymap_french_afnor.h b/quantum/keymap_extras/keymap_french_afnor.h deleted file mode 100644 index 869984c4d2e1..000000000000 --- a/quantum/keymap_extras/keymap_french_afnor.h +++ /dev/null @@ -1,167 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define FR_AT KC_GRV // @ -#define FR_AGRV KC_1 // à -#define FR_EACU KC_2 // é -#define FR_EGRV KC_3 // è -#define FR_ECIR KC_4 // ê -#define FR_LPRN KC_5 // ( -#define FR_RPRN KC_6 // ) -#define FR_LSQU KC_7 // ‘ -#define FR_RSQU KC_8 // ’ -#define FR_LDAQ KC_9 // « -#define FR_RDAQ KC_0 // » -#define FR_QUOT KC_MINS // ' -#define FR_DCIR KC_EQL // ^ (dead) -#define FR_A KC_Q // A -#define FR_Z KC_W // Z -#define FR_E KC_E // E -#define FR_R KC_R // R -#define FR_T KC_T // T -#define FR_Y KC_Y // Y -#define FR_U KC_U // U -#define FR_I KC_I // I -#define FR_O KC_O // O -#define FR_P KC_P // P -#define FR_MINS KC_LBRC // - -#define FR_PLUS KC_RBRC // + -#define FR_Q KC_A // Q -#define FR_S KC_S // S -#define FR_D KC_D // D -#define FR_F KC_F // F -#define FR_G KC_G // G -#define FR_H KC_H // H -#define FR_J KC_J // J -#define FR_K KC_K // K -#define FR_L KC_L // L -#define FR_M KC_SCLN // M -#define FR_SLSH KC_QUOT // / -#define FR_ASTR KC_NUHS // * -#define FR_LABK KC_NUBS // < -#define FR_W KC_Z // W -#define FR_X KC_X // X -#define FR_C KC_C // C -#define FR_V KC_V // V -#define FR_B KC_B // B -#define FR_N KC_N // N -#define FR_DOT KC_M // . -#define FR_COMM KC_COMM // , -#define FR_COLN KC_DOT // : -#define FR_SCLN KC_SLSH // ; -#define FR_HASH S(FR_AT) // # -#define FR_1 S(FR_AGRV) // 1 -#define FR_2 S(FR_EACU) // 2 -#define FR_3 S(FR_EGRV) // 3 -#define FR_4 S(FR_ECIR) // 4 -#define FR_5 S(FR_LPRN) // 5 -#define FR_6 S(FR_RPRN) // 6 -#define FR_7 S(FR_LSQU) // 7 -#define FR_8 S(FR_RSQU) // 8 -#define FR_9 S(FR_LDAQ) // 9 -#define FR_0 S(FR_RDAQ) // 0 -#define FR_DQUO S(FR_QUOT) // " -#define FR_DIAE S(FR_DCIR) // ¨ (dead) -#define FR_NDSH S(FR_MINS) // – -#define FR_PLMN S(FR_PLUS) // ± -#define FR_BSLS S(FR_SLSH) // (backslash) -#define FR_HALF S(FR_ASTR) // ½ -#define FR_RABK S(FR_LABK) // > -#define FR_QUES S(FR_DOT) // ? -#define FR_EXLM S(FR_COMM) // ! -#define FR_ELLP S(FR_COLN) // … -#define FR_EQL S(FR_SCLN) // = -#define FR_BREV ALGR(FR_AT) // ˘ (dead) -#define FR_SECT ALGR(FR_AGRV) // § -#define FR_ACUT ALGR(FR_EACU) // ´ (dead) -#define FR_GRV ALGR(FR_EGRV) // ` (dead) -#define FR_AMPR ALGR(FR_ECIR) // & -#define FR_LBRC ALGR(FR_LPRN) // [ -#define FR_RBRC ALGR(FR_RPRN) // ] -#define FR_MACR ALGR(FR_LSQU) // ¯ (dead) -#define FR_UNDS ALGR(FR_RSQU) // _ -#define FR_LDQU ALGR(FR_LDAQ) // “ -#define FR_RDQU ALGR(FR_RDAQ) // ” -#define FR_DEG ALGR(FR_QUOT) // ° -#define FR_CARN ALGR(FR_DCIR) // ˇ (dead) -#define FR_AE ALGR(FR_A) // æ -#define FR_PND ALGR(FR_Z) // £ -#define FR_EURO ALGR(FR_E) // € -#define FR_REGD ALGR(FR_R) // ® -#define FR_LCBR ALGR(FR_T) // { -#define FR_RCBR ALGR(FR_Y) // } -#define FR_UGRV ALGR(FR_U) // ù -#define FR_DOTA ALGR(FR_I) // ˙ (dead) -#define FR_OE ALGR(FR_O) // œ -#define FR_PERC ALGR(FR_P) // % -#define FR_MMNS ALGR(FR_MINS) // − -#define FR_DAGG ALGR(FR_PLUS) // † -#define FR_THET ALGR(FR_Q) // θ -#define FR_SS ALGR(FR_S) // ß -#define FR_DLR ALGR(FR_D) // $ -#define FR_CURR ALGR(FR_F) // ¤ (dead monetary key) -#define FR_DGRK ALGR(FR_G) // µ (dead Greek key) -#define FR_EU ALGR(FR_H) // Eu (dead European symbol key) -#define FR_DSLS ALGR(FR_K) // ∕ (dead) -#define FR_PIPE ALGR(FR_L) // | -#define FR_INFN ALGR(FR_M) // ∞ -#define FR_DIV ALGR(FR_SLSH) // ÷ -#define FR_MUL ALGR(FR_ASTR) // × -#define FR_LEQL ALGR(FR_LABK) // ≤ -#define FR_EZH ALGR(FR_W) // ʒ -#define FR_COPY ALGR(FR_X) // © -#define FR_CCED ALGR(FR_C) // ç -#define FR_CEDL ALGR(FR_V) // ¸ (dead) -#define FR_DMNS ALGR(FR_B) // − (dead) -#define FR_DTIL ALGR(FR_N) // ~ (dead) -#define FR_IQUE ALGR(FR_DOT) // ¿ -#define FR_IEXL ALGR(FR_COMM) // ¡ -#define FR_MDDT ALGR(FR_COLN) // · -#define FR_AEQL ALGR(FR_SCLN) // ≃ -#define FR_IBRV S(ALGR(FR_AT)) // ̑ (dead) -#define FR_DACU S(ALGR(FR_LPRN)) // ˝ (dead) -#define FR_DGRV S(ALGR(FR_RPRN)) // ̏ (dead) -#define FR_MDSH S(ALGR(FR_RSQU)) // — -#define FR_LSAQ S(ALGR(FR_LDAQ)) // ‹ -#define FR_RSAQ S(ALGR(FR_RDAQ)) // › -#define FR_RNGA S(ALGR(FR_QUOT)) // ˚ (dead) -#define FR_TM S(ALGR(FR_T)) // ™ -#define FR_DOTB S(ALGR(FR_I)) // ̣ (dead) -#define FR_PERM S(ALGR(FR_P)) // ‰ -#define FR_NBHY S(ALGR(FR_MINS)) // ‑ (non-breaking hyphen) -#define FR_DDAG S(ALGR(FR_PLUS)) // ‡ -#define FR_MACB S(ALGR(FR_H)) // ˍ (dead) -#define FR_SQRT S(ALGR(FR_SLSH)) // √ -#define FR_QRTR S(ALGR(FR_ASTR)) // ¼ -#define FR_GEQL S(ALGR(FR_LABK)) // ≥ -#define FR_OGON S(ALGR(FR_V)) // ˛ (dead) -#define FR_DCMM S(ALGR(FR_COMM)) // ̦ (dead) -#define FR_NEQL S(ALGR(FR_SCLN)) // ≠ - diff --git a/quantum/keymap_extras/keymap_french_mac_iso.h b/quantum/keymap_extras/keymap_french_mac_iso.h deleted file mode 100644 index e5f7514a8026..000000000000 --- a/quantum/keymap_extras/keymap_french_mac_iso.h +++ /dev/null @@ -1,186 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define FR_AT KC_GRV // @ -#define FR_AMPR KC_1 // & -#define FR_LEAC KC_2 // é -#define FR_DQUO KC_3 // " -#define FR_QUOT KC_4 // ' -#define FR_LPRN KC_5 // ( -#define FR_SECT KC_6 // § -#define FR_LEGR KC_7 // è -#define FR_EXLM KC_8 // ! -#define FR_LCCE KC_9 // ç -#define FR_LAGR KC_0 // à -#define FR_RPRN KC_MINS // ) -#define FR_MINS KC_EQL // - -#define FR_A KC_Q // A -#define FR_Z KC_W // Z -#define FR_E KC_E // E -#define FR_R KC_R // R -#define FR_T KC_T // T -#define FR_Y KC_Y // Y -#define FR_U KC_U // U -#define FR_I KC_I // I -#define FR_O KC_O // O -#define FR_P KC_P // P -#define FR_CIRC KC_LBRC // ^ -#define FR_DLR KC_RBRC // $ -#define FR_Q KC_A // Q -#define FR_S KC_S // S -#define FR_D KC_D // D -#define FR_F KC_F // F -#define FR_G KC_G // G -#define FR_H KC_H // H -#define FR_J KC_J // J -#define FR_K KC_K // K -#define FR_L KC_L // L -#define FR_M KC_SCLN // M -#define FR_LUGR KC_QUOT // ù -#define FR_GRV KC_NUHS // ` -#define FR_LABK KC_NUBS // < -#define FR_W KC_Z // W -#define FR_X KC_X // X -#define FR_C KC_C // C -#define FR_V KC_V // V -#define FR_B KC_B // B -#define FR_N KC_N // N -#define FR_COMM KC_M // , -#define FR_SCLN KC_COMM // ; -#define FR_COLN KC_DOT // : -#define FR_EQL KC_SLSH // = -#define FR_HASH S(FR_AT) // # -#define FR_1 S(FR_AMPR) // 1 -#define FR_2 S(FR_LEAC) // 2 -#define FR_3 S(FR_DQUO) // 3 -#define FR_4 S(FR_QUOT) // 4 -#define FR_5 S(FR_LPRN) // 5 -#define FR_6 S(FR_SECT) // 6 -#define FR_7 S(FR_LEGR) // 7 -#define FR_8 S(FR_EXLM) // 8 -#define FR_9 S(FR_LCCE) // 9 -#define FR_0 S(FR_LAGR) // 0 -#define FR_DEG S(FR_RPRN) // ° -#define FR_UNDS S(FR_MINS) // _ -#define FR_DIAE S(FR_CIRC) // ¨ (dead) -#define FR_ASTR S(FR_DLR) // * -#define FR_PERC S(FR_LUGR) // % -#define FR_PND S(FR_GRV) // £ -#define FR_RABK S(FR_LABK) // > -#define FR_QUES S(FR_COMM) // ? -#define FR_DOT S(FR_SCLN) // . -#define FR_SLSH S(FR_COLN) // / -#define FR_PLUS S(FR_EQL) // + -#define FR_BULT A(FR_AT) // • -#define FR_APPL A(FR_AMPR) //  (Apple logo) -#define FR_LEDI A(FR_LEAC) // ë -#define FR_LDQU A(FR_DQUO) // “ -#define FR_LSQU A(FR_QUOT) // ‘ -#define FR_LCBR A(FR_LPRN) // { -#define FR_PILC A(FR_SECT) // ¶ -#define FR_LDAQ A(FR_LEGR) // « -#define FR_IEXL A(FR_EXLM) // ¡ -#define FR_CCCE A(FR_LCCE) // Ç -#define FR_OSTR A(FR_LAGR) // Ø -#define FR_RCBR A(FR_RPRN) // } -#define FR_MDSH A(FR_MINS) // — -#define FR_AE A(FR_A) // Æ -#define FR_CACI A(FR_Z) //  -#define FR_ECIR A(FR_E) // Ê -#define FR_REGD A(FR_R) // ® -#define FR_DAGG A(FR_T) // † -#define FR_CUAC A(FR_Y) // Ú -#define FR_MORD A(FR_U) // º -#define FR_LICI A(FR_I) // î -#define FR_OE A(FR_O) // Œ -#define FR_PI A(FR_P) // π -#define FR_OCIR A(FR_CIRC) // Ô -#define FR_EURO A(FR_DLR) // € -#define FR_DDAG A(FR_Q) // ‡ -#define FR_COGR A(FR_S) // Ò -#define FR_PDIF A(FR_D) // ∂ -#define FR_FHK A(FR_F) // ƒ -#define FR_FI A(FR_G) // fi -#define FR_CIGR A(FR_H) // Ì -#define FR_CIDI A(FR_J) // Ï -#define FR_CEGR A(FR_K) // È -#define FR_NOT A(FR_L) // ¬ -#define FR_MICR A(FR_M) // µ -#define FR_CUGR A(FR_LUGR) // Ù -#define FR_LTEQ A(FR_LABK) // ≤ -#define FR_LSAQ A(FR_W) // ‹ -#define FR_AEQL A(FR_X) // ≈ -#define FR_COPY A(FR_C) // © -#define FR_LOZN A(FR_V) // ◊ -#define FR_SS A(FR_B) // ß -#define FR_TILD A(FR_N) // ~ (dead) -#define FR_INFN A(FR_COMM) // ∞ -#define FR_ELLP A(FR_SCLN) // … -#define FR_DIV A(FR_COLN) // ÷ -#define FR_NEQL A(FR_EQL) // ≠ -#define FR_CYDI S(A(FR_AT)) // Ÿ -#define FR_ACUT S(A(FR_AMPR)) // ´ (dead) -#define FR_DLQU S(A(FR_LEAC)) // „ -#define FR_LBRC S(A(FR_LPRN)) // [ -#define FR_LARI S(A(FR_SECT)) // å -#define FR_RDAQ S(A(FR_LEGR)) // » -#define FR_CUCI S(A(FR_EXLM)) // Û -#define FR_CAAC S(A(FR_LCCE)) // Á -#define FR_RBRC S(A(FR_RPRN)) // ] -#define FR_NDSH S(A(FR_MINS)) // – -#define FR_CARI S(A(FR_Z)) // Å -#define FR_SLQU S(A(FR_R)) // ‚ -#define FR_TM S(A(FR_T)) // ™ -#define FR_FORD S(A(FR_U)) // ª -#define FR_LIDI S(A(FR_I)) // ï -#define FR_NARP S(A(FR_P)) // ∏ -#define FR_YEN S(A(FR_DLR)) // ¥ -#define FR_OMEG S(A(FR_Q)) // Ω -#define FR_NARS S(A(FR_S)) // ∑ -#define FR_INCR S(A(FR_D)) // ∆ -#define FR_MDDT S(A(FR_F)) // · -#define FR_FL S(A(FR_G)) // fl -#define FR_CICI S(A(FR_H)) // Î -#define FR_CIAC S(A(FR_J)) // Í -#define FR_CEDI S(A(FR_K)) // Ë -#define FR_PIPE S(A(FR_L)) // | -#define FR_COAC S(A(FR_M)) // Ó -#define FR_PERM S(A(FR_LUGR)) // ‰ -#define FR_GTEQ S(A(FR_LABK)) // ≥ -#define FR_RSAQ S(A(FR_W)) // › -#define FR_FRSL S(A(FR_X)) // ⁄ -#define FR_CENT S(A(FR_C)) // ¢ -#define FR_SQRT S(A(FR_V)) // √ -#define FR_INTG S(A(FR_B)) // ∫ -#define FR_DLSI S(A(FR_N)) // ı -#define FR_IQUE S(A(FR_COMM)) // ¿ -#define FR_BSLS S(A(FR_COLN)) // (backslash) -#define FR_PLMN S(A(FR_EQL)) // ± - diff --git a/quantum/keymap_extras/keymap_german.h b/quantum/keymap_extras/keymap_german.h deleted file mode 100644 index 38b0c685ba67..000000000000 --- a/quantum/keymap_extras/keymap_german.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DE_CIRC KC_GRV // ^ (dead) -#define DE_1 KC_1 // 1 -#define DE_2 KC_2 // 2 -#define DE_3 KC_3 // 3 -#define DE_4 KC_4 // 4 -#define DE_5 KC_5 // 5 -#define DE_6 KC_6 // 6 -#define DE_7 KC_7 // 7 -#define DE_8 KC_8 // 8 -#define DE_9 KC_9 // 9 -#define DE_0 KC_0 // 0 -#define DE_SS KC_MINS // ß -#define DE_ACUT KC_EQL // ´ (dead) -#define DE_Q KC_Q // Q -#define DE_W KC_W // W -#define DE_E KC_E // E -#define DE_R KC_R // R -#define DE_T KC_T // T -#define DE_Z KC_Y // Z -#define DE_U KC_U // U -#define DE_I KC_I // I -#define DE_O KC_O // O -#define DE_P KC_P // P -#define DE_UDIA KC_LBRC // Ü -#define DE_PLUS KC_RBRC // + -#define DE_A KC_A // A -#define DE_S KC_S // S -#define DE_D KC_D // D -#define DE_F KC_F // F -#define DE_G KC_G // G -#define DE_H KC_H // H -#define DE_J KC_J // J -#define DE_K KC_K // K -#define DE_L KC_L // L -#define DE_ODIA KC_SCLN // Ö -#define DE_ADIA KC_QUOT // Ä -#define DE_HASH KC_NUHS // # -#define DE_LABK KC_NUBS // < -#define DE_Y KC_Z // Y -#define DE_X KC_X // X -#define DE_C KC_C // C -#define DE_V KC_V // V -#define DE_B KC_B // B -#define DE_N KC_N // N -#define DE_M KC_M // M -#define DE_COMM KC_COMM // , -#define DE_DOT KC_DOT // . -#define DE_MINS KC_SLSH // - -#define DE_DEG S(DE_CIRC) // ° -#define DE_EXLM S(DE_1) // ! -#define DE_DQUO S(DE_2) // " -#define DE_SECT S(DE_3) // § -#define DE_DLR S(DE_4) // $ -#define DE_PERC S(DE_5) // % -#define DE_AMPR S(DE_6) // & -#define DE_SLSH S(DE_7) // / -#define DE_LPRN S(DE_8) // ( -#define DE_RPRN S(DE_9) // ) -#define DE_EQL S(DE_0) // = -#define DE_QUES S(DE_SS) // ? -#define DE_GRV S(DE_ACUT) // ` (dead) -#define DE_ASTR S(DE_PLUS) // * -#define DE_QUOT S(DE_HASH) // ' -#define DE_RABK S(DE_LABK) // > -#define DE_SCLN S(DE_COMM) // ; -#define DE_COLN S(DE_DOT) // : -#define DE_UNDS S(DE_MINS) // _ -#define DE_SUP2 ALGR(DE_2) // ² -#define DE_SUP3 ALGR(DE_3) // ³ -#define DE_LCBR ALGR(DE_7) // { -#define DE_LBRC ALGR(DE_8) // [ -#define DE_RBRC ALGR(DE_9) // ] -#define DE_RCBR ALGR(DE_0) // } -#define DE_BSLS ALGR(DE_SS) // (backslash) -#define DE_AT ALGR(DE_Q) // @ -#define DE_EURO ALGR(DE_E) // € -#define DE_TILD ALGR(DE_PLUS) // ~ -#define DE_PIPE ALGR(DE_LABK) // | -#define DE_MICR ALGR(DE_M) // µ - diff --git a/quantum/keymap_extras/keymap_german_mac_iso.h b/quantum/keymap_extras/keymap_german_mac_iso.h deleted file mode 100644 index efa9099f2011..000000000000 --- a/quantum/keymap_extras/keymap_german_mac_iso.h +++ /dev/null @@ -1,181 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DE_CIRC KC_GRV // ^ (dead) -#define DE_1 KC_1 // 1 -#define DE_2 KC_2 // 2 -#define DE_3 KC_3 // 3 -#define DE_4 KC_4 // 4 -#define DE_5 KC_5 // 5 -#define DE_6 KC_6 // 6 -#define DE_7 KC_7 // 7 -#define DE_8 KC_8 // 8 -#define DE_9 KC_9 // 9 -#define DE_0 KC_0 // 0 -#define DE_SS KC_MINS // ß -#define DE_ACUT KC_EQL // ´ (dead) -#define DE_Q KC_Q // Q -#define DE_W KC_W // W -#define DE_E KC_E // E -#define DE_R KC_R // R -#define DE_T KC_T // T -#define DE_Z KC_Y // Z -#define DE_U KC_U // U -#define DE_I KC_I // I -#define DE_O KC_O // O -#define DE_P KC_P // P -#define DE_UDIA KC_LBRC // Ü -#define DE_PLUS KC_RBRC // + -#define DE_A KC_A // A -#define DE_S KC_S // S -#define DE_D KC_D // D -#define DE_F KC_F // F -#define DE_G KC_G // G -#define DE_H KC_H // H -#define DE_J KC_J // J -#define DE_K KC_K // K -#define DE_L KC_L // L -#define DE_ODIA KC_SCLN // Ö -#define DE_ADIA KC_QUOT // Ä -#define DE_HASH KC_NUHS // # -#define DE_LABK KC_NUBS // < -#define DE_Y KC_Z // Y -#define DE_X KC_X // X -#define DE_C KC_C // C -#define DE_V KC_V // V -#define DE_B KC_B // B -#define DE_N KC_N // N -#define DE_M KC_M // M -#define DE_COMM KC_COMM // , -#define DE_DOT KC_DOT // . -#define DE_MINS KC_SLSH // - -#define DE_DEG S(DE_CIRC) // ° -#define DE_EXLM S(DE_1) // ! -#define DE_DQUO S(DE_2) // " -#define DE_SECT S(DE_3) // § -#define DE_DLR S(DE_4) // $ -#define DE_PERC S(DE_5) // % -#define DE_AMPR S(DE_6) // & -#define DE_SLSH S(DE_7) // / -#define DE_LPRN S(DE_8) // ( -#define DE_RPRN S(DE_9) // ) -#define DE_EQL S(DE_0) // = -#define DE_QUES S(DE_SS) // ? -#define DE_GRV S(DE_ACUT) // ` (dead) -#define DE_ASTR S(DE_PLUS) // * -#define DE_QUOT S(DE_HASH) // ' -#define DE_RABK S(DE_LABK) // > -#define DE_SCLN S(DE_COMM) // ; -#define DE_COLN S(DE_DOT) // : -#define DE_UNDS S(DE_MINS) // _ -#define DE_DLQU A(DE_CIRC) // „ -#define DE_IEXL A(DE_1) // ¡ -#define DE_LDQU A(DE_2) // “ -#define DE_PILC A(DE_3) // ¶ -#define DE_CENT A(DE_4) // ¢ -#define DE_LBRC A(DE_5) // [ -#define DE_RBRC A(DE_6) // ] -#define DE_PIPE A(DE_7) // | -#define DE_LCBR A(DE_8) // { -#define DE_RCBR A(DE_9) // } -#define DE_NEQL A(DE_0) // ≠ -#define DE_IQUE A(DE_SS) // ¿ -#define DE_LDAQ A(DE_Q) // « -#define DE_NARS A(DE_W) // ∑ -#define DE_EURO A(DE_E) // € -#define DE_REGD A(DE_R) // ® -#define DE_DAGG A(DE_T) // † -#define DE_OMEG A(DE_Z) // Ω -#define DE_DIAE A(DE_U) // ¨ (dead) -#define DE_FRSL A(DE_I) // ⁄ -#define DE_OSTR A(DE_O) // Ø -#define DE_PI A(DE_P) // π -#define DE_BULT A(DE_UDIA) // • -#define DE_PLMN A(DE_PLUS) // ± -#define DE_ARNG A(DE_A) // Å -#define DE_SLQU A(DE_S) // ‚ -#define DE_PDIF A(DE_D) // ∂ -#define DE_FHK A(DE_F) // ƒ -#define DE_COPY A(DE_G) // © -#define DE_FORD A(DE_H) // ª -#define DE_MORD A(DE_J) // º -#define DE_INCR A(DE_K) // ∆ -#define DE_AT A(DE_L) // @ -#define DE_OE A(DE_ODIA) // Œ -#define DE_AE A(DE_ADIA) // Æ -#define DE_LSQU A(DE_HASH) // ‘ -#define DE_LTEQ A(DE_LABK) // ≤ -#define DE_YEN A(DE_Y) // ¥ -#define DE_AEQL A(DE_X) // ≈ -#define DE_CCCE A(DE_C) // Ç -#define DE_SQRT A(DE_V) // √ -#define DE_INTG A(DE_B) // ∫ -#define DE_TILD A(DE_N) // ~ (dead) -#define DE_MICR A(DE_M) // µ -#define DE_INFN A(DE_COMM) // ∞ -#define DE_ELLP A(DE_DOT) // … -#define DE_NDSH A(DE_MINS) // – -#define DE_NOT S(A(DE_1)) // ¬ -#define DE_RDQU S(A(DE_2)) // ” -#define DE_PND S(A(DE_4)) // £ -#define DE_FI S(A(DE_5)) // fi -#define DE_BSLS S(A(DE_7)) // (backslash) -#define DE_STIL S(A(DE_8)) // ˜ -#define DE_MDDT S(A(DE_9)) // · -#define DE_MACR S(A(DE_0)) // ¯ -#define DE_DOTA S(A(DE_SS)) // ˙ -#define DE_RNGA S(A(DE_ACUT)) // ˚ -#define DE_RDAQ S(A(DE_Q)) // » -#define DE_PERM S(A(DE_E)) // ‰ -#define DE_CEDL S(A(DE_R)) // ¸ -#define DE_DACU S(A(DE_T)) // ˝ -#define DE_CARN S(A(DE_Z)) // ˇ -#define DE_AACU S(A(DE_U)) // Á -#define DE_UCIR S(A(DE_I)) // Û -#define DE_NARP S(A(DE_P)) // ∏ -#define DE_APPL S(A(DE_PLUS)) //  (Apple logo) -#define DE_IACU S(A(DE_S)) // Í -#define DE_TM S(A(DE_D)) // ™ -#define DE_IDIA S(A(DE_F)) // Ï -#define DE_IGRV S(A(DE_G)) // Ì -#define DE_OACU S(A(DE_H)) // Ó -#define DE_DLSI S(A(DE_J)) // ı -#define DE_FL S(A(DE_L)) // fl -#define DE_GTEQ S(A(DE_LABK)) // ≥ -#define DE_DDAG S(A(DE_Y)) // ‡ -#define DE_UGRV S(A(DE_X)) // Ù -#define DE_LOZN S(A(DE_V)) // ◊ -#define DE_LSAQ S(A(DE_B)) // ‹ -#define DE_RSAQ S(A(DE_N)) // › -#define DE_BREV S(A(DE_M)) // ˘ -#define DE_OGON S(A(DE_COMM)) // ˛ -#define DE_DIV S(A(DE_DOT)) // ÷ -#define DE_MDSH S(A(DE_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_greek.h b/quantum/keymap_extras/keymap_greek.h deleted file mode 100644 index 01779cf2e859..000000000000 --- a/quantum/keymap_extras/keymap_greek.h +++ /dev/null @@ -1,118 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define GR_GRV KC_GRV // ` -#define GR_1 KC_1 // 1 -#define GR_2 KC_2 // 2 -#define GR_3 KC_3 // 3 -#define GR_4 KC_4 // 4 -#define GR_5 KC_5 // 5 -#define GR_6 KC_6 // 6 -#define GR_7 KC_7 // 7 -#define GR_8 KC_8 // 8 -#define GR_9 KC_9 // 9 -#define GR_0 KC_0 // 0 -#define GR_MINS KC_MINS // - -#define GR_EQL KC_EQL // = -#define GR_SCLN KC_Q // ; -#define GR_FSIG KC_W // ς -#define GR_EPSL KC_E // Ε -#define GR_RHO KC_R // Ρ -#define GR_TAU KC_T // Τ -#define GR_UPSL KC_Y // Υ -#define GR_THET KC_U // Θ -#define GR_IOTA KC_I // Ι -#define GR_OMCR KC_O // Ο -#define GR_PI KC_P // Π -#define GR_LBRC KC_LBRC // [ -#define GR_RBRC KC_RBRC // ] -#define GR_ALPH KC_A // Α -#define GR_SIGM KC_S // Σ -#define GR_DELT KC_D // Δ -#define GR_PHI KC_F // Φ -#define GR_GAMM KC_G // Γ -#define GR_ETA KC_H // Η -#define GR_XI KC_J // Ξ -#define GR_KAPP KC_K // Κ -#define GR_LAMB KC_L // Λ -#define GR_TONS KC_SCLN // ΄ (dead) -#define GR_QUOT KC_QUOT // ' -#define GR_BSLS KC_NUHS // (backslash) -#define GR_ZETA KC_Z // Ζ -#define GR_CHI KC_X // Χ -#define GR_PSI KC_C // Ψ -#define GR_OMEG KC_V // Ω -#define GR_BETA KC_B // Β -#define GR_NU KC_N // Ν -#define GR_MU KC_M // Μ -#define GR_COMM KC_COMM // , -#define GR_DOT KC_DOT // . -#define GR_SLSH KC_SLSH // / -#define GR_TILD S(GR_GRV) // ~ -#define GR_EXLM S(GR_1) // ! -#define GR_AT S(GR_2) // @ -#define GR_HASH S(GR_3) // # -#define GR_DLR S(GR_4) // $ -#define GR_PERC S(GR_5) // % -#define GR_CIRC S(GR_6) // ^ -#define GR_AMPR S(GR_7) // & -#define GR_ASTR S(GR_8) // * -#define GR_LPRN S(GR_9) // ( -#define GR_RPRN S(GR_0) // ) -#define GR_UNDS S(GR_MINS) // _ -#define GR_PLUS S(GR_EQL) // + -#define GR_COLN S(GR_SCLN) // : -#define GR_DIAT S(GR_FSIG) // ΅ (dead) -#define GR_LCBR S(GR_LBRC) // { -#define GR_RCBR S(GR_RBRC) // } -#define GR_DIAE S(GR_TONS) // ¨ (dead) -#define GR_DQUO S(GR_QUOT) // " -#define GR_PIPE S(GR_BSLS) // | -#define GR_LABK S(GR_COMM) // < -#define GR_RABK S(GR_DOT) // > -#define GR_QUES S(GR_SLSH) // ? -#define GR_SUP2 ALGR(GR_2) // ² -#define GR_SUP3 ALGR(GR_3) // ³ -#define GR_PND ALGR(GR_4) // £ -#define GR_SECT ALGR(GR_5) // § -#define GR_PILC ALGR(GR_6) // ¶ -#define GR_CURR ALGR(GR_8) // ¤ -#define GR_BRKP ALGR(GR_9) // ¦ -#define GR_DEG ALGR(GR_0) // ° -#define GR_PLMN ALGR(GR_MINS) // ± -#define GR_HALF ALGR(GR_EQL) // ½ -#define GR_EURO ALGR(GR_EPSL) // € -#define GR_REGD ALGR(GR_RHO) // ® -#define GR_YEN ALGR(GR_UPSL) // ¥ -#define GR_LDAQ ALGR(GR_LBRC) // « -#define GR_RDAQ ALGR(GR_RBRC) // » -#define GR_NOT ALGR(GR_BSLS) // ¬ -#define GR_COPY ALGR(GR_PSI) // © - diff --git a/quantum/keymap_extras/keymap_hebrew.h b/quantum/keymap_extras/keymap_hebrew.h deleted file mode 100644 index 284562072dc6..000000000000 --- a/quantum/keymap_extras/keymap_hebrew.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IL_SCLN KC_GRV // ; -#define IL_1 KC_1 // 1 -#define IL_2 KC_2 // 2 -#define IL_3 KC_3 // 3 -#define IL_4 KC_4 // 4 -#define IL_5 KC_5 // 5 -#define IL_6 KC_6 // 6 -#define IL_7 KC_7 // 7 -#define IL_8 KC_8 // 8 -#define IL_9 KC_9 // 9 -#define IL_0 KC_0 // 0 -#define IL_MINS KC_MINS // - -#define IL_EQL KC_EQL // = -#define IL_SLSH KC_Q // / -#define IL_QUOT KC_W // ' -#define IL_QOF KC_E // ק -#define IL_RESH KC_R // ר -#define IL_ALEF KC_T // א -#define IL_TET KC_Y // ט -#define IL_VAV KC_U // ו -#define IL_FNUN KC_I // ן -#define IL_FMEM KC_O // ם -#define IL_PE KC_P // פ -#define IL_RBRC KC_LBRC // ] -#define IL_LBRC KC_RBRC // [ -#define IL_SHIN KC_A // ש -#define IL_DALT KC_S // ד -#define IL_GIML KC_D // ג -#define IL_KAF KC_F // כ -#define IL_AYIN KC_G // ע -#define IL_YOD KC_H // י -#define IL_HET KC_J // ח -#define IL_LAMD KC_K // ל -#define IL_FKAF KC_L // ך -#define IL_FPE KC_SCLN // ף -#define IL_COMM KC_QUOT // , -#define IL_BSLS KC_NUHS // (backslash) -#define IL_ZAYN KC_Z // ז -#define IL_SMKH KC_X // ס -#define IL_BET KC_C // ב -#define IL_HE KC_V // ה -#define IL_NUN KC_B // נ -#define IL_MEM KC_N // מ -#define IL_TSDI KC_M // צ -#define IL_TAV KC_COMM // ת -#define IL_FTSD KC_DOT // ץ -#define IL_DOT KC_SLSH // . -#define IL_TILD S(IL_SCLN) // ~ -#define IL_EXLM S(IL_1) // ! -#define IL_AT S(IL_2) // @ -#define IL_PND S(IL_3) // # -#define IL_DLR S(IL_4) // $ -#define IL_PERC S(IL_5) // % -#define IL_CIRC S(IL_6) // ^ -#define IL_AMPR S(IL_7) // & -#define IL_ASTR S(IL_8) // * -#define IL_RPRN S(IL_9) // ) -#define IL_LPRN S(IL_0) // ( -#define IL_UNDS S(IL_MINS) // _ -#define IL_PLUS S(IL_EQL) // + -#define IL_RCBR S(IL_RBRC) // } -#define IL_LCBR S(IL_LBRC) // { -#define IL_COLN S(IL_FPE) // : -#define IL_DQUO S(IL_COMM) // " -#define IL_PIPE S(IL_BSLS) // | -#define IL_RABK S(IL_TAV) // > -#define IL_LABK S(IL_FTSD) // < -#define IL_QUES S(IL_DOT) // ? -#define IL_EURO ALGR(IL_3) // € -#define IL_SHKL ALGR(IL_4) // ₪ -#define IL_DEG ALGR(IL_5) // ° -#define IL_MUL ALGR(IL_8) // × -#define IL_DVAV ALGR(IL_TET) // װ -#define IL_VYOD ALGR(IL_AYIN) // ױ -#define IL_DYOD ALGR(IL_YOD) // ײ -#define IL_DIV ALGR(IL_DOT) // ÷ - diff --git a/quantum/keymap_extras/keymap_hungarian.h b/quantum/keymap_extras/keymap_hungarian.h deleted file mode 100644 index fbc31ed15562..000000000000 --- a/quantum/keymap_extras/keymap_hungarian.h +++ /dev/null @@ -1,129 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define HU_0 KC_GRV // 0 -#define HU_1 KC_1 // 1 -#define HU_2 KC_2 // 2 -#define HU_3 KC_3 // 3 -#define HU_4 KC_4 // 4 -#define HU_5 KC_5 // 5 -#define HU_6 KC_6 // 6 -#define HU_7 KC_7 // 7 -#define HU_8 KC_8 // 8 -#define HU_9 KC_9 // 9 -#define HU_ODIA KC_0 // Ö -#define HU_UDIA KC_MINS // Ü -#define HU_OACU KC_EQL // Ó -#define HU_Q KC_Q // Q -#define HU_W KC_W // W -#define HU_E KC_E // E -#define HU_R KC_R // R -#define HU_T KC_T // T -#define HU_Z KC_Y // Z -#define HU_U KC_U // U -#define HU_I KC_I // I -#define HU_O KC_O // O -#define HU_P KC_P // P -#define HU_ODAC KC_LBRC // Ő -#define HU_UACU KC_RBRC // Ú -#define HU_A KC_A // A -#define HU_S KC_S // S -#define HU_D KC_D // D -#define HU_F KC_F // F -#define HU_G KC_G // G -#define HU_H KC_H // H -#define HU_J KC_J // J -#define HU_K KC_K // K -#define HU_L KC_L // L -#define HU_EACU KC_SCLN // É -#define HU_AACU KC_QUOT // Á -#define HU_UDAC KC_NUHS // Ű -#define HU_IACU KC_NUBS // Í -#define HU_Y KC_Z // Y -#define HU_X KC_X // X -#define HU_C KC_C // C -#define HU_V KC_V // V -#define HU_B KC_B // B -#define HU_N KC_N // N -#define HU_M KC_M // M -#define HU_COMM KC_COMM // , -#define HU_DOT KC_DOT // . -#define HU_MINS KC_SLSH // - -#define HU_SECT S(HU_0) // § -#define HU_QUOT S(HU_1) // ' -#define HU_DQUO S(HU_2) // " -#define HU_PLUS S(HU_3) // + -#define HU_EXLM S(HU_4) // ! -#define HU_PERC S(HU_5) // % -#define HU_SLSH S(HU_6) // / -#define HU_EQL S(HU_7) // = -#define HU_LPRN S(HU_8) // ( -#define HU_RPRN S(HU_9) // ) -#define HU_QUES S(HU_COMM) // ? -#define HU_COLN S(HU_DOT) // : -#define HU_UNDS S(HU_MINS) // _ -#define HU_TILD ALGR(HU_1) // ~ -#define HU_CARN ALGR(HU_2) // ˇ (dead) -#define HU_CIRC ALGR(HU_3) // ^ (dead) -#define HU_BREV ALGR(HU_4) // ˘ (dead) -#define HU_RNGA ALGR(HU_5) // ° (dead) -#define HU_OGON ALGR(HU_6) // ˛ (dead) -#define HU_GRV ALGR(HU_7) // ` -#define HU_DOTA ALGR(HU_8) // ˙ (dead) -#define HU_ACUT ALGR(HU_9) // ´ (dead) -#define HU_DACU ALGR(HU_ODIA) // ˝ (dead) -#define HU_DIAE ALGR(HU_UDIA) // ¨ (dead) -#define HU_CEDL ALGR(HU_OACU) // ¸ (dead) -#define HU_BSLS ALGR(HU_Q) // (backslash) -#define HU_PIPE ALGR(HU_W) // | -#define HU_CADI ALGR(HU_E) // Ä -#define HU_EURO ALGR(HU_U) // € -#define HU_DIV ALGR(HU_ODAC) // ÷ -#define HU_MUL ALGR(HU_UACU) // × -#define HU_LADI ALGR(HU_A) // ä -#define HU_LDST ALGR(HU_S) // đ -#define HU_CDST ALGR(HU_D) // Đ -#define HU_LBRC ALGR(HU_F) // [ -#define HU_RBRC ALGR(HU_G) // ] -#define HU_LLST ALGR(HU_K) // ł -#define HU_CLST ALGR(HU_L) // Ł -#define HU_DLR ALGR(HU_EACU) // $ -#define HU_SS ALGR(HU_AACU) // ß -#define HU_CURR ALGR(HU_UDAC) // ¤ -#define HU_LABK ALGR(HU_IACU) // < -#define HU_RABK ALGR(HU_Y) // > -#define HU_HASH ALGR(HU_X) // # -#define HU_AMPR ALGR(HU_C) // & -#define HU_AT ALGR(HU_V) // @ -#define HU_LCBR ALGR(HU_B) // { -#define HU_RCBR ALGR(HU_N) // } -#define HU_SCLN ALGR(HU_COMM) // ; -#define HU_ASTR ALGR(HU_MINS) // * - diff --git a/quantum/keymap_extras/keymap_icelandic.h b/quantum/keymap_extras/keymap_icelandic.h deleted file mode 100644 index 3bd71c19f280..000000000000 --- a/quantum/keymap_extras/keymap_icelandic.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IS_RNGA KC_GRV // ° (dead) -#define IS_1 KC_1 // 1 -#define IS_2 KC_2 // 2 -#define IS_3 KC_3 // 3 -#define IS_4 KC_4 // 4 -#define IS_5 KC_5 // 5 -#define IS_6 KC_6 // 6 -#define IS_7 KC_7 // 7 -#define IS_8 KC_8 // 8 -#define IS_9 KC_9 // 9 -#define IS_0 KC_0 // 0 -#define IS_ODIA KC_MINS // Ö -#define IS_MINS KC_EQL // - -#define IS_Q KC_Q // Q -#define IS_W KC_W // W -#define IS_E KC_E // E -#define IS_R KC_R // R -#define IS_T KC_T // T -#define IS_Y KC_Y // Y -#define IS_U KC_U // U -#define IS_I KC_I // I -#define IS_O KC_O // O -#define IS_P KC_P // P -#define IS_ETH KC_LBRC // Ð -#define IS_QUOT KC_RBRC // ' -#define IS_A KC_A // A -#define IS_S KC_S // S -#define IS_D KC_D // D -#define IS_F KC_F // F -#define IS_G KC_G // G -#define IS_H KC_H // H -#define IS_J KC_J // J -#define IS_K KC_K // K -#define IS_L KC_L // L -#define IS_AE KC_SCLN // Æ -#define IS_ACUT KC_QUOT // ´ (dead) -#define IS_PLUS KC_NUHS // + -#define IS_LABK KC_NUBS // < -#define IS_Z KC_Z // Z -#define IS_X KC_X // X -#define IS_C KC_C // C -#define IS_V KC_V // V -#define IS_B KC_B // B -#define IS_N KC_N // N -#define IS_M KC_M // M -#define IS_COMM KC_COMM // , -#define IS_DOT KC_DOT // . -#define IS_THRN KC_SLSH // Þ -#define IS_DIAE S(IS_RNGA) // ¨ (dead) -#define IS_EXLM S(IS_1) // ! -#define IS_DQUO S(IS_2) // " -#define IS_HASH S(IS_3) // # -#define IS_DLR S(IS_4) // $ -#define IS_PERC S(IS_5) // % -#define IS_AMPR S(IS_6) // & -#define IS_SLSH S(IS_7) // / -#define IS_LPRN S(IS_8) // ( -#define IS_RPRN S(IS_9) // ) -#define IS_EQL S(IS_0) // = -#define IS_UNDS S(IS_MINS) // _ -#define IS_QUES S(IS_QUOT) // ? -#define IS_ASTR S(IS_PLUS) // * -#define IS_RABK S(IS_LABK) // > -#define IS_SCLN S(IS_COMM) // ; -#define IS_COLN S(IS_DOT) // : -#define IS_DEG ALGR(IS_RNGA) // ° -#define IS_LCBR ALGR(IS_7) // { -#define IS_LBRC ALGR(IS_8) // [ -#define IS_RBRC ALGR(IS_9) // ] -#define IS_RCBR ALGR(IS_0) // } -#define IS_BSLS ALGR(IS_ODIA) // (backslash) -#define IS_AT ALGR(IS_Q) // @ -#define IS_EURO ALGR(IS_E) // € -#define IS_TILD ALGR(IS_QUOT) // ~ -#define IS_CIRC ALGR(IS_ACUT) // ^ (dead) -#define IS_GRV ALGR(IS_PLUS) // ` (dead) -#define IS_PIPE ALGR(IS_LABK) // | -#define IS_MICR ALGR(IS_M) // µ - diff --git a/quantum/keymap_extras/keymap_irish.h b/quantum/keymap_extras/keymap_irish.h deleted file mode 100644 index 6e161628c864..000000000000 --- a/quantum/keymap_extras/keymap_irish.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IE_GRV KC_GRV // ` -#define IE_1 KC_1 // 1 -#define IE_2 KC_2 // 2 -#define IE_3 KC_3 // 3 -#define IE_4 KC_4 // 4 -#define IE_5 KC_5 // 5 -#define IE_6 KC_6 // 6 -#define IE_7 KC_7 // 7 -#define IE_8 KC_8 // 8 -#define IE_9 KC_9 // 9 -#define IE_0 KC_0 // 0 -#define IE_MINS KC_MINS // - -#define IE_EQL KC_EQL // = -#define IE_Q KC_Q // Q -#define IE_W KC_W // W -#define IE_E KC_E // E -#define IE_R KC_R // R -#define IE_T KC_T // T -#define IE_Y KC_Y // Y -#define IE_U KC_U // U -#define IE_I KC_I // I -#define IE_O KC_O // O -#define IE_P KC_P // P -#define IE_LBRC KC_LBRC // [ -#define IE_RBRC KC_RBRC // ] -#define IE_A KC_A // A -#define IE_S KC_S // S -#define IE_D KC_D // D -#define IE_F KC_F // F -#define IE_G KC_G // G -#define IE_H KC_H // H -#define IE_J KC_J // J -#define IE_K KC_K // K -#define IE_L KC_L // L -#define IE_SCLN KC_SCLN // ; -#define IE_QUOT KC_QUOT // ' -#define IE_HASH KC_NUHS // # -#define IE_BSLS KC_NUBS // (backslash) -#define IE_Z KC_Z // Z -#define IE_X KC_X // X -#define IE_C KC_C // C -#define IE_V KC_V // V -#define IE_B KC_B // B -#define IE_N KC_N // N -#define IE_M KC_M // M -#define IE_COMM KC_COMM // , -#define IE_DOT KC_DOT // . -#define IE_SLSH KC_SLSH // / -#define IE_NOT S(IE_GRV) // ¬ -#define IE_EXLM S(IE_1) // ! -#define IE_DQUO S(IE_2) // " -#define IE_PND S(IE_3) // £ -#define IE_DLR S(IE_4) // $ -#define IE_PERC S(IE_5) // % -#define IE_CIRC S(IE_6) // ^ -#define IE_AMPR S(IE_7) // & -#define IE_ASTR S(IE_8) // * -#define IE_LPRN S(IE_9) // ( -#define IE_RPRN S(IE_0) // ) -#define IE_UNDS S(IE_MINS) // _ -#define IE_PLUS S(IE_EQL) // + -#define IE_LCBR S(IE_LBRC) // { -#define IE_RCBR S(IE_RBRC) // } -#define IE_COLN S(IE_SCLN) // : -#define IE_AT S(IE_QUOT) // @ -#define IE_TILD S(IE_HASH) // ~ -#define IE_PIPE S(IE_BSLS) // | -#define IE_LABK S(IE_COMM) // < -#define IE_RABK S(IE_DOT) // > -#define IE_QUES S(IE_SLSH) // ? -#define IE_BRKP ALGR(IE_GRV) // ¦ -#define IE_EURO ALGR(IE_4) // € -#define IE_EACU ALGR(IE_E) // É -#define IE_UACU ALGR(IE_U) // Ú -#define IE_IACU ALGR(IE_I) // Í -#define IE_OACU ALGR(IE_O) // Ó -#define IE_AACU ALGR(IE_A) // Á -#define IE_ACUT ALGR(IE_QUOT) // ´ (dead) - diff --git a/quantum/keymap_extras/keymap_italian.h b/quantum/keymap_extras/keymap_italian.h deleted file mode 100644 index 8092dc130188..000000000000 --- a/quantum/keymap_extras/keymap_italian.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IT_BSLS KC_GRV // (backslash) -#define IT_1 KC_1 // 1 -#define IT_2 KC_2 // 2 -#define IT_3 KC_3 // 3 -#define IT_4 KC_4 // 4 -#define IT_5 KC_5 // 5 -#define IT_6 KC_6 // 6 -#define IT_7 KC_7 // 7 -#define IT_8 KC_8 // 8 -#define IT_9 KC_9 // 9 -#define IT_0 KC_0 // 0 -#define IT_QUOT KC_MINS // ' -#define IT_IGRV KC_EQL // ì -#define IT_Q KC_Q // Q -#define IT_W KC_W // W -#define IT_E KC_E // E -#define IT_R KC_R // R -#define IT_T KC_T // T -#define IT_Y KC_Y // Y -#define IT_U KC_U // U -#define IT_I KC_I // I -#define IT_O KC_O // O -#define IT_P KC_P // P -#define IT_EGRV KC_LBRC // è -#define IT_PLUS KC_RBRC // + -#define IT_A KC_A // A -#define IT_S KC_S // S -#define IT_D KC_D // D -#define IT_F KC_F // F -#define IT_G KC_G // G -#define IT_H KC_H // H -#define IT_J KC_J // J -#define IT_K KC_K // K -#define IT_L KC_L // L -#define IT_OGRV KC_SCLN // ò -#define IT_AGRV KC_QUOT // à -#define IT_UGRV KC_NUHS // ù -#define IT_LABK KC_NUBS // < -#define IT_Z KC_Z // Z -#define IT_X KC_X // X -#define IT_C KC_C // C -#define IT_B KC_B // B -#define IT_V KC_V // V -#define IT_N KC_N // N -#define IT_M KC_M // M -#define IT_COMM KC_COMM // , -#define IT_DOT KC_DOT // . -#define IT_MINS KC_SLSH // - -#define IT_PIPE S(IT_BSLS) // | -#define IT_EXLM S(IT_1) // ! -#define IT_DQUO S(IT_2) // " -#define IT_PND S(IT_3) // £ -#define IT_DLR S(IT_4) // $ -#define IT_PERC S(IT_5) // % -#define IT_AMPR S(IT_6) // & -#define IT_SLSH S(IT_7) // / -#define IT_LPRN S(IT_8) // ( -#define IT_RPRN S(IT_9) // ) -#define IT_EQL S(IT_0) // = -#define IT_QUES S(IT_QUOT) // ? -#define IT_CIRC S(IT_IGRV) // ^ -#define IT_EACU S(IT_EGRV) // é -#define IT_ASTR S(IT_PLUS) // * -#define IT_CCED S(IT_OGRV) // ç -#define IT_DEG S(IT_AGRV) // ° -#define IT_SECT S(IT_UGRV) // § -#define IT_RABK S(IT_LABK) // > -#define IT_COLN S(IT_DOT) // : -#define IT_SCLN S(IT_COMM) // ; -#define IT_UNDS S(IT_MINS) // _ -#define IT_EURO ALGR(IT_E) // € -#define IT_LBRC ALGR(IT_EGRV) // [ -#define IT_RBRC ALGR(IT_PLUS) // ] -#define IT_AT ALGR(IT_OGRV) // @ -#define IT_HASH ALGR(IT_AGRV) // # -#define IT_LCBR S(ALGR(IT_EGRV)) // { -#define IT_RCBR S(ALGR(IT_PLUS)) // } - diff --git a/quantum/keymap_extras/keymap_italian_mac_ansi.h b/quantum/keymap_extras/keymap_italian_mac_ansi.h deleted file mode 100644 index ae1281be262b..000000000000 --- a/quantum/keymap_extras/keymap_italian_mac_ansi.h +++ /dev/null @@ -1,188 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IT_LABK KC_GRV // < -#define IT_1 KC_1 // 1 -#define IT_2 KC_2 // 2 -#define IT_3 KC_3 // 3 -#define IT_4 KC_4 // 4 -#define IT_5 KC_5 // 5 -#define IT_6 KC_6 // 6 -#define IT_7 KC_7 // 7 -#define IT_8 KC_8 // 8 -#define IT_9 KC_9 // 9 -#define IT_0 KC_0 // 0 -#define IT_QUOT KC_MINS // ' -#define IT_IGRV KC_EQL // ì -#define IT_Q KC_Q // Q -#define IT_W KC_W // W -#define IT_E KC_E // E -#define IT_R KC_R // R -#define IT_T KC_T // T -#define IT_Y KC_Y // Y -#define IT_U KC_U // U -#define IT_I KC_I // I -#define IT_O KC_O // O -#define IT_P KC_P // P -#define IT_EGRV KC_LBRC // è -#define IT_PLUS KC_RBRC // + -#define IT_UGRV KC_BSLS // ù -#define IT_A KC_A // A -#define IT_S KC_S // S -#define IT_D KC_D // D -#define IT_F KC_F // F -#define IT_G KC_G // G -#define IT_H KC_H // H -#define IT_J KC_J // J -#define IT_K KC_K // K -#define IT_L KC_L // L -#define IT_OGRV KC_SCLN // ò -#define IT_AGRV KC_QUOT // à -#define IT_BSLS KC_NUBS // (backslash, not physically present) -#define IT_Z KC_Z // Z -#define IT_X KC_X // X -#define IT_C KC_C // C -#define IT_V KC_V // V -#define IT_B KC_B // B -#define IT_N KC_N // N -#define IT_M KC_M // M -#define IT_COMM KC_COMM // , -#define IT_DOT KC_DOT // . -#define IT_MINS KC_SLSH // - -#define IT_RABK S(IT_LABK) // > -#define IT_EXLM S(IT_1) // ! -#define IT_DQUO S(IT_2) // " -#define IT_PND S(IT_3) // £ -#define IT_DLR S(IT_4) // $ -#define IT_PERC S(IT_5) // % -#define IT_AMPR S(IT_6) // & -#define IT_SLSH S(IT_7) // / -#define IT_LPRN S(IT_8) // ( -#define IT_RPRN S(IT_9) // ) -#define IT_EQL S(IT_0) // = -#define IT_QUES S(IT_QUOT) // ? -#define IT_CIRC S(IT_IGRV) // ^ -#define IT_EACU S(IT_EGRV) // é -#define IT_ASTR S(IT_PLUS) // * -#define IT_SECT S(IT_UGRV) // § -#define IT_LCCE S(IT_OGRV) // ç -#define IT_DEG S(IT_AGRV) // ° -#define IT_PIPE S(IT_BSLS) // | (not physically present) -#define IT_SCLN S(IT_COMM) // ; -#define IT_COLN S(IT_DOT) // : -#define IT_UNDS S(IT_MINS) // _ -#define IT_LTEQ A(IT_LABK) // ≤ -#define IT_LDAQ A(IT_1) // « -#define IT_LDQU A(IT_2) // “ -#define IT_LSQU A(IT_3) // ‘ -#define IT_YEN A(IT_4) // ¥ -#define IT_TILD A(IT_5) // ~ -#define IT_LSAQ A(IT_6) // ‹ -#define IT_DIV A(IT_7) // ÷ -#define IT_ACUT A(IT_8) // ´ (dead) -#define IT_DGRV A(IT_9) // ` (dead) -#define IT_NEQL A(IT_0) // ≠ -#define IT_IEXL A(IT_QUOT) // ¡ -#define IT_DCIR A(IT_IGRV) // ˆ (dead) -#define IT_DLQU A(IT_Q) // „ -#define IT_OMEG A(IT_W) // Ω -#define IT_EURO A(IT_E) // € -#define IT_REGD A(IT_R) // ® -#define IT_TM A(IT_T) // ™ -#define IT_AE A(IT_Y) // Æ -#define IT_DIAE A(IT_U) // ¨ (dead) -#define IT_OE A(IT_I) // Œ -#define IT_OSTR A(IT_O) // Ø -#define IT_PI A(IT_P) // π -#define IT_LBRC A(IT_EGRV) // [ -#define IT_RBRC A(IT_PLUS) // ] -#define IT_ARNG A(IT_A) // Å -#define IT_SS A(IT_S) // ß -#define IT_PDIF A(IT_D) // ∂ -#define IT_FHK A(IT_F) // ƒ -#define IT_INFN A(IT_G) // ∞ -#define IT_INCR A(IT_H) // ∆ -#define IT_FORD A(IT_J) // ª -#define IT_MORD A(IT_K) // º -#define IT_NOT A(IT_L) // ¬ -#define IT_AT A(IT_OGRV) // @ -#define IT_HASH A(IT_AGRV) // # -#define IT_PILC A(IT_UGRV) // ¶ -#define IT_GRV A(IT_BSLS) // ` (not physically present) -#define IT_NARS A(IT_Z) // ∑ -#define IT_DAGG A(IT_X) // † -#define IT_COPY A(IT_C) // © -#define IT_SQRT A(IT_V) // √ -#define IT_INTG A(IT_B) // ∫ -#define IT_STIL A(IT_N) // ˜ (dead) -#define IT_MICR A(IT_M) // µ -#define IT_ELLP A(IT_COMM) // … -#define IT_BULT A(IT_DOT) // • -#define IT_NDSH A(IT_MINS) // – -#define IT_GTEQ S(A(IT_LABK)) // ≥ -#define IT_RDAQ S(A(IT_1)) // » -#define IT_RDQU S(A(IT_2)) // ” -#define IT_RSQU S(A(IT_3)) // ’ -#define IT_CENT S(A(IT_4)) // ¢ -#define IT_PERM S(A(IT_5)) // ‰ -#define IT_RSAQ S(A(IT_6)) // › -#define IT_FRSL S(A(IT_7)) // ⁄ -#define IT_APPL S(A(IT_8)) //  (Apple logo) -#define IT_AEQL S(A(IT_0)) // ≈ -#define IT_IQUE S(A(IT_QUOT)) // ¿ -#define IT_PLMN S(A(IT_IGRV)) // ± -#define IT_SLQU S(A(IT_Q)) // ‚ -#define IT_CAGR S(A(IT_W)) // À -#define IT_CEGR S(A(IT_E)) // È -#define IT_CIGR S(A(IT_R)) // Ì -#define IT_COGR S(A(IT_T)) // Ò -#define IT_CUGR S(A(IT_U)) // Ù -#define IT_NARP S(A(IT_P)) // ∏ -#define IT_LCBR S(A(IT_EGRV)) // { -#define IT_RCBR S(A(IT_PLUS)) // } -#define IT_LOZN S(A(IT_UGRV)) // ◊ -#define IT_MACR S(A(IT_S)) // ¯ -#define IT_BREV S(A(IT_D)) // ˘ -#define IT_DOTA S(A(IT_F)) // ˙ -#define IT_RGNA S(A(IT_G)) // ˚ -#define IT_CEDL S(A(IT_H)) // ¸ -#define IT_DACU S(A(IT_J)) // ˝ -#define IT_OGON S(A(IT_K)) // ˛ -#define IT_CARN S(A(IT_L)) // ˇ -#define IT_CCCE S(A(IT_OGRV)) // Ç -#define IT_DDAG S(A(IT_X)) // ‡ -#define IT_CAAC S(A(IT_C)) // Á -#define IT_CEAC S(A(IT_V)) // É -#define IT_CIAC S(A(IT_B)) // Í -#define IT_COAC S(A(IT_N)) // Ó -#define IT_CUAC S(A(IT_M)) // Ú -#define IT_MDDT S(A(IT_DOT)) // · -#define IT_MDSH S(A(IT_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_italian_mac_iso.h b/quantum/keymap_extras/keymap_italian_mac_iso.h deleted file mode 100644 index f3f01839c32a..000000000000 --- a/quantum/keymap_extras/keymap_italian_mac_iso.h +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define IT_BSLS KC_GRV // (backslash) -#define IT_1 KC_1 // 1 -#define IT_2 KC_2 // 2 -#define IT_3 KC_3 // 3 -#define IT_4 KC_4 // 4 -#define IT_5 KC_5 // 5 -#define IT_6 KC_6 // 6 -#define IT_7 KC_7 // 7 -#define IT_8 KC_8 // 8 -#define IT_9 KC_9 // 9 -#define IT_0 KC_0 // 0 -#define IT_QUOT KC_MINS // ' -#define IT_IGRV KC_EQL // ì -#define IT_Q KC_Q // Q -#define IT_W KC_W // W -#define IT_E KC_E // E -#define IT_R KC_R // R -#define IT_T KC_T // T -#define IT_Y KC_Y // Y -#define IT_U KC_U // U -#define IT_I KC_I // I -#define IT_O KC_O // O -#define IT_P KC_P // P -#define IT_EGRV KC_LBRC // è -#define IT_PLUS KC_RBRC // + -#define IT_A KC_A // A -#define IT_S KC_S // S -#define IT_D KC_D // D -#define IT_F KC_F // F -#define IT_G KC_G // G -#define IT_H KC_H // H -#define IT_J KC_J // J -#define IT_K KC_K // K -#define IT_L KC_L // L -#define IT_OGRV KC_SCLN // ò -#define IT_AGRV KC_QUOT // à -#define IT_UGRV KC_NUHS // ù -#define IT_LABK KC_NUBS // < -#define IT_Z KC_Z // Z -#define IT_X KC_X // X -#define IT_C KC_C // C -#define IT_V KC_V // V -#define IT_B KC_B // B -#define IT_N KC_N // N -#define IT_M KC_M // M -#define IT_COMM KC_COMM // , -#define IT_DOT KC_DOT // . -#define IT_MINS KC_SLSH // - -#define IT_PIPE S(IT_BSLS) // | -#define IT_EXLM S(IT_1) // ! -#define IT_DQUO S(IT_2) // " -#define IT_PND S(IT_3) // £ -#define IT_DLR S(IT_4) // $ -#define IT_PERC S(IT_5) // % -#define IT_AMPR S(IT_6) // & -#define IT_SLSH S(IT_7) // / -#define IT_LPRN S(IT_8) // ( -#define IT_RPRN S(IT_9) // ) -#define IT_EQL S(IT_0) // = -#define IT_QUES S(IT_QUOT) // ? -#define IT_CIRC S(IT_IGRV) // ^ -#define IT_EACU S(IT_EGRV) // é -#define IT_ASTR S(IT_PLUS) // * -#define IT_LCCE S(IT_OGRV) // ç -#define IT_DEG S(IT_AGRV) // ° -#define IT_SECT S(IT_UGRV) // § -#define IT_RABK S(IT_LABK) // > -#define IT_SCLN S(IT_COMM) // ; -#define IT_COLN S(IT_DOT) // : -#define IT_UNDS S(IT_MINS) // _ -#define IT_GRV A(IT_BSLS) // ` -#define IT_LDAQ A(IT_1) // « -#define IT_LDQU A(IT_2) // “ -#define IT_LSQU A(IT_3) // ‘ -#define IT_YEN A(IT_4) // ¥ -#define IT_TILD A(IT_5) // ~ -#define IT_LSAQ A(IT_6) // ‹ -#define IT_DIV A(IT_7) // ÷ -#define IT_ACUT A(IT_8) // ´ (dead) -#define IT_DGRV A(IT_9) // ` (dead) -#define IT_NEQL A(IT_0) // ≠ -#define IT_IEXL A(IT_QUOT) // ¡ -#define IT_DCIR A(IT_IGRV) // ˆ (dead) -#define IT_DLQU A(IT_Q) // „ -#define IT_OMEG A(IT_W) // Ω -#define IT_EURO A(IT_E) // € -#define IT_REGD A(IT_R) // ® -#define IT_TM A(IT_T) // ™ -#define IT_AE A(IT_Y) // Æ -#define IT_DIAE A(IT_U) // ¨ (dead) -#define IT_OE A(IT_I) // Œ -#define IT_OSTR A(IT_O) // Ø -#define IT_PI A(IT_P) // π -#define IT_LBRC A(IT_EGRV) // [ -#define IT_RBRC A(IT_PLUS) // ] -#define IT_ARNG A(IT_A) // Å -#define IT_SS A(IT_S) // ß -#define IT_PDIF A(IT_D) // ∂ -#define IT_FHK A(IT_F) // ƒ -#define IT_INFN A(IT_G) // ∞ -#define IT_INCR A(IT_H) // ∆ -#define IT_FORD A(IT_J) // ª -#define IT_MORD A(IT_K) // º -#define IT_NOT A(IT_L) // ¬ -#define IT_AT A(IT_OGRV) // @ -#define IT_HASH A(IT_AGRV) // # -#define IT_PILC A(IT_UGRV) // ¶ -#define IT_LTEQ A(IT_LABK) // ≤ -#define IT_NARS A(IT_Z) // ∑ -#define IT_DAGG A(IT_X) // † -#define IT_COPY A(IT_C) // © -#define IT_SQRT A(IT_V) // √ -#define IT_INTG A(IT_B) // ∫ -#define IT_STIL A(IT_N) // ˜ (dead) -#define IT_MICR A(IT_M) // µ -#define IT_ELLP A(IT_COMM) // … -#define IT_BULT A(IT_DOT) // • -#define IT_NDSH A(IT_MINS) // – -#define IT_DLSI S(A(IT_BSLS)) // ı -#define IT_RDAQ S(A(IT_1)) // » -#define IT_RDQU S(A(IT_2)) // ” -#define IT_RSQU S(A(IT_3)) // ’ -#define IT_CENT S(A(IT_4)) // ¢ -#define IT_PERM S(A(IT_5)) // ‰ -#define IT_RSAQ S(A(IT_6)) // › -#define IT_FRSL S(A(IT_7)) // ⁄ -#define IT_APPL S(A(IT_8)) //  (Apple logo) -#define IT_AEQL S(A(IT_0)) // ≈ -#define IT_IQUE S(A(IT_QUOT)) // ¿ -#define IT_PLMN S(A(IT_IGRV)) // ± -#define IT_SLQU S(A(IT_Q)) // ‚ -#define IT_CAGR S(A(IT_W)) // À -#define IT_CEGR S(A(IT_E)) // È -#define IT_CIGR S(A(IT_R)) // Ì -#define IT_COGR S(A(IT_T)) // Ò -#define IT_CUGR S(A(IT_U)) // Ù -#define IT_NARP S(A(IT_P)) // ∏ -#define IT_LCBR S(A(IT_EGRV)) // { -#define IT_RCBR S(A(IT_PLUS)) // } -#define IT_MACR S(A(IT_S)) // ¯ -#define IT_BREV S(A(IT_D)) // ˘ -#define IT_DOTA S(A(IT_F)) // ˙ -#define IT_RNGA S(A(IT_G)) // ˚ -#define IT_CEDL S(A(IT_H)) // ¸ -#define IT_DACU S(A(IT_J)) // ˝ -#define IT_OGON S(A(IT_K)) // ˛ -#define IT_CARN S(A(IT_L)) // ˇ -#define IT_CCCE S(A(IT_OGRV)) // Ç -#define IT_LOZN S(A(IT_UGRV)) // ◊ -#define IT_GTEQ S(A(IT_LABK)) // ≥ -#define IT_DDAG S(A(IT_X)) // ‡ -#define IT_CAAC S(A(IT_C)) // Á -#define IT_CEAC S(A(IT_V)) // É -#define IT_CIAC S(A(IT_B)) // Í -#define IT_COAC S(A(IT_N)) // Ó -#define IT_CUAC S(A(IT_M)) // Ú -#define IT_MDDT S(A(IT_DOT)) // · -#define IT_MDSH S(A(IT_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_japanese.h b/quantum/keymap_extras/keymap_japanese.h deleted file mode 100644 index 947317833ed2..000000000000 --- a/quantum/keymap_extras/keymap_japanese.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define JP_ZKHK KC_GRV // Zenkaku ↔ Hankaku ↔ Kanji (半角 ↔ 全角 ↔ 漢字) -#define JP_1 KC_1 // 1 -#define JP_2 KC_2 // 2 -#define JP_3 KC_3 // 3 -#define JP_4 KC_4 // 4 -#define JP_5 KC_5 // 5 -#define JP_6 KC_6 // 6 -#define JP_7 KC_7 // 7 -#define JP_8 KC_8 // 8 -#define JP_9 KC_9 // 9 -#define JP_0 KC_0 // 0 -#define JP_MINS KC_MINS // - -#define JP_CIRC KC_EQL // ^ -#define JP_YEN KC_INT3 // ¥ -#define JP_Q KC_Q // Q -#define JP_W KC_W // W -#define JP_E KC_E // E -#define JP_R KC_R // R -#define JP_T KC_T // T -#define JP_Y KC_Y // Y -#define JP_U KC_U // U -#define JP_I KC_I // I -#define JP_O KC_O // O -#define JP_P KC_P // P -#define JP_AT KC_LBRC // @ -#define JP_LBRC KC_RBRC // [ -#define JP_EISU KC_CAPS // Eisū (英数) -#define JP_A KC_A // A -#define JP_S KC_S // S -#define JP_D KC_D // D -#define JP_F KC_F // F -#define JP_G KC_G // G -#define JP_H KC_H // H -#define JP_J KC_J // J -#define JP_K KC_K // K -#define JP_L KC_L // L -#define JP_SCLN KC_SCLN // ; -#define JP_COLN KC_QUOT // : -#define JP_RBRC KC_NUHS // ] -#define JP_Z KC_Z // Z -#define JP_X KC_X // X -#define JP_C KC_C // C -#define JP_V KC_V // V -#define JP_B KC_B // B -#define JP_N KC_N // N -#define JP_M KC_M // M -#define JP_COMM KC_COMM // , -#define JP_DOT KC_DOT // . -#define JP_SLSH KC_SLSH // / -#define JP_BSLS KC_INT1 // (backslash) -#define JP_MHEN KC_INT5 // Muhenkan (無変換) -#define JP_HENK KC_INT4 // Henkan (変換) -#define JP_KANA KC_INT2 // Katakana ↔ Hiragana ↔ Rōmaji (カタカナ ↔ ひらがな ↔ ローマ字) -#define JP_EXLM S(JP_1) // ! -#define JP_DQUO S(JP_2) // " -#define JP_HASH S(JP_3) // # -#define JP_DLR S(JP_4) // $ -#define JP_PERC S(JP_5) // % -#define JP_AMPR S(JP_6) // & -#define JP_QUOT S(JP_7) // ' -#define JP_LPRN S(JP_8) // ( -#define JP_RPRN S(JP_9) // ) -#define JP_EQL S(JP_MINS) // = -#define JP_TILD S(JP_CIRC) // ~ -#define JP_PIPE S(JP_YEN) // | -#define JP_GRV S(JP_AT) // ` -#define JP_LCBR S(JP_LBRC) // { -#define JP_CAPS S(JP_EISU) // Caps Lock -#define JP_PLUS S(JP_SCLN) // + -#define JP_ASTR S(JP_COLN) // * -#define JP_RCBR S(JP_RBRC) // } -#define JP_LABK S(JP_COMM) // < -#define JP_RABK S(JP_DOT) // > -#define JP_QUES S(JP_SLSH) // ? -#define JP_UNDS S(JP_BSLS) // _ - diff --git a/quantum/keymap_extras/keymap_korean.h b/quantum/keymap_extras/keymap_korean.h deleted file mode 100644 index 440a6b3b4dfc..000000000000 --- a/quantum/keymap_extras/keymap_korean.h +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define KR_GRV KC_GRV // ` -#define KR_1 KC_1 // 1 -#define KR_2 KC_2 // 2 -#define KR_3 KC_3 // 3 -#define KR_4 KC_4 // 4 -#define KR_5 KC_5 // 5 -#define KR_6 KC_6 // 6 -#define KR_7 KC_7 // 7 -#define KR_8 KC_8 // 8 -#define KR_9 KC_9 // 9 -#define KR_0 KC_0 // 0 -#define KR_MINS KC_MINS // - -#define KR_EQL KC_EQL // = -#define KR_Q KC_Q // Q -#define KR_W KC_W // W -#define KR_E KC_E // E -#define KR_R KC_R // R -#define KR_T KC_T // T -#define KR_Y KC_Y // Y -#define KR_U KC_U // U -#define KR_I KC_I // I -#define KR_O KC_O // O -#define KR_P KC_P // P -#define KR_LBRC KC_LBRC // [ -#define KR_RBRC KC_RBRC // ] -#define KR_WON KC_BSLS // ₩ -#define KR_A KC_A // A -#define KR_S KC_S // S -#define KR_D KC_D // D -#define KR_F KC_F // F -#define KR_G KC_G // G -#define KR_H KC_H // H -#define KR_J KC_J // J -#define KR_K KC_K // K -#define KR_L KC_L // L -#define KR_SCLN KC_SCLN // ; -#define KR_QUOT KC_QUOT // ' -#define KR_Z KC_Z // Z -#define KR_X KC_X // X -#define KR_C KC_C // C -#define KR_V KC_V // V -#define KR_B KC_B // B -#define KR_N KC_N // N -#define KR_M KC_M // M -#define KR_COMM KC_COMM // , -#define KR_DOT KC_DOT // . -#define KR_SLSH KC_SLSH // / -#define KR_HANJ KC_LNG2 // Hanja (한자) -#define KR_HAEN KC_LNG1 // Han ↔ Yeong (한 ↔ 영) -#define KR_TILD S(KR_GRV) // ~ -#define KR_EXLM S(KR_1) // ! -#define KR_AT S(KR_2) // @ -#define KR_HASH S(KR_3) // # -#define KR_DLR S(KR_4) // $ -#define KR_PERC S(KR_5) // % -#define KR_CIRC S(KR_6) // ^ -#define KR_AMPR S(KR_7) // & -#define KR_ASTR S(KR_8) // * -#define KR_LPRN S(KR_9) // ( -#define KR_RPRN S(KR_0) // ) -#define KR_UNDS S(KR_MINS) // _ -#define KR_PLUS S(KR_EQL) // + -#define KR_LCBR S(KR_LBRC) // { -#define KR_RCBR S(KR_RBRC) // } -#define KR_PIPE S(KR_WON) // | -#define KR_COLN S(KR_SCLN) // : -#define KR_DQUO S(KR_QUOT) // " -#define KR_LABK S(KR_COMM) // < -#define KR_RABK S(KR_DOT) // > -#define KR_QUES S(KR_SLSH) // ? - diff --git a/quantum/keymap_extras/keymap_latvian.h b/quantum/keymap_extras/keymap_latvian.h deleted file mode 100644 index 2f26b1d8afa5..000000000000 --- a/quantum/keymap_extras/keymap_latvian.h +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define LV_GRV KC_GRV // ` -#define LV_1 KC_1 // 1 -#define LV_2 KC_2 // 2 -#define LV_3 KC_3 // 3 -#define LV_4 KC_4 // 4 -#define LV_5 KC_5 // 5 -#define LV_6 KC_6 // 6 -#define LV_7 KC_7 // 7 -#define LV_8 KC_8 // 8 -#define LV_9 KC_9 // 9 -#define LV_0 KC_0 // 0 -#define LV_MINS KC_MINS // - -#define LV_EQL KC_EQL // = -#define LV_Q KC_Q // Q -#define LV_W KC_W // W -#define LV_E KC_E // E -#define LV_R KC_R // R -#define LV_T KC_T // T -#define LV_Y KC_Y // Y -#define LV_U KC_U // U -#define LV_I KC_I // I -#define LV_O KC_O // O -#define LV_P KC_P // P -#define LV_LBRC KC_LBRC // [ -#define LV_RBRC KC_RBRC // ] -#define LV_A KC_A // A -#define LV_S KC_S // S -#define LV_D KC_D // D -#define LV_F KC_F // F -#define LV_G KC_G // G -#define LV_H KC_H // H -#define LV_J KC_J // J -#define LV_K KC_K // K -#define LV_L KC_L // L -#define LV_SCLN KC_SCLN // ; -#define LV_QUOT KC_QUOT // ' (dead) -#define LV_BSLS KC_NUHS // (backslash) -#define LV_NUBS KC_NUBS // (backslash) -#define LV_Z KC_Z // Z -#define LV_X KC_X // X -#define LV_C KC_C // C -#define LV_V KC_V // V -#define LV_B KC_B // B -#define LV_N KC_N // N -#define LV_M KC_M // M -#define LV_COMM KC_COMM // , -#define LV_DOT KC_DOT // . -#define LV_SLSH KC_SLSH // / -#define LV_TILD S(LV_GRV) // ~ -#define LV_EXLM S(LV_1) // ! -#define LV_AT S(LV_2) // @ -#define LV_HASH S(LV_3) // # -#define LV_DLR S(LV_4) // $ -#define LV_PERC S(LV_5) // % -#define LV_CIRC S(LV_6) // ^ -#define LV_AMPR S(LV_7) // & -#define LV_ASTR S(LV_8) // * -#define LV_LPRN S(LV_9) // ( -#define LV_RPRN S(LV_0) // ) -#define LV_UNDS S(LV_MINS) // _ -#define LV_PLUS S(LV_EQL) // + -#define LV_LCBR S(LV_LBRC) // { -#define LV_RCBR S(LV_RBRC) // } -#define LV_COLN S(LV_SCLN) // : -#define LV_DQUO S(LV_QUOT) // " (dead) -#define LV_PIPE S(LV_BSLS) // | -#define LV_LABK S(LV_COMM) // < -#define LV_RABK S(LV_DOT) // > -#define LV_QUES S(LV_SLSH) // ? -#define LV_SHYP ALGR(LV_GRV) // ­ (soft hyphen) -#define LV_NBSP ALGR(LV_1) // (non-breaking space) -#define LV_LDAQ ALGR(LV_2) // « -#define LV_RDAQ ALGR(LV_3) // » -#define LV_EURO ALGR(LV_4) // € -#define LV_RSQU ALGR(LV_6) // ’ -#define LV_NDSH ALGR(LV_MINS) // – -#define LV_EMAC ALGR(LV_E) // Ē -#define LV_RCED ALGR(LV_R) // Ŗ -#define LV_UMAC ALGR(LV_U) // Ū -#define LV_IMAC ALGR(LV_I) // Ī -#define LV_OMAC ALGR(LV_O) // Ō -#define LV_AMAC ALGR(LV_A) // Ā -#define LV_SCAR ALGR(LV_S) // Š -#define LV_GCED ALGR(LV_G) // Ģ -#define LV_KCED ALGR(LV_K) // Ķ -#define LV_LCED ALGR(LV_L) // Ļ -#define LV_ACUT ALGR(LV_QUOT) // ´ (dead) -#define LV_ZCAR ALGR(LV_Z) // Ž -#define LV_CCAR ALGR(LV_C) // Č -#define LV_NCED ALGR(LV_N) // Ņ -#define LV_SECT S(ALGR(LV_4)) // § -#define LV_DEG S(ALGR(LV_5)) // ° -#define LV_PLMN S(ALGR(LV_7)) // ± -#define LV_MUL S(ALGR(LV_8)) // × -#define LV_MDSH S(ALGR(LV_MINS)) // — -#define LV_DIAE S(ALGR(LV_QUOT)) // ¨ (dead) - diff --git a/quantum/keymap_extras/keymap_lithuanian_azerty.h b/quantum/keymap_extras/keymap_lithuanian_azerty.h deleted file mode 100644 index f6dd94f0ca77..000000000000 --- a/quantum/keymap_extras/keymap_lithuanian_azerty.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define LT_GRV KC_GRV // ` -#define LT_EXLM KC_1 // ! -#define LT_MINS KC_2 // - -#define LT_SLSH KC_3 // / -#define LT_SCLN KC_4 // ; -#define LT_COLN KC_5 // : -#define LT_COMM KC_6 // , -#define LT_DOT KC_7 // . -#define LT_EQL KC_8 // = -#define LT_LPRN KC_9 // ( -#define LT_RPRN KC_0 // ) -#define LT_QUES KC_MINS // ? -#define LT_X KC_EQL // X -#define LT_AOGO KC_Q // Ą -#define LT_ZCAR KC_W // Ž -#define LT_E KC_E // E -#define LT_R KC_R // R -#define LT_T KC_T // T -#define LT_Y KC_Y // Y -#define LT_U KC_U // U -#define LT_I KC_I // I -#define LT_O KC_O // O -#define LT_P KC_P // P -#define LT_IOGO KC_LBRC // Į -#define LT_W KC_RBRC // W -#define LT_A KC_A // A -#define LT_S KC_S // S -#define LT_D KC_D // D -#define LT_SCAR KC_F // Š -#define LT_G KC_G // G -#define LT_H KC_H // H -#define LT_J KC_J // J -#define LT_K KC_K // K -#define LT_L KC_L // L -#define LT_UOGO KC_SCLN // Ų -#define LT_EDOT KC_QUOT // Ė -#define LT_Q KC_NUHS // Q -#define LT_LABK KC_NUBS // < -#define LT_Z KC_Z // Z -#define LT_UMAC KC_X // Ū -#define LT_C KC_C // C -#define LT_V KC_V // V -#define LT_B KC_B // B -#define LT_N KC_N // N -#define LT_M KC_M // M -#define LT_CCAR KC_COMM // Č -#define LT_F KC_DOT // F -#define LT_EOGO KC_SLSH // Ę -#define LT_TILD S(LT_GRV) // ~ -#define LT_1 S(LT_EXLM) // 1 -#define LT_2 S(LT_MINS) // 2 -#define LT_3 S(LT_SLSH) // 3 -#define LT_4 S(LT_SCLN) // 4 -#define LT_5 S(LT_COLN) // 5 -#define LT_6 S(LT_COMM) // 6 -#define LT_7 S(LT_DOT) // 7 -#define LT_8 S(LT_EQL) // 8 -#define LT_9 S(LT_LPRN) // 9 -#define LT_0 S(LT_RPRN) // 0 -#define LT_PLUS S(LT_QUES) // + -#define LT_RABK S(LT_LABK) // > -#define LT_ACUT ALGR(LT_GRV) // ´ -#define LT_AT ALGR(LT_EXLM) // @ -#define LT_UNDS ALGR(LT_MINS) // _ -#define LT_HASH ALGR(LT_SLSH) // # -#define LT_DLR ALGR(LT_SCLN) // $ -#define LT_SECT ALGR(LT_COLN) // § -#define LT_CIRC ALGR(LT_COMM) // ^ -#define LT_AMPR ALGR(LT_DOT) // & -#define LT_ASTR ALGR(LT_EQL) // * -#define LT_LBRC ALGR(LT_LPRN) // [ -#define LT_RBRC ALGR(LT_RPRN) // ] -#define LT_QUOT ALGR(LT_QUES) // ' -#define LT_PERC ALGR(LT_X) // % -#define LT_EURO ALGR(LT_E) // € -#define LT_LCBR ALGR(LT_IOGO) // { -#define LT_RCBR ALGR(LT_W) // } -#define LT_DQUO ALGR(LT_EDOT) // " -#define LT_PIPE ALGR(LT_Q) // | -#define LT_NDSH ALGR(LT_LABK) // – -#define LT_DLQU ALGR(LT_CCAR) // „ -#define LT_LDQU ALGR(LT_F) // “ -#define LT_BSLS ALGR(LT_EOGO) // (backslash) - diff --git a/quantum/keymap_extras/keymap_lithuanian_qwerty.h b/quantum/keymap_extras/keymap_lithuanian_qwerty.h deleted file mode 100644 index 03c6b7a2af5c..000000000000 --- a/quantum/keymap_extras/keymap_lithuanian_qwerty.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define LT_GRV KC_GRV // ` -#define LT_AOGO KC_1 // Ą -#define LT_CCAR KC_2 // Č -#define LT_EOGO KC_3 // Ę -#define LT_EDOT KC_4 // Ė -#define LT_IOGO KC_5 // Į -#define LT_SCAR KC_6 // Š -#define LT_UOGO KC_7 // Ų -#define LT_UMAC KC_8 // Ū -#define LT_9 KC_9 // 9 -#define LT_0 KC_0 // 0 -#define LT_MINS KC_MINS // - -#define LT_ZCAR KC_EQL // Ž -#define LT_Q KC_Q // Q -#define LT_W KC_W // W -#define LT_E KC_E // E -#define LT_R KC_R // R -#define LT_T KC_T // T -#define LT_Y KC_Y // Y -#define LT_U KC_U // U -#define LT_I KC_I // I -#define LT_O KC_O // O -#define LT_P KC_P // P -#define LT_LBRC KC_LBRC // [ -#define LT_RBRC KC_RBRC // ] -#define LT_A KC_A // A -#define LT_S KC_S // S -#define LT_D KC_D // D -#define LT_F KC_F // F -#define LT_G KC_G // G -#define LT_H KC_H // H -#define LT_J KC_J // J -#define LT_K KC_K // K -#define LT_L KC_L // L -#define LT_SCLN KC_SCLN // ; -#define LT_QUOT KC_QUOT // ' -#define LT_BSLS KC_BSLS // (backslash) -#define LT_Z KC_Z // Z -#define LT_X KC_X // X -#define LT_C KC_C // C -#define LT_V KC_V // V -#define LT_B KC_B // B -#define LT_N KC_N // N -#define LT_M KC_M // M -#define LT_COMM KC_COMM // , -#define LT_DOT KC_DOT // . -#define LT_SLSH KC_SLSH // / -#define LT_TILD S(LT_GRV) // ~ -#define LT_LPRN S(LT_9) // ( -#define LT_RPRN S(LT_0) // ) -#define LT_UNDS S(LT_MINS) // _ -#define LT_LCBR S(LT_LBRC) // { -#define LT_RCBR S(LT_RBRC) // } -#define LT_COLN S(LT_SCLN) // : -#define LT_DQUO S(LT_QUOT) // " -#define LT_PIPE S(LT_BSLS) // | -#define LT_LABK S(LT_COMM) // < -#define LT_RABK S(LT_DOT) // > -#define LT_QUES S(LT_SLSH) // ? -#define LT_1 ALGR(LT_AOGO) // 1 -#define LT_2 ALGR(LT_CCAR) // 2 -#define LT_3 ALGR(LT_EOGO) // 3 -#define LT_4 ALGR(LT_EDOT) // 4 -#define LT_5 ALGR(LT_IOGO) // 5 -#define LT_6 ALGR(LT_SCAR) // 6 -#define LT_7 ALGR(LT_UOGO) // 7 -#define LT_8 ALGR(LT_UMAC) // 8 -#define LT_EQL ALGR(LT_ZCAR) // = -#define LT_EURO ALGR(LT_E) // € -#define LT_EXLM S(ALGR(LT_AOGO)) // ! -#define LT_AT S(ALGR(LT_CCAR)) // @ -#define LT_HASH S(ALGR(LT_EOGO)) // # -#define LT_DLR S(ALGR(LT_EDOT)) // $ -#define LT_PERC S(ALGR(LT_IOGO)) // % -#define LT_CIRC S(ALGR(LT_SCAR)) // ^ -#define LT_AMPR S(ALGR(LT_UOGO)) // & -#define LT_ASTR S(ALGR(LT_UMAC)) // * -#define LT_PLUS S(ALGR(LT_ZCAR)) // + - diff --git a/quantum/keymap_extras/keymap_neo2.h b/quantum/keymap_extras/keymap_neo2.h deleted file mode 100644 index bc9445892f9a..000000000000 --- a/quantum/keymap_extras/keymap_neo2.h +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define NE_CIRC KC_GRV // ^ (dead) -#define NE_1 KC_1 // 1 -#define NE_2 KC_2 // 2 -#define NE_3 KC_3 // 3 -#define NE_4 KC_4 // 4 -#define NE_5 KC_5 // 5 -#define NE_6 KC_6 // 6 -#define NE_7 KC_7 // 7 -#define NE_8 KC_8 // 8 -#define NE_9 KC_9 // 9 -#define NE_0 KC_0 // 0 -#define NE_MINS KC_MINS // - -#define NE_GRV KC_EQL // ` (dead) -#define NE_X KC_Q // X -#define NE_V KC_W // V -#define NE_L KC_E // L -#define NE_C KC_R // C -#define NE_W KC_T // W -#define NE_K KC_Y // K -#define NE_H KC_U // H -#define NE_G KC_I // G -#define NE_F KC_O // F -#define NE_Q KC_P // Q -#define NE_SS KC_LBRC // ß -#define NE_ACUT KC_RBRC // ´ (dead) -#define NE_L3L KC_CAPS // (layer 3) -#define NE_U KC_A // U -#define NE_I KC_S // I -#define NE_A KC_D // A -#define NE_E KC_F // E -#define NE_O KC_G // O -#define NE_S KC_H // S -#define NE_N KC_J // N -#define NE_R KC_K // R -#define NE_T KC_L // T -#define NE_D KC_SCLN // D -#define NE_Y KC_QUOT // Y -#define NE_L3R KC_NUHS // (layer 3) -#define NE_L4L KC_NUBS // (layer 4) -#define NE_UDIA KC_Z // Ü -#define NE_ODIA KC_X // Ö -#define NE_ADIA KC_C // Ä -#define NE_P KC_V // P -#define NE_Z KC_B // Z -#define NE_B KC_N // B -#define NE_M KC_M // M -#define NE_COMM KC_COMM // , -#define NE_DOT KC_DOT // . -#define NE_J KC_SLSH // J -#define NE_L4R KC_ALGR // (layer 4) - diff --git a/quantum/keymap_extras/keymap_nordic.h b/quantum/keymap_extras/keymap_nordic.h deleted file mode 100644 index 6464966c7119..000000000000 --- a/quantum/keymap_extras/keymap_nordic.h +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define NO_HALF KC_GRV -#define NO_PLUS KC_MINS -#define NO_ACUT KC_EQL -#define NO_AM KC_LBRC -#define NO_QUOT KC_RBRC // this is the "umlaut" char on Nordic keyboards, Apple layout -#define NO_AE KC_SCLN -#define NO_OSLH KC_QUOT -#define NO_APOS KC_NUHS -#define NO_LESS KC_NUBS -#define NO_MINS KC_SLSH -#define NO_SECT LSFT(NO_HALF) -#define NO_QUO2 LSFT(KC_2) -#define NO_BULT LSFT(KC_4) -#define NO_AMPR LSFT(KC_6) -#define NO_SLSH LSFT(KC_7) -#define NO_LPRN LSFT(KC_8) -#define NO_RPRN LSFT(KC_9) -#define NO_EQL LSFT(KC_0) -#define NO_QUES LSFT(NO_PLUS) -#define NO_GRV LSFT(NO_ACUT) -#define NO_CIRC LSFT(NO_QUOT) -#define NO_GRTR LSFT(NO_LESS) -#define NO_SCLN LSFT(KC_COMM) -#define NO_COLN LSFT(KC_DOT) -#define NO_UNDS LSFT(NO_MINS) -#define NO_AT ALGR(KC_2) -#define NO_PND ALGR(KC_3) -#define NO_DLR ALGR(KC_4) -#define NO_LCBR ALGR(KC_7) -#define NO_LBRC ALGR(KC_8) -#define NO_RBRC ALGR(KC_9) -#define NO_RCBR ALGR(KC_0) -#define NO_PIPE ALGR(KC_NUBS) -#define NO_EURO ALGR(KC_E) -#define NO_TILD ALGR(NO_QUOT) -#define NO_BSLS ALGR(KC_MINS) -#define NO_MU ALGR(KC_M) - diff --git a/quantum/keymap_extras/keymap_norman.h b/quantum/keymap_extras/keymap_norman.h deleted file mode 100644 index 1a3a0bc53a42..000000000000 --- a/quantum/keymap_extras/keymap_norman.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define NM_GRV KC_GRV // ` -#define NM_1 KC_1 // 1 -#define NM_2 KC_2 // 2 -#define NM_3 KC_3 // 3 -#define NM_4 KC_4 // 4 -#define NM_5 KC_5 // 5 -#define NM_6 KC_6 // 6 -#define NM_7 KC_7 // 7 -#define NM_8 KC_8 // 8 -#define NM_9 KC_9 // 9 -#define NM_0 KC_0 // 0 -#define NM_MINS KC_MINS // - -#define NM_EQL KC_EQL // = -#define NM_Q KC_Q // Q -#define NM_W KC_W // W -#define NM_D KC_E // D -#define NM_F KC_R // F -#define NM_K KC_T // K -#define NM_J KC_Y // J -#define NM_U KC_U // U -#define NM_R KC_I // R -#define NM_L KC_O // L -#define NM_SCLN KC_P // ; -#define NM_LBRC KC_LBRC // [ -#define NM_RBRC KC_RBRC // ] -#define NM_BSLS KC_BSLS // (backslash) -#define NM_A KC_A // A -#define NM_S KC_S // S -#define NM_E KC_D // E -#define NM_T KC_F // T -#define NM_G KC_G // G -#define NM_Y KC_H // Y -#define NM_N KC_J // N -#define NM_I KC_K // I -#define NM_O KC_L // O -#define NM_H KC_SCLN // H -#define NM_QUOT KC_QUOT // ' -#define NM_Z KC_Z // Z -#define NM_X KC_X // X -#define NM_C KC_C // C -#define NM_V KC_V // V -#define NM_B KC_B // B -#define NM_P KC_N // P -#define NM_M KC_M // M -#define NM_COMM KC_COMM // , -#define NM_DOT KC_DOT // . -#define NM_SLSH KC_SLSH // / -#define NM_TILD S(NM_GRV) // ~ -#define NM_EXLM S(NM_1) // ! -#define NM_AT S(NM_2) // @ -#define NM_HASH S(NM_3) // # -#define NM_DLR S(NM_4) // $ -#define NM_PERC S(NM_5) // % -#define NM_CIRC S(NM_6) // ^ -#define NM_AMPR S(NM_7) // & -#define NM_ASTR S(NM_8) // * -#define NM_LPRN S(NM_9) // ( -#define NM_RPRN S(NM_0) // ) -#define NM_UNDS S(NM_MINS) // _ -#define NM_PLUS S(NM_EQL) // + -#define NM_COLN S(NM_SCLN) // : -#define NM_LCBR S(NM_LBRC) // { -#define NM_RCBR S(NM_RBRC) // } -#define NM_PIPE S(NM_BSLS) // | -#define NM_DQUO S(NM_QUOT) // " -#define NM_LABK S(NM_COMM) // < -#define NM_RABK S(NM_DOT) // > -#define NM_QUES S(NM_SLSH) // ? - diff --git a/quantum/keymap_extras/keymap_norwegian.h b/quantum/keymap_extras/keymap_norwegian.h deleted file mode 100644 index af16fec8d6a1..000000000000 --- a/quantum/keymap_extras/keymap_norwegian.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define NO_PIPE KC_GRV // | -#define NO_1 KC_1 // 1 -#define NO_2 KC_2 // 2 -#define NO_3 KC_3 // 3 -#define NO_4 KC_4 // 4 -#define NO_5 KC_5 // 5 -#define NO_6 KC_6 // 6 -#define NO_7 KC_7 // 7 -#define NO_8 KC_8 // 8 -#define NO_9 KC_9 // 9 -#define NO_0 KC_0 // 0 -#define NO_PLUS KC_MINS // + -#define NO_BSLS KC_EQL // (backslash) -#define NO_Q KC_Q // Q -#define NO_W KC_W // W -#define NO_E KC_E // E -#define NO_R KC_R // R -#define NO_T KC_T // T -#define NO_Y KC_Y // Y -#define NO_U KC_U // U -#define NO_I KC_I // I -#define NO_O KC_O // O -#define NO_P KC_P // P -#define NO_ARNG KC_LBRC // Å -#define NO_DIAE KC_RBRC // ¨ (dead) -#define NO_A KC_A // A -#define NO_S KC_S // S -#define NO_D KC_D // D -#define NO_F KC_F // F -#define NO_G KC_G // G -#define NO_H KC_H // H -#define NO_J KC_J // J -#define NO_K KC_K // K -#define NO_L KC_L // L -#define NO_OSTR KC_SCLN // Ø -#define NO_AE KC_QUOT // Æ -#define NO_QUOT KC_NUHS // ' -#define NO_LABK KC_NUBS // < -#define NO_Z KC_Z // Z -#define NO_X KC_X // X -#define NO_C KC_C // C -#define NO_V KC_V // V -#define NO_B KC_B // B -#define NO_N KC_N // N -#define NO_M KC_M // M -#define NO_COMM KC_COMM // , -#define NO_DOT KC_DOT // . -#define NO_MINS KC_SLSH // - -#define NO_SECT S(NO_PIPE) // § -#define NO_EXLM S(NO_1) // ! -#define NO_DQUO S(NO_2) // " -#define NO_HASH S(NO_3) // # -#define NO_CURR S(NO_4) // ¤ -#define NO_PERC S(NO_5) // % -#define NO_AMPR S(NO_6) // & -#define NO_SLSH S(NO_7) // / -#define NO_LPRN S(NO_8) // ( -#define NO_RPRN S(NO_9) // ) -#define NO_EQL S(NO_0) // = -#define NO_QUES S(NO_PLUS) // ? -#define NO_GRV S(NO_BSLS) // ` (dead) -#define NO_CIRC S(NO_DIAE) // ^ (dead) -#define NO_ASTR S(NO_QUOT) // * -#define NO_RABK S(NO_LABK) // > -#define NO_SCLN S(NO_COMM) // ; -#define NO_COLN S(NO_DOT) // : -#define NO_UNDS S(NO_MINS) // _ -#define NO_AT ALGR(NO_2) // @ -#define NO_PND ALGR(NO_3) // £ -#define NO_DLR ALGR(NO_4) // $ -#define NO_EURO ALGR(NO_5) // € -#define NO_LCBR ALGR(NO_7) // { -#define NO_LBRC ALGR(NO_8) // [ -#define NO_RBRC ALGR(NO_9) // ] -#define NO_RCBR ALGR(NO_0) // } -#define NO_ACUT ALGR(NO_BSLS) // ´ (dead) -#define NO_TILD ALGR(NO_DIAE) // ~ (dead) -#define NO_MICR ALGR(NO_M) // µ - diff --git a/quantum/keymap_extras/keymap_plover.h b/quantum/keymap_extras/keymap_plover.h deleted file mode 100644 index c0e3311e90bf..000000000000 --- a/quantum/keymap_extras/keymap_plover.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define PV_NUM KC_1 -#define PV_LS KC_Q -#define PV_LT KC_W -#define PV_LP KC_E -#define PV_LH KC_R -#define PV_STAR KC_Y -#define PV_RF KC_U -#define PV_RP KC_I -#define PV_RL KC_O -#define PV_RT KC_P -#define PV_RD KC_LBRC -#define PV_LK KC_S -#define PV_LW KC_D -#define PV_LR KC_F -#define PV_RR KC_J -#define PV_RB KC_K -#define PV_RG KC_L -#define PV_RS KC_SCLN -#define PV_RZ KC_QUOT -#define PV_A KC_C -#define PV_O KC_V -#define PV_E KC_N -#define PV_U KC_M - diff --git a/quantum/keymap_extras/keymap_plover_dvorak.h b/quantum/keymap_extras/keymap_plover_dvorak.h deleted file mode 100644 index 7feb52a25c7b..000000000000 --- a/quantum/keymap_extras/keymap_plover_dvorak.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define PD_NUM DV_1 -#define PD_LS DV_Q -#define PD_LT DV_W -#define PD_LP DV_E -#define PD_LH DV_R -#define PD_LK DV_S -#define PD_LW DV_D -#define PD_LR DV_F -#define PD_STAR DV_Y -#define PD_RF DV_U -#define PD_RP DV_I -#define PD_RL DV_O -#define PD_RT DV_P -#define PD_RD DV_LBRC -#define PD_RR DV_J -#define PD_RB DV_K -#define PD_RG DV_L -#define PD_RS DV_SCLN -#define PD_RZ DV_QUOT -#define PD_A DV_C -#define PD_O DV_V -#define PD_E DV_N -#define PD_U DV_M - diff --git a/quantum/keymap_extras/keymap_polish.h b/quantum/keymap_extras/keymap_polish.h deleted file mode 100644 index 40870ec2378d..000000000000 --- a/quantum/keymap_extras/keymap_polish.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define PL_GRV KC_GRV // ` -#define PL_1 KC_1 // 1 -#define PL_2 KC_2 // 2 -#define PL_3 KC_3 // 3 -#define PL_4 KC_4 // 4 -#define PL_5 KC_5 // 5 -#define PL_6 KC_6 // 6 -#define PL_7 KC_7 // 7 -#define PL_8 KC_8 // 8 -#define PL_9 KC_9 // 9 -#define PL_0 KC_0 // 0 -#define PL_MINS KC_MINS // - -#define PL_EQL KC_EQL // = -#define PL_Q KC_Q // Q -#define PL_W KC_W // W -#define PL_E KC_E // E -#define PL_R KC_R // R -#define PL_T KC_T // T -#define PL_Y KC_Y // Y -#define PL_U KC_U // U -#define PL_I KC_I // I -#define PL_O KC_O // O -#define PL_P KC_P // P -#define PL_LBRC KC_LBRC // [ -#define PL_RBRC KC_RBRC // ] -#define PL_BSLS KC_BSLS // (backslash) -#define PL_A KC_A // A -#define PL_S KC_S // S -#define PL_D KC_D // D -#define PL_F KC_F // F -#define PL_G KC_G // G -#define PL_H KC_H // H -#define PL_J KC_J // J -#define PL_K KC_K // K -#define PL_L KC_L // L -#define PL_SCLN KC_SCLN // ; -#define PL_QUOT KC_QUOT // ' -#define PL_Z KC_Z // Z -#define PL_X KC_X // X -#define PL_C KC_C // C -#define PL_V KC_V // V -#define PL_B KC_B // B -#define PL_N KC_N // N -#define PL_M KC_M // M -#define PL_COMM KC_COMM // , -#define PL_DOT KC_DOT // . -#define PL_SLSH KC_SLSH // / -#define PL_TILD S(PL_GRV) // ~ -#define PL_EXLM S(PL_1) // ! -#define PL_AT S(PL_2) // @ -#define PL_HASH S(PL_3) // # -#define PL_DLR S(PL_4) // $ -#define PL_PERC S(PL_5) // % -#define PL_CIRC S(PL_6) // ^ -#define PL_AMPR S(PL_7) // & -#define PL_ASTR S(PL_8) // * -#define PL_LPRN S(PL_9) // ( -#define PL_RPRN S(PL_0) // ) -#define PL_UNDS S(PL_MINS) // _ -#define PL_PLUS S(PL_EQL) // + -#define PL_LCBR S(PL_LBRC) // { -#define PL_RCBR S(PL_RBRC) // } -#define PL_PIPE S(PL_BSLS) // | -#define PL_COLN S(PL_SCLN) // : -#define PL_DQUO S(PL_QUOT) // " -#define PL_LABK S(PL_COMM) // < -#define PL_RABK S(PL_DOT) // > -#define PL_QUES S(PL_SLSH) // ? -#define PL_EOGO ALGR(PL_E) // Ę -#define PL_EURO ALGR(PL_U) // € -#define PL_OACU ALGR(PL_O) // Ó -#define PL_AOGO ALGR(PL_A) // Ą -#define PL_SACU ALGR(PL_S) // Ś -#define PL_LSTR ALGR(PL_L) // Ł -#define PL_ZDOT ALGR(PL_Z) // Ż -#define PL_ZACU ALGR(PL_X) // Ź -#define PL_CACU ALGR(PL_C) // Ć -#define PL_NACU ALGR(PL_N) // Ń - diff --git a/quantum/keymap_extras/keymap_portuguese.h b/quantum/keymap_extras/keymap_portuguese.h deleted file mode 100644 index b4570ad922d0..000000000000 --- a/quantum/keymap_extras/keymap_portuguese.h +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define PT_BSLS KC_GRV // (backslash) -#define PT_1 KC_1 // 1 -#define PT_2 KC_2 // 2 -#define PT_3 KC_3 // 3 -#define PT_4 KC_4 // 4 -#define PT_5 KC_5 // 5 -#define PT_6 KC_6 // 6 -#define PT_7 KC_7 // 7 -#define PT_8 KC_8 // 8 -#define PT_9 KC_9 // 9 -#define PT_0 KC_0 // 0 -#define PT_QUOT KC_MINS // ' -#define PT_LDAQ KC_EQL // « -#define PT_Q KC_Q // Q -#define PT_W KC_W // W -#define PT_E KC_E // E -#define PT_R KC_R // R -#define PT_T KC_T // T -#define PT_Y KC_Y // Y -#define PT_U KC_U // U -#define PT_I KC_I // I -#define PT_O KC_O // O -#define PT_P KC_P // P -#define PT_PLUS KC_LBRC // + -#define PT_ACUT KC_RBRC // ´ (dead) -#define PT_A KC_A // A -#define PT_S KC_S // S -#define PT_D KC_D // D -#define PT_F KC_F // F -#define PT_G KC_G // G -#define PT_H KC_H // H -#define PT_J KC_J // J -#define PT_K KC_K // K -#define PT_L KC_L // L -#define PT_CCED KC_SCLN // Ç -#define PT_MORD KC_QUOT // º -#define PT_TILD KC_NUHS // ~ (dead) -#define PT_LABK KC_NUBS // < -#define PT_Z KC_Z // Z -#define PT_X KC_X // X -#define PT_C KC_C // C -#define PT_V KC_V // V -#define PT_B KC_B // B -#define PT_N KC_N // N -#define PT_M KC_M // M -#define PT_COMM KC_COMM // , -#define PT_DOT KC_DOT // . -#define PT_MINS KC_SLSH // - -#define PT_PIPE S(PT_BSLS) // | -#define PT_EXLM S(PT_1) // ! -#define PT_DQUO S(PT_2) // " -#define PT_HASH S(PT_3) // # -#define PT_DLR S(PT_4) // $ -#define PT_PERC S(PT_5) // % -#define PT_AMPR S(PT_6) // & -#define PT_SLSH S(PT_7) // / -#define PT_LPRN S(PT_8) // ( -#define PT_RPRN S(PT_9) // ) -#define PT_EQL S(PT_0) // = -#define PT_QUES S(PT_QUOT) // ? -#define PT_RDAQ S(PT_LDAQ) // » -#define PT_ASTR S(PT_PLUS) // * -#define PT_GRV S(PT_ACUT) // ` (dead) -#define PT_FORD S(PT_MORD) // ª -#define PT_CIRC S(PT_TILD) // ^ (dead) -#define PT_RABK S(PT_LABK) // > -#define PT_SCLN S(PT_COMM) // ; -#define PT_COLN S(PT_DOT) // : -#define PT_UNDS S(PT_MINS) // _ -#define PT_AT ALGR(PT_2) // @ -#define PT_PND ALGR(PT_3) // £ -#define PT_SECT ALGR(PT_4) // § -#define PT_LCBR ALGR(PT_7) // { -#define PT_LBRC ALGR(PT_8) // [ -#define PT_RBRC ALGR(PT_9) // ] -#define PT_RCBR ALGR(PT_0) // } -#define PT_DIAE ALGR(PT_PLUS) // ¨ (dead) -#define PT_EURO ALGR(PT_E) // € - diff --git a/quantum/keymap_extras/keymap_portuguese_mac_iso.h b/quantum/keymap_extras/keymap_portuguese_mac_iso.h deleted file mode 100644 index 57a27d04e9b6..000000000000 --- a/quantum/keymap_extras/keymap_portuguese_mac_iso.h +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define PT_SECT KC_GRV // § -#define PT_1 KC_1 // 1 -#define PT_2 KC_2 // 2 -#define PT_3 KC_3 // 3 -#define PT_4 KC_4 // 4 -#define PT_5 KC_5 // 5 -#define PT_6 KC_6 // 6 -#define PT_7 KC_7 // 7 -#define PT_8 KC_8 // 8 -#define PT_9 KC_9 // 9 -#define PT_0 KC_0 // 0 -#define PT_QUOT KC_MINS // ' -#define PT_PLUS KC_EQL // + -#define PT_Q KC_Q // Q -#define PT_W KC_W // W -#define PT_E KC_E // E -#define PT_R KC_R // R -#define PT_T KC_T // T -#define PT_Y KC_Y // Y -#define PT_U KC_U // U -#define PT_I KC_I // I -#define PT_O KC_O // O -#define PT_P KC_P // P -#define PT_MORD KC_LBRC // º -#define PT_ACUT KC_RBRC // ´ (dead) -#define PT_A KC_A // A -#define PT_S KC_S // S -#define PT_D KC_D // D -#define PT_F KC_F // F -#define PT_G KC_G // G -#define PT_H KC_H // H -#define PT_J KC_J // J -#define PT_K KC_K // K -#define PT_L KC_L // L -#define PT_CCED KC_SCLN // Ç -#define PT_TILD KC_QUOT // ~ (dead) -#define PT_BSLS KC_NUHS // (backslash) -#define PT_LABK KC_NUBS // < -#define PT_Z KC_Z // Z -#define PT_X KC_X // X -#define PT_C KC_C // C -#define PT_V KC_V // V -#define PT_B KC_B // B -#define PT_N KC_N // N -#define PT_M KC_M // M -#define PT_COMM KC_COMM // , -#define PT_DOT KC_DOT // . -#define PT_MINS KC_SLSH // - -#define PT_PLMN S(PT_SECT) // ± -#define PT_EXLM S(PT_1) // ! -#define PT_DQUO S(PT_2) // " -#define PT_HASH S(PT_3) // # -#define PT_DLR S(PT_4) // $ -#define PT_PERC S(PT_5) // % -#define PT_AMPR S(PT_6) // & -#define PT_SLSH S(PT_7) // / -#define PT_LPRN S(PT_8) // ( -#define PT_RPRN S(PT_9) // ) -#define PT_EQL S(PT_0) // = -#define PT_QUES S(PT_QUOT) // ? -#define PT_ASTR S(PT_PLUS) // * -#define PT_FORD S(PT_MORD) // ª -#define PT_GRV S(PT_ACUT) // ` (dead) -#define PT_CIRC S(PT_TILD) // ^ (dead) -#define PT_PIPE S(PT_BSLS) // | -#define PT_RABK S(PT_LABK) // > -#define PT_SCLN S(PT_COMM) // ; -#define PT_COLN S(PT_DOT) // : -#define PT_UNDS S(PT_MINS) // _ -#define PT_APPL A(PT_1) //  (Apple logo) -#define PT_AT A(PT_2) // @ -#define PT_EURO A(PT_3) // € -#define PT_PND A(PT_4) // £ -#define PT_PERM A(PT_5) // ‰ -#define PT_PILC A(PT_6) // ¶ -#define PT_DIV A(PT_7) // ÷ -#define PT_LBRC A(PT_8) // [ -#define PT_RBRC A(PT_9) // ] -#define PT_NEQL A(PT_0) // ≠ -#define PT_OE A(PT_Q) // Œ -#define PT_NARS A(PT_W) // ∑ -#define PT_AE A(PT_E) // Æ -#define PT_REGD A(PT_R) // ® -#define PT_TM A(PT_T) // ™ -#define PT_YEN A(PT_Y) // ¥ -#define PT_DAGG A(PT_U) // † -#define PT_DLSI A(PT_I) // ı -#define PT_OSTR A(PT_O) // Ø -#define PT_PI A(PT_P) // π -#define PT_DEG A(PT_MORD) // ° -#define PT_DIAE A(PT_ACUT) // ¨ (dead) -#define PT_ARNG A(PT_A) // å -#define PT_SS A(PT_S) // ß -#define PT_PDIF A(PT_D) // ∂ -#define PT_FHK A(PT_F) // ƒ -#define PT_DOTA A(PT_G) // ˙ -#define PT_CARN A(PT_H) // ˇ -#define PT_MACR A(PT_J) // ¯ -#define PT_DLQU A(PT_K) // „ -#define PT_LSQU A(PT_L) // ‘ -#define PT_CEDL A(PT_CCED) // ¸ -#define PT_STIL A(PT_TILD) // ˜ (dead) -#define PT_LSAQ A(PT_BSLS) // ‹ -#define PT_LTEQ A(PT_LABK) // ≤ -#define PT_OMEG A(PT_Z) // Ω -#define PT_LDAQ A(PT_X) // « -#define PT_COPY A(PT_C) // © -#define PT_SQRT A(PT_V) // √ -#define PT_INTG A(PT_B) // ∫ -#define PT_NOT A(PT_N) // ¬ -#define PT_MICR A(PT_M) // µ -#define PT_LDQU A(PT_COMM) // “ -#define PT_ELLP A(PT_DOT) // … -#define PT_MDSH A(PT_MINS) // — -#define PT_IEXL S(A(PT_1)) // ¡ -#define PT_FI S(A(PT_2)) // fi -#define PT_FL S(A(PT_3)) // fl -#define PT_CENT S(A(PT_4)) // ¢ -#define PT_INFN S(A(PT_5)) // ∞ -#define PT_BULT S(A(PT_6)) // • -#define PT_FRSL S(A(PT_7)) // ⁄ -#define PT_LCBR S(A(PT_8)) // { -#define PT_RCBR S(A(PT_9)) // } -#define PT_AEQL S(A(PT_0)) // ≈ -#define PT_IQUE S(A(PT_QUOT)) // ¿ -#define PT_LOZN S(A(PT_PLUS)) // ◊ -#define PT_DDAG S(A(PT_U)) // ‡ -#define PT_RNGA S(A(PT_I)) // ˚ -#define PT_NARP S(A(PT_P)) // ∏ -#define PT_DACU S(A(PT_ACUT)) // ˝ -#define PT_INCR S(A(PT_D)) // ∆ -#define PT_SLQU S(A(PT_K)) // ‚ -#define PT_RSQU S(A(PT_L)) // ’ -#define PT_OGON S(A(PT_CCED)) // ˛ -#define PT_DCIR S(A(PT_TILD)) // ˆ (dead) -#define PT_RSAQ S(A(PT_BSLS)) // › -#define PT_GTEQ S(A(PT_LABK)) // ≥ -#define PT_RDAQ S(A(PT_X)) // » -#define PT_RDQU S(A(PT_COMM)) // ” -#define PT_MDDT S(A(PT_DOT)) // · -#define PT_NDSH S(A(PT_MINS)) // – - diff --git a/quantum/keymap_extras/keymap_romanian.h b/quantum/keymap_extras/keymap_romanian.h deleted file mode 100644 index cf4c17125f13..000000000000 --- a/quantum/keymap_extras/keymap_romanian.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define RO_DLQU KC_GRV // „ -#define RO_1 KC_1 // 1 -#define RO_2 KC_2 // 2 -#define RO_3 KC_3 // 3 -#define RO_4 KC_4 // 4 -#define RO_5 KC_5 // 5 -#define RO_6 KC_6 // 6 -#define RO_7 KC_7 // 7 -#define RO_8 KC_8 // 8 -#define RO_9 KC_9 // 9 -#define RO_0 KC_0 // 0 -#define RO_MINS KC_MINS // - -#define RO_EQL KC_EQL // = -#define RO_Q KC_Q // Q -#define RO_W KC_W // W -#define RO_E KC_E // E -#define RO_R KC_R // R -#define RO_T KC_T // T -#define RO_Y KC_Y // Y -#define RO_U KC_U // U -#define RO_I KC_I // I -#define RO_O KC_O // O -#define RO_P KC_P // P -#define RO_ABRV KC_LBRC // Ă -#define RO_ICIR KC_RBRC // Î -#define RO_A KC_A // A -#define RO_S KC_S // S -#define RO_D KC_D // D -#define RO_F KC_F // F -#define RO_G KC_G // G -#define RO_H KC_H // H -#define RO_J KC_J // J -#define RO_K KC_K // K -#define RO_L KC_L // L -#define RO_SCOM KC_SCLN // Ș -#define RO_TCOM KC_QUOT // Ț -#define RO_ACIR KC_NUHS //  -#define RO_BSLS KC_NUBS // (backslash) -#define RO_Z KC_Z // Z -#define RO_X KC_X // X -#define RO_C KC_C // C -#define RO_V KC_V // V -#define RO_B KC_B // B -#define RO_N KC_N // N -#define RO_M KC_M // M -#define RO_COMM KC_COMM // , -#define RO_DOT KC_DOT // . -#define RO_SLSH KC_SLSH // / -#define RO_RDQU S(RO_DLQU) // ” -#define RO_EXLM S(RO_1) // ! -#define RO_AT S(RO_2) // @ -#define RO_HASH S(RO_3) // # -#define RO_DLR S(RO_4) // $ -#define RO_PERC S(RO_5) // % -#define RO_CIRC S(RO_6) // ^ -#define RO_AMPR S(RO_7) // & -#define RO_ASTR S(RO_8) // * -#define RO_LPRN S(RO_9) // ( -#define RO_RPRN S(RO_0) // ) -#define RO_UNDS S(RO_MINS) // _ -#define RO_PLUS S(RO_EQL) // + -#define RO_PIPE S(RO_BSLS) // | -#define RO_SCLN S(RO_COMM) // ; -#define RO_COLN S(RO_DOT) // : -#define RO_QUES S(RO_SLSH) // ? -#define RO_GRV ALGR(RO_DLQU) // ` -#define RO_DTIL ALGR(RO_1) // ~ (dead) -#define RO_CARN ALGR(RO_2) // ˇ (dead) -#define RO_DCIR ALGR(RO_3) // ^ (dead) -#define RO_BREV ALGR(RO_4) // ˘ (dead) -#define RO_RNGA ALGR(RO_5) // ° (dead) -#define RO_OGON ALGR(RO_6) // ˛ (dead) -#define RO_DGRV ALGR(RO_7) // ` (dead) -#define RO_DOTA ALGR(RO_8) // ˙ (dead) -#define RO_ACUT ALGR(RO_9) // ´ (dead) -#define RO_DACU ALGR(RO_0) // ˝ (dead) -#define RO_DIAE ALGR(RO_MINS) // ¨ (dead) -#define RO_CEDL ALGR(RO_EQL) // ¸ (dead) -#define RO_EURO ALGR(RO_E) // € -#define RO_SECT ALGR(RO_P) // § -#define RO_LBRC ALGR(RO_ABRV) // [ -#define RO_RBRC ALGR(RO_ICIR) // ] -#define RO_SS ALGR(RO_S) // ß -#define RO_DSTR ALGR(RO_D) // Đ -#define RO_LSTR ALGR(RO_L) // Ł -#define RO_QUOT ALGR(RO_TCOM) // ' -#define RO_COPY ALGR(RO_C) // © -#define RO_LABK ALGR(RO_COMM) // < -#define RO_RABK ALGR(RO_DOT) // > -#define RO_TILD S(ALGR(RO_DLQU)) // ~ -#define RO_NDSH S(ALGR(RO_MINS)) // – -#define RO_PLMN S(ALGR(RO_EQL)) // ± -#define RO_LCBR S(ALGR(RO_ABRV)) // { -#define RO_RCBR S(ALGR(RO_ICIR)) // } -#define RO_DQUO S(ALGR(RO_TCOM)) // " -#define RO_LDAQ S(ALGR(RO_COMM)) // « -#define RO_RDAQ S(ALGR(RO_DOT)) // » - diff --git a/quantum/keymap_extras/keymap_russian.h b/quantum/keymap_extras/keymap_russian.h deleted file mode 100644 index fd3a1604c8e0..000000000000 --- a/quantum/keymap_extras/keymap_russian.h +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define RU_YO KC_GRV // Ё -#define RU_1 KC_1 // 1 -#define RU_2 KC_2 // 2 -#define RU_3 KC_3 // 3 -#define RU_4 KC_4 // 4 -#define RU_5 KC_5 // 5 -#define RU_6 KC_6 // 6 -#define RU_7 KC_7 // 7 -#define RU_8 KC_8 // 8 -#define RU_9 KC_9 // 9 -#define RU_0 KC_0 // 0 -#define RU_MINS KC_MINS // - -#define RU_EQL KC_EQL // = -#define RU_SHTI KC_Q // Й -#define RU_TSE KC_W // Ц -#define RU_U KC_E // У -#define RU_KA KC_R // К -#define RU_IE KC_T // Е -#define RU_EN KC_Y // Н -#define RU_GHE KC_U // Г -#define RU_SHA KC_I // Ш -#define RU_SHCH KC_O // Щ -#define RU_ZE KC_P // З -#define RU_HA KC_LBRC // Х -#define RU_HARD KC_RBRC // Ъ -#define RU_BSLS KC_BSLS // (backslash) -#define RU_EF KC_A // Ф -#define RU_YERU KC_S // Ы -#define RU_VE KC_D // В -#define RU_A KC_F // А -#define RU_PE KC_G // П -#define RU_ER KC_H // Р -#define RU_O KC_J // О -#define RU_EL KC_K // Л -#define RU_DE KC_L // Д -#define RU_ZHE KC_SCLN // Ж -#define RU_E KC_QUOT // Э -#define RU_YA KC_Z // Я -#define RU_CHE KC_X // Ч -#define RU_ES KC_C // С -#define RU_EM KC_V // М -#define RU_I KC_B // И -#define RU_TE KC_N // Т -#define RU_SOFT KC_M // Ь -#define RU_BE KC_COMM // Б -#define RU_YU KC_DOT // Ю -#define RU_DOT KC_SLSH // . -#define RU_EXLM S(RU_1) // ! -#define RU_DQUO S(RU_2) // " -#define RU_NUM S(RU_3) // № -#define RU_SCLN S(RU_4) // ; -#define RU_PERC S(RU_5) // % -#define RU_COLN S(RU_6) // : -#define RU_QUES S(RU_7) // ? -#define RU_ASTR S(RU_8) // * -#define RU_LPRN S(RU_9) // ( -#define RU_RPRN S(RU_0) // ) -#define RU_UNDS S(RU_MINS) // _ -#define RU_PLUS S(RU_EQL) // + -#define RU_SLSH S(RU_BSLS) // / -#define RU_COMM S(RU_DOT) // , -#define RU_RUBL ALGR(RU_8) // ₽ - diff --git a/quantum/keymap_extras/keymap_serbian.h b/quantum/keymap_extras/keymap_serbian.h deleted file mode 100644 index 732e2e939d1e..000000000000 --- a/quantum/keymap_extras/keymap_serbian.h +++ /dev/null @@ -1,97 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define RS_GRV KC_GRV // ` -#define RS_1 KC_1 // 1 -#define RS_2 KC_2 // 2 -#define RS_3 KC_3 // 3 -#define RS_4 KC_4 // 4 -#define RS_5 KC_5 // 5 -#define RS_6 KC_6 // 6 -#define RS_7 KC_7 // 7 -#define RS_8 KC_8 // 8 -#define RS_9 KC_9 // 9 -#define RS_0 KC_0 // 0 -#define RS_QUOT KC_MINS // ' (dead) -#define RS_PLUS KC_EQL // + -#define RS_LJE KC_Q // Љ -#define RS_NJE KC_W // Њ -#define RS_IE KC_E // Е -#define RS_ER KC_R // Р -#define RS_TE KC_T // Т -#define RS_ZE KC_Y // З -#define RS_U KC_U // У -#define RS_I KC_I // И -#define RS_O KC_O // О -#define RS_PE KC_P // П -#define RS_SHA KC_LBRC // Ш -#define RS_DJE KC_RBRC // Ђ -#define RS_A KC_A // А -#define RS_ES KC_S // С -#define RS_DE KC_D // Д -#define RS_EF KC_F // Ф -#define RS_GHE KC_G // Г -#define RS_HA KC_H // Х -#define RS_JE KC_J // Ј -#define RS_KA KC_K // К -#define RS_EL KC_L // Л -#define RS_CHE KC_SCLN // Ч -#define RS_TSHE KC_QUOT // Ћ -#define RS_ZHE KC_NUHS // Ж -#define RS_LABK KC_NUBS // < -#define RS_DZE KC_Z // Ѕ -#define RS_DZHE KC_X // Џ -#define RS_TSE KC_C // Ц -#define RS_VE KC_V // В -#define RS_BE KC_B // Б -#define RS_EN KC_N // Н -#define RS_EM KC_M // М -#define RS_COMM KC_COMM // , -#define RS_DOT KC_DOT // . -#define RS_MINS KC_SLSH // - -#define RS_TILD S(RS_GRV) // ~ -#define RS_EXLM S(RS_1) // ! -#define RS_DQUO S(RS_2) // " -#define RS_HASH S(RS_3) // # -#define RS_DLR S(RS_4) // $ -#define RS_PERC S(RS_5) // % -#define RS_AMPR S(RS_6) // & -#define RS_SLSH S(RS_7) // / -#define RS_LPRN S(RS_8) // ( -#define RS_RPRN S(RS_9) // ) -#define RS_EQL S(RS_0) // = -#define RS_QUES S(RS_QUOT) // ? -#define RS_ASTR S(RS_PLUS) // * -#define RS_RABK S(RS_LABK) // > -#define RS_SCLN S(RS_COMM) // ; -#define RS_COLN S(RS_DOT) // : -#define RS_UNDS S(RS_MINS) // _ -#define RS_EURO ALGR(RS_IE) // € - diff --git a/quantum/keymap_extras/keymap_serbian_latin.h b/quantum/keymap_extras/keymap_serbian_latin.h deleted file mode 100644 index 5151696a1031..000000000000 --- a/quantum/keymap_extras/keymap_serbian_latin.h +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define RS_SLQU KC_GRV // ‚ (dead) -#define RS_1 KC_1 // 1 -#define RS_2 KC_2 // 2 -#define RS_3 KC_3 // 3 -#define RS_4 KC_4 // 4 -#define RS_5 KC_5 // 5 -#define RS_6 KC_6 // 6 -#define RS_7 KC_7 // 7 -#define RS_8 KC_8 // 8 -#define RS_9 KC_9 // 9 -#define RS_0 KC_0 // 0 -#define RS_QUOT KC_MINS // ' -#define RS_PLUS KC_EQL // + -#define RS_Q KC_Q // Q -#define RS_W KC_W // W -#define RS_E KC_E // E -#define RS_R KC_R // R -#define RS_T KC_T // T -#define RS_Z KC_Y // Z -#define RS_U KC_U // U -#define RS_I KC_I // I -#define RS_O KC_O // O -#define RS_P KC_P // P -#define RS_SCAR KC_LBRC // Š -#define RS_DSTR KC_RBRC // Đ -#define RS_A KC_A // A -#define RS_S KC_S // S -#define RS_D KC_D // D -#define RS_F KC_F // F -#define RS_G KC_G // G -#define RS_H KC_H // H -#define RS_J KC_J // J -#define RS_K KC_K // K -#define RS_L KC_L // L -#define RS_CCAR KC_SCLN // Č -#define RS_CACU KC_QUOT // Ć -#define RS_ZCAR KC_NUHS // Ž -#define RS_LABK KC_NUBS // < -#define RS_Y KC_Z // Y -#define RS_X KC_X // X -#define RS_C KC_C // C -#define RS_V KC_V // V -#define RS_B KC_B // B -#define RS_N KC_N // N -#define RS_M KC_M // M -#define RS_COMM KC_COMM // , -#define RS_DOT KC_DOT // . -#define RS_MINS KC_SLSH // - -#define RS_TILD S(RS_SLQU) // ~ -#define RS_EXLM S(RS_1) // ! -#define RS_DQUO S(RS_2) // " -#define RS_HASH S(RS_3) // # -#define RS_DLR S(RS_4) // $ -#define RS_PERC S(RS_5) // % -#define RS_AMPR S(RS_6) // & -#define RS_SLSH S(RS_7) // / -#define RS_LPRN S(RS_8) // ( -#define RS_RPRN S(RS_9) // ) -#define RS_EQL S(RS_0) // = -#define RS_QUES S(RS_QUOT) // ? -#define RS_ASTR S(RS_PLUS) // * -#define RS_RABK S(RS_LABK) // > -#define RS_SCLN S(RS_COMM) // ; -#define RS_COLN S(RS_DOT) // : -#define RS_UNDS S(RS_MINS) // _ -#define RS_CARN ALGR(RS_2) // ˇ (dead) -#define RS_CIRC ALGR(RS_3) // ^ (dead) -#define RS_BREV ALGR(RS_4) // ˘ (dead) -#define RS_RNGA ALGR(RS_5) // ° (dead) -#define RS_OGON ALGR(RS_6) // ˛ (dead) -#define RS_GRV ALGR(RS_7) // ` -#define RS_DOTA ALGR(RS_8) // ˙ (dead) -#define RS_ACUT ALGR(RS_9) // ´ (dead) -#define RS_DACU ALGR(RS_0) // ˝ (dead) -#define RS_DIAE ALGR(RS_QUOT) // ¨ (dead) -#define RS_CEDL ALGR(RS_PLUS) // ¸ (dead) -#define RS_BSLS ALGR(RS_Q) // (backslash) -#define RS_PIPE ALGR(RS_W) // | -#define RS_EURO ALGR(RS_E) // € -#define RS_DIV ALGR(RS_SCAR) // ÷ -#define RS_MUL ALGR(RS_DSTR) // × -#define RS_LBRC ALGR(RS_F) // [ -#define RS_RBRC ALGR(RS_G) // ] -#define RS_LLST ALGR(RS_K) // ł -#define RS_CLST ALGR(RS_L) // Ł -#define RS_SS ALGR(RS_CACU) // ß -#define RS_CURR ALGR(RS_ZCAR) // ¤ -#define RS_AT ALGR(RS_V) // @ -#define RS_LCBR ALGR(RS_B) // { -#define RS_RCBR ALGR(RS_N) // } -#define RS_SECT ALGR(RS_M) // § - diff --git a/quantum/keymap_extras/keymap_slovak.h b/quantum/keymap_extras/keymap_slovak.h deleted file mode 100644 index 81a88fa25c0e..000000000000 --- a/quantum/keymap_extras/keymap_slovak.h +++ /dev/null @@ -1,131 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SK_SCLN KC_GRV // ; -#define SK_PLUS KC_1 // + -#define SK_LCAR KC_2 // ľ -#define SK_SCAR KC_3 // š -#define SK_CCAR KC_4 // č -#define SK_TCAR KC_5 // ť -#define SK_ZCAR KC_6 // ž -#define SK_YACU KC_7 // ý -#define SK_AACU KC_8 // á -#define SK_IACU KC_9 // í -#define SK_EACU KC_0 // é -#define SK_EQL KC_MINS // = -#define SK_ACUT KC_EQL // ´ (dead) -#define SK_Q KC_Q // Q -#define SK_W KC_W // W -#define SK_E KC_E // E -#define SK_R KC_R // R -#define SK_T KC_T // T -#define SK_Z KC_Y // Z -#define SK_U KC_U // U -#define SK_I KC_I // I -#define SK_O KC_O // O -#define SK_P KC_P // P -#define SK_UACU KC_LBRC // ú -#define SK_ADIA KC_RBRC // ä -#define SK_A KC_A // A -#define SK_S KC_S // S -#define SK_D KC_D // D -#define SK_F KC_F // F -#define SK_G KC_G // G -#define SK_H KC_H // H -#define SK_J KC_J // J -#define SK_K KC_K // K -#define SK_L KC_L // L -#define SK_OCIR KC_SCLN // ô -#define SK_SECT KC_QUOT // § -#define SK_NCAR KC_NUHS // ň -#define SK_AMPR KC_NUBS // & -#define SK_Y KC_Z // Y -#define SK_X KC_X // X -#define SK_C KC_C // C -#define SK_V KC_V // V -#define SK_B KC_B // B -#define SK_N KC_N // N -#define SK_M KC_M // M -#define SK_COMM KC_COMM // , -#define SK_DOT KC_DOT // . -#define SK_MINS KC_SLSH // - -#define SK_RNGA S(SK_SCLN) // ° (dead) -#define SK_1 S(SK_PLUS) // 1 -#define SK_2 S(SK_LCAR) // 2 -#define SK_3 S(SK_SCAR) // 3 -#define SK_4 S(SK_CCAR) // 4 -#define SK_5 S(SK_TCAR) // 5 -#define SK_6 S(SK_ZCAR) // 6 -#define SK_7 S(SK_YACU) // 7 -#define SK_8 S(SK_AACU) // 8 -#define SK_9 S(SK_IACU) // 9 -#define SK_0 S(SK_EACU) // 0 -#define SK_PERC S(SK_EQL) // % -#define SK_CARN S(SK_ACUT) // ˇ (dead) -#define SK_SLSH S(SK_UACU) // / -#define SK_LPRN S(SK_ADIA) // ( -#define SK_DQUO S(SK_OCIR) // " -#define SK_EXLM S(SK_SECT) // ! -#define SK_RPRN S(SK_NCAR) // ) -#define SK_ASTR S(SK_AMPR) // * -#define SK_QUES S(SK_COMM) // ? -#define SK_COLN S(SK_DOT) // : -#define SK_UNDS S(SK_MINS) // _ -#define SK_TILD ALGR(SK_PLUS) // ~ -#define SK_CIRC ALGR(SK_SCAR) // ^ (dead) -#define SK_BREV ALGR(SK_CCAR) // ˘ (dead) -#define SK_OGON ALGR(SK_TCAR) // ˛ (dead) -#define SK_GRV ALGR(SK_ZCAR) // ` -#define SK_DOTA ALGR(SK_YACU) // ˙ (dead) -#define SK_DACU ALGR(SK_EACU) // ˝ (dead) -#define SK_DIAE ALGR(SK_EQL) // ¨ (dead) -#define SK_CEDL ALGR(SK_ACUT) // ¸ (dead) -#define SK_BSLS ALGR(SK_Q) // (backslash) -#define SK_PIPE ALGR(SK_W) // | -#define SK_EURO ALGR(SK_E) // € -#define SK_QUOT ALGR(SK_P) // ' -#define SK_DIV ALGR(SK_UACU) // ÷ -#define SK_MUL ALGR(SK_ADIA) // × -#define SK_LDST ALGR(SK_S) // đ -#define SK_CDST ALGR(SK_D) // Đ -#define SK_LBRC ALGR(SK_F) // [ -#define SK_RBRC ALGR(SK_G) // ] -#define SK_LLST ALGR(SK_K) // ł -#define SK_CLST ALGR(SK_L) // Ł -#define SK_DLR ALGR(SK_OCIR) // $ -#define SK_SS ALGR(SK_SECT) // ß -#define SK_CURR ALGR(SK_NCAR) // ¤ -#define SK_LABK ALGR(SK_AMPR) // < -#define SK_RABK ALGR(SK_Y) // > -#define SK_HASH ALGR(SK_X) // # -#define SK_AT ALGR(SK_V) // @ -#define SK_LCBR ALGR(SK_B) // { -#define SK_RCBR ALGR(SK_N) // } - diff --git a/quantum/keymap_extras/keymap_slovenian.h b/quantum/keymap_extras/keymap_slovenian.h deleted file mode 100644 index 1e17342c2734..000000000000 --- a/quantum/keymap_extras/keymap_slovenian.h +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SI_CEDL KC_GRV // ¸ (dead) -#define SI_1 KC_1 // 1 -#define SI_2 KC_2 // 2 -#define SI_3 KC_3 // 3 -#define SI_4 KC_4 // 4 -#define SI_5 KC_5 // 5 -#define SI_6 KC_6 // 6 -#define SI_7 KC_7 // 7 -#define SI_8 KC_8 // 8 -#define SI_9 KC_9 // 9 -#define SI_0 KC_0 // 0 -#define SI_QUOT KC_MINS // ' -#define SI_PLUS KC_EQL // + -#define SI_Q KC_Q // Q -#define SI_W KC_W // W -#define SI_E KC_E // E -#define SI_R KC_R // R -#define SI_T KC_T // T -#define SI_Z KC_Y // Z -#define SI_U KC_U // U -#define SI_I KC_I // I -#define SI_O KC_O // O -#define SI_P KC_P // P -#define SI_SCAR KC_LBRC // Š -#define SI_DSTR KC_RBRC // Đ -#define SI_A KC_A // A -#define SI_S KC_S // S -#define SI_D KC_D // D -#define SI_F KC_F // F -#define SI_G KC_G // G -#define SI_H KC_H // H -#define SI_J KC_J // J -#define SI_K KC_K // K -#define SI_L KC_L // L -#define SI_CCAR KC_SCLN // Č -#define SI_CACU KC_QUOT // Ć -#define SI_ZCAR KC_NUHS // Ž -#define SI_LABK KC_NUBS // < -#define SI_Y KC_Z // Y -#define SI_X KC_X // X -#define SI_C KC_C // C -#define SI_V KC_V // V -#define SI_B KC_B // B -#define SI_N KC_N // N -#define SI_M KC_M // M -#define SI_COMM KC_COMM // , -#define SI_DOT KC_DOT // . -#define SI_MINS KC_SLSH // - -#define SI_DIAE S(SI_CEDL) // ¨ (dead) -#define SI_EXLM S(SI_1) // ! -#define SI_DQUO S(SI_2) // " -#define SI_HASH S(SI_3) // # -#define SI_DLR S(SI_4) // $ -#define SI_PERC S(SI_5) // % -#define SI_AMPR S(SI_6) // & -#define SI_SLSH S(SI_7) // / -#define SI_LPRN S(SI_8) // ( -#define SI_RPRN S(SI_9) // ) -#define SI_EQL S(SI_0) // = -#define SI_QUES S(SI_QUOT) // ? -#define SI_ASTR S(SI_PLUS) // * -#define SI_RABK S(SI_LABK) // > -#define SI_SCLN S(SI_COMM) // ; -#define SI_COLN S(SI_DOT) // : -#define SI_UNDS S(SI_MINS) // _ -#define SI_TILD ALGR(SI_1) // ~ -#define SI_CARN ALGR(SI_2) // ˇ (dead) -#define SI_CIRC ALGR(SI_3) // ^ (dead) -#define SI_BREV ALGR(SI_4) // ˘ (dead) -#define SI_RNGA ALGR(SI_5) // ° (dead) -#define SI_OGON ALGR(SI_6) // ˛ (dead) -#define SI_GRV ALGR(SI_7) // ` -#define SI_DOTA ALGR(SI_8) // ˙ (dead) -#define SI_ACUT ALGR(SI_9) // ´ (dead) -#define SI_DACU ALGR(SI_0) // ˝ (dead) -#define SI_BSLS ALGR(SI_Q) // (backslash) -#define SI_PIPE ALGR(SI_W) // | -#define SI_EURO ALGR(SI_E) // € -#define SI_DIV ALGR(SI_SCAR) // ÷ -#define SI_MUL ALGR(SI_DSTR) // × -#define SI_LBRC ALGR(SI_F) // [ -#define SI_RBRC ALGR(SI_G) // ] -#define SI_LLST ALGR(SI_K) // ł -#define SI_CLST ALGR(SI_L) // Ł -#define SI_SS ALGR(SI_CACU) // ß -#define SI_CURR ALGR(SI_ZCAR) // ¤ -#define SI_AT ALGR(SI_V) // @ -#define SI_LCBR ALGR(SI_B) // { -#define SI_RCBR ALGR(SI_N) // } -#define SI_SECT ALGR(SI_M) // § - diff --git a/quantum/keymap_extras/keymap_spanish.h b/quantum/keymap_extras/keymap_spanish.h deleted file mode 100644 index bcdd5af0c257..000000000000 --- a/quantum/keymap_extras/keymap_spanish.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define ES_MORD KC_GRV // º -#define ES_1 KC_1 // 1 -#define ES_2 KC_2 // 2 -#define ES_3 KC_3 // 3 -#define ES_4 KC_4 // 4 -#define ES_5 KC_5 // 5 -#define ES_6 KC_6 // 6 -#define ES_7 KC_7 // 7 -#define ES_8 KC_8 // 8 -#define ES_9 KC_9 // 9 -#define ES_0 KC_0 // 0 -#define ES_QUOT KC_MINS // ' -#define ES_IEXL KC_EQL // ¡ -#define ES_Q KC_Q // Q -#define ES_W KC_W // W -#define ES_E KC_E // E -#define ES_R KC_R // R -#define ES_T KC_T // T -#define ES_Y KC_Y // Y -#define ES_U KC_U // U -#define ES_I KC_I // I -#define ES_O KC_O // O -#define ES_P KC_P // P -#define ES_GRV KC_LBRC // ` (dead) -#define ES_PLUS KC_RBRC // + -#define ES_A KC_A // A -#define ES_S KC_S // S -#define ES_D KC_D // D -#define ES_F KC_F // F -#define ES_G KC_G // G -#define ES_H KC_H // H -#define ES_J KC_J // J -#define ES_K KC_K // K -#define ES_L KC_L // L -#define ES_NTIL KC_SCLN // Ñ -#define ES_ACUT KC_QUOT // ´ (dead) -#define ES_CCED KC_NUHS // Ç -#define ES_LABK KC_NUBS // < -#define ES_Z KC_Z // Z -#define ES_X KC_X // X -#define ES_C KC_C // C -#define ES_V KC_V // V -#define ES_B KC_B // B -#define ES_N KC_N // N -#define ES_M KC_M // M -#define ES_COMM KC_COMM // , -#define ES_DOT KC_DOT // . -#define ES_MINS KC_SLSH // - -#define ES_FORD S(ES_MORD) // ª -#define ES_EXLM S(ES_1) // ! -#define ES_DQUO S(ES_2) // " -#define ES_BULT S(ES_3) // · -#define ES_DLR S(ES_4) // $ -#define ES_PERC S(ES_5) // % -#define ES_AMPR S(ES_6) // & -#define ES_SLSH S(ES_7) // / -#define ES_LPRN S(ES_8) // ( -#define ES_RPRN S(ES_9) // ) -#define ES_EQL S(ES_0) // = -#define ES_QUES S(ES_QUOT) // ? -#define ES_IQUE S(ES_IEXL) // ¿ -#define ES_CIRC S(ES_GRV) // ^ (dead) -#define ES_ASTR S(ES_PLUS) // * -#define ES_DIAE S(ES_ACUT) // ¨ (dead) -#define ES_RABK S(ES_LABK) // > -#define ES_SCLN S(KC_COMM) // ; -#define ES_COLN S(KC_DOT) // : -#define ES_UNDS S(ES_MINS) // _ -#define ES_BSLS ALGR(ES_MORD) // (backslash) -#define ES_PIPE ALGR(ES_1) // | -#define ES_AT ALGR(ES_2) // @ -#define ES_HASH ALGR(ES_3) // # -#define ES_TILD ALGR(ES_4) // ~ -#define ES_EURO ALGR(ES_5) // € -#define ES_NOT ALGR(ES_6) // ¬ -#define ES_LBRC ALGR(ES_GRV) // [ -#define ES_RBRC ALGR(ES_PLUS) // ] -#define ES_LCBR ALGR(ES_ACUT) // { -#define ES_RCBR ALGR(ES_CCED) // } - diff --git a/quantum/keymap_extras/keymap_spanish_dvorak.h b/quantum/keymap_extras/keymap_spanish_dvorak.h deleted file mode 100644 index fb033df770a1..000000000000 --- a/quantum/keymap_extras/keymap_spanish_dvorak.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define DV_MORD KC_GRV // º -#define DV_1 KC_1 // 1 -#define DV_2 KC_2 // 2 -#define DV_3 KC_3 // 3 -#define DV_4 KC_4 // 4 -#define DV_5 KC_5 // 5 -#define DV_6 KC_6 // 6 -#define DV_7 KC_7 // 7 -#define DV_8 KC_8 // 8 -#define DV_9 KC_9 // 9 -#define DV_0 KC_0 // 0 -#define DV_QUOT KC_MINS // ' -#define DV_IEXL KC_EQL // ¡ -#define DV_DOT KC_Q // . -#define DV_COMM KC_W // , -#define DV_NTIL KC_E // Ñ -#define DV_P KC_R // P -#define DV_Y KC_T // Y -#define DV_F KC_Y // F -#define DV_G KC_U // G -#define DV_C KC_I // C -#define DV_H KC_O // H -#define DV_L KC_P // L -#define DV_GRV KC_LBRC // ` (dead) -#define DV_PLUS KC_RBRC // + -#define DV_A KC_A // A -#define DV_O KC_S // O -#define DV_E KC_D // E -#define DV_U KC_F // U -#define DV_I KC_G // I -#define DV_D KC_H // D -#define DV_R KC_J // R -#define DV_T KC_K // T -#define DV_N KC_L // N -#define DV_S KC_SCLN // S -#define DV_ACUT KC_QUOT // ´ (dead) -#define DV_CCED KC_NUHS // Ç -#define DV_LABK KC_NUBS // < -#define DV_MINS KC_Z // - -#define DV_Q KC_X // Q -#define DV_J KC_C // J -#define DV_K KC_V // K -#define DV_X KC_B // X -#define DV_B KC_N // B -#define DV_M KC_M // M -#define DV_W KC_COMM // W -#define DV_V KC_DOT // V -#define DV_Z KC_SLSH // Z -#define DV_FORD S(DV_MORD) // ª -#define DV_EXLM S(DV_1) // ! -#define DV_DQUO S(DV_2) // " -#define DV_BULT S(DV_3) // · -#define DV_DLR S(DV_4) // $ -#define DV_PERC S(DV_5) // % -#define DV_AMPR S(DV_6) // & -#define DV_SLSH S(DV_7) // / -#define DV_LPRN S(DV_8) // ( -#define DV_RPRN S(DV_9) // ) -#define DV_EQL S(DV_0) // = -#define DV_QUES S(DV_QUOT) // ? -#define DV_IQUE S(DV_IEXL) // ¿ -#define DV_COLN S(DV_DOT) // : -#define DV_SCLN S(DV_COMM) // ; -#define DV_CIRC S(DV_GRV) // ^ (dead) -#define DV_ASTR S(DV_PLUS) // * -#define DV_DIAE S(DV_ACUT) // ¨ (dead) -#define DV_RABK S(DV_LABK) // > -#define DV_UNDS S(DV_MINS) // _ -#define DV_BSLS ALGR(DV_MORD) // (backslash) -#define DV_PIPE ALGR(DV_1) // | -#define DV_AT ALGR(DV_2) // @ -#define DV_HASH ALGR(DV_3) // # -#define DV_TILD ALGR(DV_4) // ~ -#define DV_EURO ALGR(DV_5) // € -#define DV_NOT ALGR(DV_6) // ¬ -#define DV_LBRC ALGR(DV_GRV) // [ -#define DV_RBRC ALGR(DV_PLUS) // ] -#define DV_LCBR ALGR(DV_ACUT) // { -#define DV_RCBR ALGR(DV_CCED) // } - diff --git a/quantum/keymap_extras/keymap_steno.h b/quantum/keymap_extras/keymap_steno.h deleted file mode 100644 index 852b2f71211d..000000000000 --- a/quantum/keymap_extras/keymap_steno.h +++ /dev/null @@ -1,119 +0,0 @@ -/* Copyright 2017 Joseph Wasson - * - * 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 . - */ - -#pragma once - -#include "keycodes.h" - -// List of keycodes for the steno keyboard. To prevent -// errors, this must be <= 42 total entries in order to -// support the GeminiPR protocol. -enum steno_keycodes { - STN__MIN = QK_STENO, - STN_FN = STN__MIN, - STN_NUM, - STN_N1 = STN_NUM, - STN_N2, - STN_N3, - STN_N4, - STN_N5, - STN_N6, - STN_SL, - STN_S1 = STN_SL, - STN_S2, - STN_TL, - STN_KL, - STN_PL, - STN_WL, - STN_HL, - STN_RL, - STN_A, - STN_O, - STN_STR, - STN_ST1 = STN_STR, - STN_ST2, - STN_RES1, - STN_RE1 = STN_RES1, - STN_RES2, - STN_RE2 = STN_RES2, - STN_PWR, - STN_ST3, - STN_ST4, - STN_E, - STN_U, - STN_FR, - STN_RR, - STN_PR, - STN_BR, - STN_LR, - STN_GR, - STN_TR, - STN_SR, - STN_DR, - STN_N7, - STN_N8, - STN_N9, - STN_NA, - STN_NB, - STN_NC, - STN_ZR, - STN__MAX = STN_ZR, // must be less than QK_STENO_BOLT -}; - -#ifdef STENO_COMBINEDMAP -enum steno_combined_keycodes { - STN_S3 = QK_STENO_COMB, - STN_TKL, - STN_PWL, - STN_HRL, - STN_FRR, - STN_PBR, - STN_LGR, - STN_TSR, - STN_DZR, - STN_AO, - STN_EU, - STN_COMB_MAX = STN_EU, -}; -#endif - -#ifdef STENO_ENABLE_BOLT -// TxBolt Codes -# define TXB_NUL 0 -# define TXB_S_L 0b00000001 -# define TXB_T_L 0b00000010 -# define TXB_K_L 0b00000100 -# define TXB_P_L 0b00001000 -# define TXB_W_L 0b00010000 -# define TXB_H_L 0b00100000 -# define TXB_R_L 0b01000001 -# define TXB_A_L 0b01000010 -# define TXB_O_L 0b01000100 -# define TXB_STR 0b01001000 -# define TXB_E_R 0b01010000 -# define TXB_U_R 0b01100000 -# define TXB_F_R 0b10000001 -# define TXB_R_R 0b10000010 -# define TXB_P_R 0b10000100 -# define TXB_B_R 0b10001000 -# define TXB_L_R 0b10010000 -# define TXB_G_R 0b10100000 -# define TXB_T_R 0b11000001 -# define TXB_S_R 0b11000010 -# define TXB_D_R 0b11000100 -# define TXB_Z_R 0b11001000 -# define TXB_NUM 0b11010000 -#endif // STENO_ENABLE_BOLT diff --git a/quantum/keymap_extras/keymap_swedish.h b/quantum/keymap_extras/keymap_swedish.h deleted file mode 100644 index acb49f77738b..000000000000 --- a/quantum/keymap_extras/keymap_swedish.h +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SE_SECT KC_GRV // § -#define SE_1 KC_1 // 1 -#define SE_2 KC_2 // 2 -#define SE_3 KC_3 // 3 -#define SE_4 KC_4 // 4 -#define SE_5 KC_5 // 5 -#define SE_6 KC_6 // 6 -#define SE_7 KC_7 // 7 -#define SE_8 KC_8 // 8 -#define SE_9 KC_9 // 9 -#define SE_0 KC_0 // 0 -#define SE_PLUS KC_MINS // + -#define SE_ACUT KC_EQL // ´ (dead) -#define SE_Q KC_Q // Q -#define SE_W KC_W // W -#define SE_E KC_E // E -#define SE_R KC_R // R -#define SE_T KC_T // T -#define SE_Y KC_Y // Y -#define SE_U KC_U // U -#define SE_I KC_I // I -#define SE_O KC_O // O -#define SE_P KC_P // P -#define SE_ARNG KC_LBRC // Å -#define SE_DIAE KC_RBRC // ¨ (dead) -#define SE_A KC_A // A -#define SE_S KC_S // S -#define SE_D KC_D // D -#define SE_F KC_F // F -#define SE_G KC_G // G -#define SE_H KC_H // H -#define SE_J KC_J // J -#define SE_K KC_K // K -#define SE_L KC_L // L -#define SE_ODIA KC_SCLN // Ö -#define SE_ADIA KC_QUOT // Ä -#define SE_QUOT KC_NUHS // ' -#define SE_LABK KC_NUBS // < -#define SE_Z KC_Z // Z -#define SE_X KC_X // X -#define SE_C KC_C // C -#define SE_V KC_V // V -#define SE_B KC_B // B -#define SE_N KC_N // N -#define SE_M KC_M // M -#define SE_COMM KC_COMM // , -#define SE_DOT KC_DOT // . -#define SE_MINS KC_SLSH // - -#define SE_HALF S(SE_SECT) // ½ -#define SE_EXLM S(SE_1) // ! -#define SE_DQUO S(SE_2) // " -#define SE_HASH S(SE_3) // # -#define SE_CURR S(SE_4) // ¤ -#define SE_PERC S(SE_5) // % -#define SE_AMPR S(SE_6) // & -#define SE_SLSH S(SE_7) // / -#define SE_LPRN S(SE_8) // ( -#define SE_RPRN S(SE_9) // ) -#define SE_EQL S(SE_0) // = -#define SE_QUES S(SE_PLUS) // ? -#define SE_GRV S(SE_ACUT) // ` (dead) -#define SE_CIRC S(SE_DIAE) // ^ (dead) -#define SE_ASTR S(SE_QUOT) // * -#define SE_RABK S(SE_LABK) // > -#define SE_SCLN S(SE_COMM) // ; -#define SE_COLN S(SE_DOT) // : -#define SE_UNDS S(SE_MINS) // _ -#define SE_AT ALGR(SE_2) // @ -#define SE_PND ALGR(SE_3) // £ -#define SE_DLR ALGR(SE_4) // $ -#define SE_EURO ALGR(SE_5) // € -#define SE_LCBR ALGR(SE_7) // { -#define SE_LBRC ALGR(SE_8) // [ -#define SE_RBRC ALGR(SE_9) // ] -#define SE_RCBR ALGR(SE_0) // } -#define SE_BSLS ALGR(SE_PLUS) // (backslash) -#define SE_TILD ALGR(SE_DIAE) // ~ (dead) -#define SE_PIPE ALGR(SE_LABK) // | -#define SE_MICR ALGR(SE_M) // µ - diff --git a/quantum/keymap_extras/keymap_swedish_mac_ansi.h b/quantum/keymap_extras/keymap_swedish_mac_ansi.h deleted file mode 100644 index ef48a9e493e4..000000000000 --- a/quantum/keymap_extras/keymap_swedish_mac_ansi.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SE_LABK KC_GRV // < -#define SE_1 KC_1 // 1 -#define SE_2 KC_2 // 2 -#define SE_3 KC_3 // 3 -#define SE_4 KC_4 // 4 -#define SE_5 KC_5 // 5 -#define SE_6 KC_6 // 6 -#define SE_7 KC_7 // 7 -#define SE_8 KC_8 // 8 -#define SE_9 KC_9 // 9 -#define SE_0 KC_0 // 0 -#define SE_PLUS KC_MINS // + -#define SE_ACUT KC_EQL // ´ (dead) -#define SE_Q KC_Q // Q -#define SE_W KC_W // W -#define SE_E KC_E // E -#define SE_R KC_R // R -#define SE_T KC_T // T -#define SE_Y KC_Y // Y -#define SE_U KC_U // U -#define SE_I KC_I // I -#define SE_O KC_O // O -#define SE_P KC_P // P -#define SE_ARNG KC_LBRC // Å -#define SE_DIAE KC_RBRC // ¨ (dead) -#define SE_QUOT KC_NUHS // ' -#define SE_A KC_A // A -#define SE_S KC_S // S -#define SE_D KC_D // D -#define SE_F KC_F // F -#define SE_G KC_G // G -#define SE_H KC_H // H -#define SE_J KC_J // J -#define SE_K KC_K // K -#define SE_L KC_L // L -#define SE_ODIA KC_SCLN // Ö -#define SE_ADIA KC_QUOT // Ä -#define SE_Z KC_Z // Z -#define SE_X KC_X // X -#define SE_C KC_C // C -#define SE_V KC_V // V -#define SE_B KC_B // B -#define SE_N KC_N // N -#define SE_M KC_M // M -#define SE_COMM KC_COMM // , -#define SE_DOT KC_DOT // . -#define SE_MINS KC_SLSH // - -#define SE_RABK S(SE_LABK) // > -#define SE_EXLM S(SE_1) // ! -#define SE_DQUO S(SE_2) // " -#define SE_HASH S(SE_3) // # -#define SE_EURO S(SE_4) // € -#define SE_PERC S(SE_5) // % -#define SE_AMPR S(SE_6) // & -#define SE_SLSH S(SE_7) // / -#define SE_LPRN S(SE_8) // ( -#define SE_RPRN S(SE_9) // ) -#define SE_EQL S(SE_0) // = -#define SE_QUES S(SE_PLUS) // ? -#define SE_GRV S(SE_ACUT) // ` -#define SE_CIRC S(SE_DIAE) // ^ (dead) -#define SE_ASTR S(SE_QUOT) // * -#define SE_SCLN S(SE_COMM) // ; -#define SE_COLN S(SE_DOT) // : -#define SE_UNDS S(SE_MINS) // _ -#define SE_LTEQ A(SE_LABK) // ≤ -#define SE_COPY A(SE_1) // © -#define SE_TM A(SE_2) // ™ -#define SE_PND A(SE_3) // £ -#define SE_DLR A(SE_4) // $ -#define SE_INFN A(SE_5) // ∞ -#define SE_SECT A(SE_6) // § -#define SE_PIPE A(SE_7) // | -#define SE_LBRC A(SE_8) // [ -#define SE_RBRC A(SE_9) // ] -#define SE_AEQL A(SE_0) // ≈ -#define SE_PLMN A(SE_PLUS) // ± -#define SE_BULT A(SE_Q) // • -#define SE_OMEG A(SE_W) // Ω -#define SE_EACU A(SE_E) // É -#define SE_REGD A(SE_R) // ® -#define SE_DAGG A(SE_T) // † -#define SE_MICR A(SE_Y) // µ -#define SE_UDIA A(SE_U) // Ü -#define SE_DLSI A(SE_I) // ı -#define SE_OE A(SE_O) // Œ -#define SE_PI A(SE_P) // π -#define SE_DOTA A(SE_ARNG) // ˙ -#define SE_TILD A(SE_DIAE) // ~ (dead) -#define SE_AT A(SE_QUOT) // @ -#define SE_APPL A(SE_A) //  (Apple logo) -#define SE_SS A(SE_S) // ß -#define SE_PDIF A(SE_D) // ∂ -#define SE_FHK A(SE_F) // ƒ -#define SE_CEDL A(SE_G) // ¸ -#define SE_OGON A(SE_H) // ˛ -#define SE_SQRT A(SE_J) // √ -#define SE_FORD A(SE_K) // ª -#define SE_FI A(SE_L) // fi -#define SE_OSTR A(SE_ODIA) // Ø -#define SE_AE A(SE_ADIA) // Æ -#define SE_DIV A(SE_Z) // ÷ -#define SE_CCED A(SE_C) // Ç -#define SE_LSAQ A(SE_V) // ‹ -#define SE_RSAQ A(SE_B) // › -#define SE_LSQU A(SE_N) // ‘ -#define SE_RSQU A(SE_M) // ’ -#define SE_SLQU A(SE_COMM) // ‚ -#define SE_ELLP A(SE_DOT) // … -#define SE_NDSH A(SE_MINS) // – -#define SE_GTEQ S(A(SE_LABK)) // ≥ -#define SE_IEXL S(A(SE_1)) // ¡ -#define SE_YEN S(A(SE_3)) // ¥ -#define SE_CENT S(A(SE_4)) // ¢ -#define SE_PERM S(A(SE_5)) // ‰ -#define SE_PILC S(A(SE_6)) // ¶ -#define SE_BSLS S(A(SE_7)) // (backslash) -#define SE_LCBR S(A(SE_8)) // { -#define SE_RCBR S(A(SE_9)) // } -#define SE_NEQL S(A(SE_0)) // ≠ -#define SE_IQUE S(A(SE_PLUS)) // ¿ -#define SE_DEG S(A(SE_Q)) // ° -#define SE_DACU S(A(SE_W)) // ˝ -#define SE_DDAG S(A(SE_T)) // ‡ -#define SE_STIL S(A(SE_Y)) // ˜ -#define SE_DCIR S(A(SE_I)) // ˆ -#define SE_NARP S(A(SE_P)) // ∏ -#define SE_RNGA S(A(SE_ARNG)) // ˚ -#define SE_LOZN S(A(SE_A)) // ◊ -#define SE_NARS S(A(SE_S)) // ∑ -#define SE_INCR S(A(SE_D)) // ∆ -#define SE_INTG S(A(SE_F)) // ∫ -#define SE_MACR S(A(SE_G)) // ¯ -#define SE_BREV S(A(SE_H)) // ˘ -#define SE_NOT S(A(SE_J)) // ¬ -#define SE_MORD S(A(SE_K)) // º -#define SE_FL S(A(SE_L)) // fl -#define SE_FRSL S(A(SE_Z)) // ⁄ -#define SE_CARN S(A(SE_X)) // ˇ -#define SE_LDAQ S(A(SE_V)) // « -#define SE_RDAQ S(A(SE_B)) // » -#define SE_LDQU S(A(SE_N)) // “ -#define SE_RDQU S(A(SE_M)) // ” -#define SE_DLQU S(A(SE_COMM)) // „ -#define SE_MDDT S(A(SE_DOT)) // · -#define SE_MDSH S(A(SE_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_swedish_mac_iso.h b/quantum/keymap_extras/keymap_swedish_mac_iso.h deleted file mode 100644 index 2eaef5e60ca5..000000000000 --- a/quantum/keymap_extras/keymap_swedish_mac_iso.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SE_SECT KC_GRV // § -#define SE_1 KC_1 // 1 -#define SE_2 KC_2 // 2 -#define SE_3 KC_3 // 3 -#define SE_4 KC_4 // 4 -#define SE_5 KC_5 // 5 -#define SE_6 KC_6 // 6 -#define SE_7 KC_7 // 7 -#define SE_8 KC_8 // 8 -#define SE_9 KC_9 // 9 -#define SE_0 KC_0 // 0 -#define SE_PLUS KC_MINS // + -#define SE_ACUT KC_EQL // ´ (dead) -#define SE_Q KC_Q // Q -#define SE_W KC_W // W -#define SE_E KC_E // E -#define SE_R KC_R // R -#define SE_T KC_T // T -#define SE_Y KC_Y // Y -#define SE_U KC_U // U -#define SE_I KC_I // I -#define SE_O KC_O // O -#define SE_P KC_P // P -#define SE_ARNG KC_LBRC // Å -#define SE_DIAE KC_RBRC // ¨ (dead) -#define SE_A KC_A // A -#define SE_S KC_S // S -#define SE_D KC_D // D -#define SE_F KC_F // F -#define SE_G KC_G // G -#define SE_H KC_H // H -#define SE_J KC_J // J -#define SE_K KC_K // K -#define SE_L KC_L // L -#define SE_ODIA KC_SCLN // Ö -#define SE_ADIA KC_QUOT // Ä -#define SE_QUOT KC_NUHS // ' -#define SE_LABK KC_NUBS // < -#define SE_Z KC_Z // Z -#define SE_X KC_X // X -#define SE_C KC_C // C -#define SE_V KC_V // V -#define SE_B KC_B // B -#define SE_N KC_N // N -#define SE_M KC_M // M -#define SE_COMM KC_COMM // , -#define SE_DOT KC_DOT // . -#define SE_MINS KC_SLSH // - -#define SE_DEG S(SE_SECT) // ° -#define SE_EXLM S(SE_1) // ! -#define SE_DQUO S(SE_2) // " -#define SE_HASH S(SE_3) // # -#define SE_EURO S(SE_4) // € -#define SE_PERC S(SE_5) // % -#define SE_AMPR S(SE_6) // & -#define SE_SLSH S(SE_7) // / -#define SE_LPRN S(SE_8) // ( -#define SE_RPRN S(SE_9) // ) -#define SE_EQL S(SE_0) // = -#define SE_QUES S(SE_PLUS) // ? -#define SE_GRV S(SE_ACUT) // ` -#define SE_CIRC S(SE_DIAE) // ^ (dead) -#define SE_ASTR S(SE_QUOT) // * -#define SE_RABK S(SE_LABK) // > -#define SE_SCLN S(SE_COMM) // ; -#define SE_COLN S(SE_DOT) // : -#define SE_UNDS S(SE_MINS) // _ -#define SE_PILC A(SE_SECT) // ¶ -#define SE_COPY A(SE_1) // © -#define SE_TM A(SE_2) // ™ -#define SE_PND A(SE_3) // £ -#define SE_DLR A(SE_4) // $ -#define SE_INFN A(SE_5) // ∞ -#define SE_PIPE A(SE_7) // | -#define SE_LBRC A(SE_8) // [ -#define SE_RBRC A(SE_9) // ] -#define SE_AEQL A(SE_0) // ≈ -#define SE_PLMN A(SE_PLUS) // ± -#define SE_BULT A(SE_Q) // • -#define SE_OMEG A(SE_W) // Ω -#define SE_EACU A(SE_E) // É -#define SE_REGD A(SE_R) // ® -#define SE_DAGG A(SE_T) // † -#define SE_MICR A(SE_Y) // µ -#define SE_UDIA A(SE_U) // Ü -#define SE_DLSI A(SE_I) // ı -#define SE_OE A(SE_O) // Œ -#define SE_PI A(SE_P) // π -#define SE_DOTA A(SE_ARNG) // ˙ -#define SE_TILD A(SE_DIAE) // ~ (dead) -#define SE_APPL A(SE_A) //  (Apple logo) -#define SE_SS A(SE_S) // ß -#define SE_PDIF A(SE_D) // ∂ -#define SE_FHK A(SE_F) // ƒ -#define SE_CEDL A(SE_G) // ¸ -#define SE_OGON A(SE_H) // ˛ -#define SE_SQRT A(SE_J) // √ -#define SE_FORD A(SE_K) // ª -#define SE_FI A(SE_L) // fi -#define SE_OSTR A(SE_ODIA) // Ø -#define SE_AE A(SE_ADIA) // Æ -#define SE_AT A(SE_QUOT) // @ -#define SE_LTEQ A(SE_LABK) // ≤ -#define SE_DIV A(SE_Z) // ÷ -#define SE_CCED A(SE_C) // Ç -#define SE_LSAQ A(SE_V) // ‹ -#define SE_RSAQ A(SE_B) // › -#define SE_LSQU A(SE_N) // ‘ -#define SE_RSQU A(SE_M) // ’ -#define SE_SLQU A(SE_COMM) // ‚ -#define SE_ELLP A(SE_DOT) // … -#define SE_NDSH A(SE_MINS) // – -#define SE_IEXL S(A(SE_1)) // ¡ -#define SE_YEN S(A(SE_3)) // ¥ -#define SE_CENT S(A(SE_4)) // ¢ -#define SE_PERM S(A(SE_5)) // ‰ -#define SE_BSLS S(A(SE_7)) // (backslash) -#define SE_LCBR S(A(SE_8)) // { -#define SE_RCBR S(A(SE_9)) // } -#define SE_NEQL S(A(SE_0)) // ≠ -#define SE_IQUE S(A(SE_PLUS)) // ¿ -#define SE_DACU S(A(SE_W)) // ˝ -#define SE_DDAG S(A(SE_T)) // ‡ -#define SE_STIL S(A(SE_Y)) // ˜ -#define SE_DCIR S(A(SE_I)) // ˆ -#define SE_NARP S(A(SE_P)) // ∏ -#define SE_RNGA S(A(SE_ARNG)) // ˚ -#define SE_LOZN S(A(SE_A)) // ◊ -#define SE_NARS S(A(SE_S)) // ∑ -#define SE_INCR S(A(SE_D)) // ∆ -#define SE_INTG S(A(SE_F)) // ∫ -#define SE_MACR S(A(SE_G)) // ¯ -#define SE_BREV S(A(SE_H)) // ˘ -#define SE_NOT S(A(SE_J)) // ¬ -#define SE_MORD S(A(SE_K)) // º -#define SE_FL S(A(SE_L)) // fl -#define SE_GTEQ S(A(SE_LABK)) // ≥ -#define SE_FRSL S(A(SE_Z)) // ⁄ -#define SE_CARN S(A(SE_X)) // ˇ -#define SE_LDAQ S(A(SE_V)) // « -#define SE_RDAQ S(A(SE_B)) // » -#define SE_LDQU S(A(SE_N)) // “ -#define SE_RDQU S(A(SE_M)) // ” -#define SE_DLQU S(A(SE_COMM)) // „ -#define SE_MDDT S(A(SE_DOT)) // · -#define SE_MDSH S(A(SE_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_swedish_pro_mac_ansi.h b/quantum/keymap_extras/keymap_swedish_pro_mac_ansi.h deleted file mode 100644 index d33a25902354..000000000000 --- a/quantum/keymap_extras/keymap_swedish_pro_mac_ansi.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SE_LABK KC_GRV // < -#define SE_1 KC_1 // 1 -#define SE_2 KC_2 // 2 -#define SE_3 KC_3 // 3 -#define SE_4 KC_4 // 4 -#define SE_5 KC_5 // 5 -#define SE_6 KC_6 // 6 -#define SE_7 KC_7 // 7 -#define SE_8 KC_8 // 8 -#define SE_9 KC_9 // 9 -#define SE_0 KC_0 // 0 -#define SE_PLUS KC_MINS // + -#define SE_ACUT KC_EQL // ´ (dead) -#define SE_Q KC_Q // Q -#define SE_W KC_W // W -#define SE_E KC_E // E -#define SE_R KC_R // R -#define SE_T KC_T // T -#define SE_Y KC_Y // Y -#define SE_U KC_U // U -#define SE_I KC_I // I -#define SE_O KC_O // O -#define SE_P KC_P // P -#define SE_ARNG KC_LBRC // Å -#define SE_DIAE KC_RBRC // ¨ (dead) -#define SE_QUOT KC_NUHS // ' -#define SE_A KC_A // A -#define SE_S KC_S // S -#define SE_D KC_D // D -#define SE_F KC_F // F -#define SE_G KC_G // G -#define SE_H KC_H // H -#define SE_J KC_J // J -#define SE_K KC_K // K -#define SE_L KC_L // L -#define SE_ODIA KC_SCLN // Ö -#define SE_ADIA KC_QUOT // Ä -#define SE_Z KC_Z // Z -#define SE_X KC_X // X -#define SE_C KC_C // C -#define SE_V KC_V // V -#define SE_B KC_B // B -#define SE_N KC_N // N -#define SE_M KC_M // M -#define SE_COMM KC_COMM // , -#define SE_DOT KC_DOT // . -#define SE_MINS KC_SLSH // - -#define SE_RABK S(SE_LABK) // > -#define SE_EXLM S(SE_1) // ! -#define SE_DQUO S(SE_2) // " -#define SE_HASH S(SE_3) // # -#define SE_EURO S(SE_4) // € -#define SE_PERC S(SE_5) // % -#define SE_AMPR S(SE_6) // & -#define SE_SLSH S(SE_7) // / -#define SE_LPRN S(SE_8) // ( -#define SE_RPRN S(SE_9) // ) -#define SE_EQL S(SE_0) // = -#define SE_QUES S(SE_PLUS) // ? -#define SE_GRV S(SE_ACUT) // ` -#define SE_CIRC S(SE_DIAE) // ^ (dead) -#define SE_ASTR S(SE_QUOT) // * -#define SE_SCLN S(SE_COMM) // ; -#define SE_COLN S(SE_DOT) // : -#define SE_UNDS S(SE_MINS) // _ -#define SE_LTEQ A(SE_LABK) // ≤ -#define SE_COPY A(SE_1) // © -#define SE_AT A(SE_2) // @ -#define SE_PND A(SE_3) // £ -#define SE_DLR A(SE_4) // $ -#define SE_INFN A(SE_5) // ∞ -#define SE_SECT A(SE_6) // § -#define SE_PIPE A(SE_7) // | -#define SE_LBRC A(SE_8) // [ -#define SE_RBRC A(SE_9) // ] -#define SE_AEQL A(SE_0) // ≈ -#define SE_PLMN A(SE_PLUS) // ± -#define SE_BULT A(SE_Q) // • -#define SE_OMEG A(SE_W) // Ω -#define SE_EACU A(SE_E) // É -#define SE_REGD A(SE_R) // ® -#define SE_DAGG A(SE_T) // † -#define SE_MICR A(SE_Y) // µ -#define SE_UDIA A(SE_U) // Ü -#define SE_DLSI A(SE_I) // ı -#define SE_OE A(SE_O) // Œ -#define SE_PI A(SE_P) // π -#define SE_DOTA A(SE_ARNG) // ˙ -#define SE_TILD A(SE_DIAE) // ~ (dead) -#define SE_TM A(SE_QUOT) // ™ -#define SE_APPL A(SE_A) //  (Apple logo) -#define SE_SS A(SE_S) // ß -#define SE_PDIF A(SE_D) // ∂ -#define SE_FHK A(SE_F) // ƒ -#define SE_CEDL A(SE_G) // ¸ -#define SE_OGON A(SE_H) // ˛ -#define SE_SQRT A(SE_J) // √ -#define SE_FORD A(SE_K) // ª -#define SE_FI A(SE_L) // fi -#define SE_OSTR A(SE_ODIA) // Ø -#define SE_AE A(SE_ADIA) // Æ -#define SE_DIV A(SE_Z) // ÷ -#define SE_CCED A(SE_C) // Ç -#define SE_LSAQ A(SE_V) // ‹ -#define SE_RSAQ A(SE_B) // › -#define SE_LSQU A(SE_N) // ‘ -#define SE_RSQU A(SE_M) // ’ -#define SE_SLQU A(SE_COMM) // ‚ -#define SE_ELLP A(SE_DOT) // … -#define SE_NDSH A(SE_MINS) // – -#define SE_GTEQ S(A(SE_LABK)) // ≥ -#define SE_IEXL S(A(SE_1)) // ¡ -#define SE_YEN S(A(SE_3)) // ¥ -#define SE_CENT S(A(SE_4)) // ¢ -#define SE_PERM S(A(SE_5)) // ‰ -#define SE_PILC S(A(SE_6)) // ¶ -#define SE_BSLS S(A(SE_7)) // (backslash) -#define SE_LCBR S(A(SE_8)) // { -#define SE_RCBR S(A(SE_9)) // } -#define SE_NEQL S(A(SE_0)) // ≠ -#define SE_IQUE S(A(SE_PLUS)) // ¿ -#define SE_DEG S(A(SE_Q)) // ° -#define SE_DACU S(A(SE_W)) // ˝ -#define SE_DDAG S(A(SE_T)) // ‡ -#define SE_STIL S(A(SE_Y)) // ˜ -#define SE_DCIR S(A(SE_I)) // ˆ -#define SE_NARP S(A(SE_P)) // ∏ -#define SE_RNGA S(A(SE_ARNG)) // ˚ -#define SE_LOZN S(A(SE_A)) // ◊ -#define SE_NARS S(A(SE_S)) // ∑ -#define SE_INCR S(A(SE_D)) // ∆ -#define SE_INTG S(A(SE_F)) // ∫ -#define SE_MACR S(A(SE_G)) // ¯ -#define SE_BREV S(A(SE_H)) // ˘ -#define SE_NOT S(A(SE_J)) // ¬ -#define SE_MORD S(A(SE_K)) // º -#define SE_FL S(A(SE_L)) // fl -#define SE_FRSL S(A(SE_Z)) // ⁄ -#define SE_CARN S(A(SE_X)) // ˇ -#define SE_LDAQ S(A(SE_V)) // « -#define SE_RDAQ S(A(SE_B)) // » -#define SE_LDQU S(A(SE_N)) // “ -#define SE_RDQU S(A(SE_M)) // ” -#define SE_DLQU S(A(SE_COMM)) // „ -#define SE_MDDT S(A(SE_DOT)) // · -#define SE_MDSH S(A(SE_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_swedish_pro_mac_iso.h b/quantum/keymap_extras/keymap_swedish_pro_mac_iso.h deleted file mode 100644 index 680bd1db9e26..000000000000 --- a/quantum/keymap_extras/keymap_swedish_pro_mac_iso.h +++ /dev/null @@ -1,177 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define SE_SECT KC_GRV // § -#define SE_1 KC_1 // 1 -#define SE_2 KC_2 // 2 -#define SE_3 KC_3 // 3 -#define SE_4 KC_4 // 4 -#define SE_5 KC_5 // 5 -#define SE_6 KC_6 // 6 -#define SE_7 KC_7 // 7 -#define SE_8 KC_8 // 8 -#define SE_9 KC_9 // 9 -#define SE_0 KC_0 // 0 -#define SE_PLUS KC_MINS // + -#define SE_ACUT KC_EQL // ´ (dead) -#define SE_Q KC_Q // Q -#define SE_W KC_W // W -#define SE_E KC_E // E -#define SE_R KC_R // R -#define SE_T KC_T // T -#define SE_Y KC_Y // Y -#define SE_U KC_U // U -#define SE_I KC_I // I -#define SE_O KC_O // O -#define SE_P KC_P // P -#define SE_ARNG KC_LBRC // Å -#define SE_DIAE KC_RBRC // ¨ (dead) -#define SE_A KC_A // A -#define SE_S KC_S // S -#define SE_D KC_D // D -#define SE_F KC_F // F -#define SE_G KC_G // G -#define SE_H KC_H // H -#define SE_J KC_J // J -#define SE_K KC_K // K -#define SE_L KC_L // L -#define SE_ODIA KC_SCLN // Ö -#define SE_ADIA KC_QUOT // Ä -#define SE_QUOT KC_NUHS // ' -#define SE_LABK KC_NUBS // < -#define SE_Z KC_Z // Z -#define SE_X KC_X // X -#define SE_C KC_C // C -#define SE_V KC_V // V -#define SE_B KC_B // B -#define SE_N KC_N // N -#define SE_M KC_M // M -#define SE_COMM KC_COMM // , -#define SE_DOT KC_DOT // . -#define SE_MINS KC_SLSH // - -#define SE_DEG S(SE_SECT) // ° -#define SE_EXLM S(SE_1) // ! -#define SE_DQUO S(SE_2) // " -#define SE_HASH S(SE_3) // # -#define SE_EURO S(SE_4) // € -#define SE_PERC S(SE_5) // % -#define SE_AMPR S(SE_6) // & -#define SE_SLSH S(SE_7) // / -#define SE_LPRN S(SE_8) // ( -#define SE_RPRN S(SE_9) // ) -#define SE_EQL S(SE_0) // = -#define SE_QUES S(SE_PLUS) // ? -#define SE_GRV S(SE_ACUT) // ` -#define SE_CIRC S(SE_DIAE) // ^ (dead) -#define SE_ASTR S(SE_QUOT) // * -#define SE_RABK S(SE_LABK) // > -#define SE_SCLN S(SE_COMM) // ; -#define SE_COLN S(SE_DOT) // : -#define SE_UNDS S(SE_MINS) // _ -#define SE_PILC A(SE_SECT) // ¶ -#define SE_COPY A(SE_1) // © -#define SE_AT A(SE_2) // @ -#define SE_PND A(SE_3) // £ -#define SE_DLR A(SE_4) // $ -#define SE_INFN A(SE_5) // ∞ -#define SE_PIPE A(SE_7) // | -#define SE_LBRC A(SE_8) // [ -#define SE_RBRC A(SE_9) // ] -#define SE_AEQL A(SE_0) // ≈ -#define SE_PLMN A(SE_PLUS) // ± -#define SE_BULT A(SE_Q) // • -#define SE_OMEG A(SE_W) // Ω -#define SE_EACU A(SE_E) // É -#define SE_REGD A(SE_R) // ® -#define SE_DAGG A(SE_T) // † -#define SE_MICR A(SE_Y) // µ -#define SE_UDIA A(SE_U) // Ü -#define SE_DLSI A(SE_I) // ı -#define SE_OE A(SE_O) // Œ -#define SE_PI A(SE_P) // π -#define SE_DOTA A(SE_ARNG) // ˙ -#define SE_TILD A(SE_DIAE) // ~ (dead) -#define SE_APPL A(SE_A) //  (Apple logo) -#define SE_SS A(SE_S) // ß -#define SE_PDIF A(SE_D) // ∂ -#define SE_FHK A(SE_F) // ƒ -#define SE_CEDL A(SE_G) // ¸ -#define SE_OGON A(SE_H) // ˛ -#define SE_SQRT A(SE_J) // √ -#define SE_FORD A(SE_K) // ª -#define SE_FI A(SE_L) // fi -#define SE_OSTR A(SE_ODIA) // Ø -#define SE_AE A(SE_ADIA) // Æ -#define SE_TM A(SE_QUOT) // ™ -#define SE_LTEQ A(SE_LABK) // ≤ -#define SE_DIV A(SE_Z) // ÷ -#define SE_CCED A(SE_C) // Ç -#define SE_LSAQ A(SE_V) // ‹ -#define SE_RSAQ A(SE_B) // › -#define SE_LSQU A(SE_N) // ‘ -#define SE_RSQU A(SE_M) // ’ -#define SE_SLQU A(SE_COMM) // ‚ -#define SE_ELLP A(SE_DOT) // … -#define SE_NDSH A(SE_MINS) // – -#define SE_IEXL S(A(SE_1)) // ¡ -#define SE_YEN S(A(SE_3)) // ¥ -#define SE_CENT S(A(SE_4)) // ¢ -#define SE_PERM S(A(SE_5)) // ‰ -#define SE_BSLS S(A(SE_7)) // (backslash) -#define SE_LCBR S(A(SE_8)) // { -#define SE_RCBR S(A(SE_9)) // } -#define SE_NEQL S(A(SE_0)) // ≠ -#define SE_IQUE S(A(SE_PLUS)) // ¿ -#define SE_DACU S(A(SE_W)) // ˝ -#define SE_DDAG S(A(SE_T)) // ‡ -#define SE_STIL S(A(SE_Y)) // ˜ -#define SE_DCIR S(A(SE_I)) // ˆ -#define SE_NARP S(A(SE_P)) // ∏ -#define SE_RNGA S(A(SE_ARNG)) // ˚ -#define SE_LOZN S(A(SE_A)) // ◊ -#define SE_NARS S(A(SE_S)) // ∑ -#define SE_INCR S(A(SE_D)) // ∆ -#define SE_INTG S(A(SE_F)) // ∫ -#define SE_MACR S(A(SE_G)) // ¯ -#define SE_BREV S(A(SE_H)) // ˘ -#define SE_NOT S(A(SE_J)) // ¬ -#define SE_MORD S(A(SE_K)) // º -#define SE_FL S(A(SE_L)) // fl -#define SE_GTEQ S(A(SE_LABK)) // ≥ -#define SE_FRSL S(A(SE_Z)) // ⁄ -#define SE_CARN S(A(SE_X)) // ˇ -#define SE_LDAQ S(A(SE_V)) // « -#define SE_RDAQ S(A(SE_B)) // » -#define SE_LDQU S(A(SE_N)) // “ -#define SE_RDQU S(A(SE_M)) // ” -#define SE_DLQU S(A(SE_COMM)) // „ -#define SE_MDDT S(A(SE_DOT)) // · -#define SE_MDSH S(A(SE_MINS)) // — - diff --git a/quantum/keymap_extras/keymap_swiss_de.h b/quantum/keymap_extras/keymap_swiss_de.h deleted file mode 100644 index 69bba7293e67..000000000000 --- a/quantum/keymap_extras/keymap_swiss_de.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define CH_SECT KC_GRV // § -#define CH_1 KC_1 // 1 -#define CH_2 KC_2 // 2 -#define CH_3 KC_3 // 3 -#define CH_4 KC_4 // 4 -#define CH_5 KC_5 // 5 -#define CH_6 KC_6 // 6 -#define CH_7 KC_7 // 7 -#define CH_8 KC_8 // 8 -#define CH_9 KC_9 // 9 -#define CH_0 KC_0 // 0 -#define CH_QUOT KC_MINS // ' -#define CH_CIRC KC_EQL // ^ (dead) -#define CH_Q KC_Q // Q -#define CH_W KC_W // W -#define CH_E KC_E // E -#define CH_R KC_R // R -#define CH_T KC_T // T -#define CH_Z KC_Y // Z -#define CH_U KC_U // U -#define CH_I KC_I // I -#define CH_O KC_O // O -#define CH_P KC_P // P -#define CH_UDIA KC_LBRC // ü -#define CH_DIAE KC_RBRC // ¨ (dead) -#define CH_A KC_A // A -#define CH_S KC_S // S -#define CH_D KC_D // D -#define CH_F KC_F // F -#define CH_G KC_G // G -#define CH_H KC_H // H -#define CH_J KC_J // J -#define CH_K KC_K // K -#define CH_L KC_L // L -#define CH_ODIA KC_SCLN // ö -#define CH_ADIA KC_QUOT // ä -#define CH_DLR KC_NUHS // $ -#define CH_LABK KC_NUBS // < -#define CH_Y KC_Z // Y -#define CH_X KC_X // X -#define CH_C KC_C // C -#define CH_V KC_V // V -#define CH_B KC_B // B -#define CH_N KC_N // N -#define CH_M KC_M // M -#define CH_COMM KC_COMM // , -#define CH_DOT KC_DOT // . -#define CH_MINS KC_SLSH // - -#define CH_DEG S(CH_SECT) // ° -#define CH_PLUS S(CH_1) // + -#define CH_DQUO S(CH_2) // " -#define CH_ASTR S(CH_3) // * -#define CH_CCED S(CH_4) // ç -#define CH_PERC S(CH_5) // % -#define CH_AMPR S(CH_6) // & -#define CH_SLSH S(CH_7) // / -#define CH_LPRN S(CH_8) // ( -#define CH_RPRN S(CH_9) // ) -#define CH_EQL S(CH_0) // = -#define CH_QUES S(CH_QUOT) // ? -#define CH_GRV S(CH_CIRC) // ` (dead) -#define CH_EGRV S(CH_UDIA) // è -#define CH_EXLM S(CH_DIAE) // ! -#define CH_EACU S(CH_ODIA) // é -#define CH_AGRV S(CH_ADIA) // à -#define CH_PND S(CH_DLR) // £ -#define CH_RABK S(CH_LABK) // > -#define CH_SCLN S(CH_COMM) // ; -#define CH_COLN S(CH_DOT) // : -#define CH_UNDS S(CH_MINS) // _ -#define CH_BRKP ALGR(CH_1) // ¦ -#define CH_AT ALGR(CH_2) // @ -#define CH_HASH ALGR(CH_3) // # -#define CH_NOT ALGR(CH_6) // ¬ -#define CH_PIPE ALGR(CH_7) // | -#define CH_CENT ALGR(CH_8) // ¢ -#define CH_ACUT ALGR(CH_QUOT) // ´ (dead) -#define CH_TILD ALGR(CH_CIRC) // ~ (dead) -#define CH_EURO ALGR(CH_E) // € -#define CH_LBRC ALGR(CH_UDIA) // [ -#define CH_RBRC ALGR(CH_DIAE) // ] -#define CH_LCBR ALGR(CH_ADIA) // { -#define CH_RCBR ALGR(CH_DLR) // } -#define CH_BSLS ALGR(CH_LABK) // (backslash) - diff --git a/quantum/keymap_extras/keymap_swiss_fr.h b/quantum/keymap_extras/keymap_swiss_fr.h deleted file mode 100644 index 1e2f833db16f..000000000000 --- a/quantum/keymap_extras/keymap_swiss_fr.h +++ /dev/null @@ -1,115 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define CH_SECT KC_GRV // § -#define CH_1 KC_1 // 1 -#define CH_2 KC_2 // 2 -#define CH_3 KC_3 // 3 -#define CH_4 KC_4 // 4 -#define CH_5 KC_5 // 5 -#define CH_6 KC_6 // 6 -#define CH_7 KC_7 // 7 -#define CH_8 KC_8 // 8 -#define CH_9 KC_9 // 9 -#define CH_0 KC_0 // 0 -#define CH_QUOT KC_MINS // ' -#define CH_CIRC KC_EQL // ^ (dead) -#define CH_Q KC_Q // Q -#define CH_W KC_W // W -#define CH_E KC_E // E -#define CH_R KC_R // R -#define CH_T KC_T // T -#define CH_Z KC_Y // Z -#define CH_U KC_U // U -#define CH_I KC_I // I -#define CH_O KC_O // O -#define CH_P KC_P // P -#define CH_EGRV KC_LBRC // è -#define CH_DIAE KC_RBRC // ¨ (dead) -#define CH_A KC_A // A -#define CH_S KC_S // S -#define CH_D KC_D // D -#define CH_F KC_F // F -#define CH_G KC_G // G -#define CH_H KC_H // H -#define CH_J KC_J // J -#define CH_K KC_K // K -#define CH_L KC_L // L -#define CH_EACU KC_SCLN // é -#define CH_AGRV KC_QUOT // à -#define CH_DLR KC_NUHS // $ -#define CH_LABK KC_NUBS // < -#define CH_Y KC_Z // Y -#define CH_X KC_X // X -#define CH_C KC_C // C -#define CH_V KC_V // V -#define CH_B KC_B // B -#define CH_N KC_N // N -#define CH_M KC_M // M -#define CH_COMM KC_COMM // , -#define CH_DOT KC_DOT // . -#define CH_MINS KC_SLSH // - -#define CH_DEG S(CH_SECT) // ° -#define CH_PLUS S(CH_1) // + -#define CH_DQUO S(CH_2) // " -#define CH_ASTR S(CH_3) // * -#define CH_CCED S(CH_4) // ç -#define CH_PERC S(CH_5) // % -#define CH_AMPR S(CH_6) // & -#define CH_SLSH S(CH_7) // / -#define CH_LPRN S(CH_8) // ( -#define CH_RPRN S(CH_9) // ) -#define CH_EQL S(CH_0) // = -#define CH_QUES S(CH_QUOT) // ? -#define CH_GRV S(CH_CIRC) // ` (dead) -#define CH_UDIA S(CH_EGRV) // ü -#define CH_EXLM S(CH_DIAE) // ! -#define CH_ODIA S(CH_EACU) // ö -#define CH_ADIA S(CH_AGRV) // ä -#define CH_PND S(CH_DLR) // £ -#define CH_RABK S(CH_LABK) // > -#define CH_SCLN S(CH_COMM) // ; -#define CH_COLN S(CH_DOT) // : -#define CH_UNDS S(CH_MINS) // _ -#define CH_BRKP ALGR(CH_1) // ¦ -#define CH_AT ALGR(CH_2) // @ -#define CH_HASH ALGR(CH_3) // # -#define CH_NOT ALGR(CH_6) // ¬ -#define CH_PIPE ALGR(CH_7) // | -#define CH_CENT ALGR(CH_8) // ¢ -#define CH_ACUT ALGR(CH_QUOT) // ´ (dead) -#define CH_TILD ALGR(CH_CIRC) // ~ (dead) -#define CH_EURO ALGR(CH_E) // € -#define CH_LBRC ALGR(CH_EGRV) // [ -#define CH_RBRC ALGR(CH_DIAE) // ] -#define CH_LCBR ALGR(CH_AGRV) // { -#define CH_RCBR ALGR(CH_DLR) // } -#define CH_BSLS ALGR(CH_LABK) // (backslash) - diff --git a/quantum/keymap_extras/keymap_turkish_f.h b/quantum/keymap_extras/keymap_turkish_f.h deleted file mode 100644 index 4fdcf3f7462c..000000000000 --- a/quantum/keymap_extras/keymap_turkish_f.h +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define TR_PLUS KC_GRV // + -#define TR_1 KC_1 // 1 -#define TR_2 KC_2 // 2 -#define TR_3 KC_3 // 3 -#define TR_4 KC_4 // 4 -#define TR_5 KC_5 // 5 -#define TR_6 KC_6 // 6 -#define TR_7 KC_7 // 7 -#define TR_8 KC_8 // 8 -#define TR_9 KC_9 // 9 -#define TR_0 KC_0 // 0 -#define TR_SLSH KC_MINS // / -#define TR_MINS KC_EQL // - -#define TR_F KC_Q // F -#define TR_G KC_W // G -#define TR_GBRV KC_E // Ğ -#define TR_I KC_R // I -#define TR_O KC_T // O -#define TR_D KC_Y // D -#define TR_R KC_U // R -#define TR_N KC_I // N -#define TR_H KC_O // H -#define TR_P KC_P // P -#define TR_Q KC_LBRC // Q -#define TR_W KC_RBRC // W -#define TR_U KC_A // U -#define TR_IDOT KC_S // İ -#define TR_E KC_D // E -#define TR_A KC_F // A -#define TR_UDIA KC_G // Ü -#define TR_T KC_H // T -#define TR_K KC_J // K -#define TR_M KC_K // M -#define TR_L KC_L // L -#define TR_Y KC_SCLN // Y -#define TR_SCED KC_QUOT // Ş -#define TR_X KC_NUHS // X -#define TR_LABK KC_NUBS // < -#define TR_J KC_Z // J -#define TR_ODIA KC_X // Ö -#define TR_V KC_C // V -#define TR_C KC_V // C -#define TR_CCED KC_B // Ç -#define TR_Z KC_N // Z -#define TR_S KC_M // S -#define TR_B KC_COMM // B -#define TR_DOT KC_DOT // . -#define TR_COMM KC_SLSH // , -#define TR_ASTR S(TR_PLUS) // * -#define TR_EXLM S(TR_1) // ! -#define TR_DQUO S(TR_2) // " -#define TR_CIRC S(TR_3) // ^ (dead) -#define TR_DLR S(TR_4) // $ -#define TR_PERC S(TR_5) // % -#define TR_AMPR S(TR_6) // & -#define TR_QUOT S(TR_7) // ' -#define TR_LPRN S(TR_8) // ( -#define TR_RPRN S(TR_9) // ) -#define TR_EQL S(TR_0) // = -#define TR_QUES S(TR_SLSH) // ? -#define TR_UNDS S(TR_MINS) // _ -#define TR_RABK S(TR_LABK) // > -#define TR_COLN S(TR_DOT) // : -#define TR_SCLN S(TR_COMM) // ; -#define TR_NOT ALGR(TR_PLUS) // ¬ -#define TR_SUP1 ALGR(TR_1) // ¹ -#define TR_SUP2 ALGR(TR_2) // ² -#define TR_HASH ALGR(TR_3) // # -#define TR_QRTR ALGR(TR_4) // ¼ -#define TR_HALF ALGR(TR_5) // ½ -#define TR_TQTR ALGR(TR_6) // ¾ -#define TR_LCBR ALGR(TR_7) // { -#define TR_LBRC ALGR(TR_8) // [ -#define TR_RBRC ALGR(TR_9) // ] -#define TR_RCBR ALGR(TR_0) // } -#define TR_BSLS ALGR(TR_SLSH) // (backslash) -#define TR_PIPE ALGR(TR_MINS) // | -#define TR_AT ALGR(TR_F) // @ -#define TR_PILC ALGR(TR_I) // ¶ -#define TR_YEN ALGR(TR_D) // ¥ -#define TR_OSTR ALGR(TR_H) // Ø -#define TR_PND ALGR(TR_P) // £ -#define TR_DIAE ALGR(TR_Q) // ¨ (dead) -#define TR_TILD ALGR(TR_W) // ~ (dead) -#define TR_AE ALGR(TR_U) // Æ -#define TR_SS ALGR(TR_IDOT) // ß -#define TR_EURO ALGR(TR_E) // € -#define TR_LIRA ALGR(TR_T) // ₺ -#define TR_ACUT ALGR(TR_Y) // ´ (dead) -#define TR_GRV ALGR(TR_X) // ` (dead) -#define TR_LDAQ ALGR(TR_J) // « -#define TR_RDAQ ALGR(TR_ODIA) // » -#define TR_CENT ALGR(TR_V) // ¢ -#define TR_MICR ALGR(TR_S) // µ -#define TR_MUL ALGR(TR_B) // × -#define TR_DIV ALGR(TR_DOT) // ÷ -#define TR_SHYP ALGR(TR_COMM) // ­ (soft hyphen) -#define TR_SUP3 S(ALGR(TR_3)) // ³ -#define TR_CURR S(ALGR(TR_4)) // ¤ -#define TR_IQUE S(ALGR(TR_SLSH)) // ¿ -#define TR_REGD S(ALGR(TR_I)) // ® -#define TR_SECT S(ALGR(TR_IDOT)) // § -#define TR_FORD S(ALGR(TR_A)) // ª -#define TR_BRKP S(ALGR(TR_LABK)) // ¦ -#define TR_COPY S(ALGR(TR_V)) // © -#define TR_MORD S(ALGR(TR_S)) // º - diff --git a/quantum/keymap_extras/keymap_turkish_q.h b/quantum/keymap_extras/keymap_turkish_q.h deleted file mode 100644 index 5a9362acb4c8..000000000000 --- a/quantum/keymap_extras/keymap_turkish_q.h +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define TR_DQUO KC_GRV // " -#define TR_1 KC_1 // 1 -#define TR_2 KC_2 // 2 -#define TR_3 KC_3 // 3 -#define TR_4 KC_4 // 4 -#define TR_5 KC_5 // 5 -#define TR_6 KC_6 // 6 -#define TR_7 KC_7 // 7 -#define TR_8 KC_8 // 8 -#define TR_9 KC_9 // 9 -#define TR_0 KC_0 // 0 -#define TR_ASTR KC_MINS // * -#define TR_MINS KC_EQL // - -#define TR_Q KC_Q // Q -#define TR_W KC_W // W -#define TR_E KC_E // E -#define TR_R KC_R // R -#define TR_T KC_T // T -#define TR_Y KC_Y // Y -#define TR_U KC_U // U -#define TR_I KC_I // I -#define TR_O KC_O // O -#define TR_P KC_P // P -#define TR_GBRV KC_LBRC // Ğ -#define TR_UDIA KC_RBRC // Ü -#define TR_A KC_A // A -#define TR_S KC_S // S -#define TR_D KC_D // D -#define TR_F KC_F // F -#define TR_G KC_G // G -#define TR_H KC_H // H -#define TR_J KC_J // J -#define TR_K KC_K // K -#define TR_L KC_L // L -#define TR_SCED KC_SCLN // Ş -#define TR_IDOT KC_QUOT // İ -#define TR_COMM KC_NUHS // , -#define TR_LABK KC_NUBS // < -#define TR_Z KC_Z // Z -#define TR_X KC_X // X -#define TR_C KC_C // C -#define TR_V KC_V // V -#define TR_B KC_B // B -#define TR_N KC_N // N -#define TR_M KC_M // M -#define TR_ODIA KC_COMM // Ö -#define TR_CCED KC_DOT // Ç -#define TR_DOT KC_SLSH // . -#define TR_EACU S(TR_DQUO) // é -#define TR_EXLM S(TR_1) // ! -#define TR_QUOT S(TR_2) // ' -#define TR_CIRC S(TR_3) // ^ (dead) -#define TR_PLUS S(TR_4) // + -#define TR_PERC S(TR_5) // % -#define TR_AMPR S(TR_6) // & -#define TR_SLSH S(TR_7) // / -#define TR_LPRN S(TR_8) // ( -#define TR_RPRN S(TR_9) // ) -#define TR_EQL S(TR_0) // = -#define TR_QUES S(TR_ASTR) // ? -#define TR_UNDS S(TR_MINS) // _ -#define TR_SCLN S(TR_COMM) // ; -#define TR_RABK S(TR_LABK) // > -#define TR_COLN S(TR_DOT) // : -#define TR_PND ALGR(TR_2) // £ -#define TR_HASH ALGR(TR_3) // # -#define TR_DLR ALGR(TR_4) // $ -#define TR_HALF ALGR(TR_5) // ½ -#define TR_LCBR ALGR(TR_7) // { -#define TR_LBRC ALGR(TR_8) // [ -#define TR_RBRC ALGR(TR_9) // ] -#define TR_RCBR ALGR(TR_0) // } -#define TR_BSLS ALGR(TR_ASTR) // (backslash) -#define TR_PIPE ALGR(TR_MINS) // | -#define TR_AT ALGR(TR_Q) // @ -#define TR_EURO ALGR(TR_E) // € -#define TR_LIRA ALGR(TR_T) // ₺ -#define TR_DIAE ALGR(TR_GBRV) // ¨ (dead) -#define TR_TILD ALGR(TR_UDIA) // ~ (dead) -#define TR_AE ALGR(TR_A) // Æ -#define TR_SS ALGR(TR_S) // ß -#define TR_ACUT ALGR(TR_SCED) // ´ (dead) -#define TR_GRV ALGR(TR_COMM) // ` (dead) - diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h deleted file mode 100644 index 71e5f38f55a9..000000000000 --- a/quantum/keymap_extras/keymap_uk.h +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define UK_GRV KC_GRV // ` -#define UK_1 KC_1 // 1 -#define UK_2 KC_2 // 2 -#define UK_3 KC_3 // 3 -#define UK_4 KC_4 // 4 -#define UK_5 KC_5 // 5 -#define UK_6 KC_6 // 6 -#define UK_7 KC_7 // 7 -#define UK_8 KC_8 // 8 -#define UK_9 KC_9 // 9 -#define UK_0 KC_0 // 0 -#define UK_MINS KC_MINS // - -#define UK_EQL KC_EQL // = -#define UK_Q KC_Q // Q -#define UK_W KC_W // W -#define UK_E KC_E // E -#define UK_R KC_R // R -#define UK_T KC_T // T -#define UK_Y KC_Y // Y -#define UK_U KC_U // U -#define UK_I KC_I // I -#define UK_O KC_O // O -#define UK_P KC_P // P -#define UK_LBRC KC_LBRC // [ -#define UK_RBRC KC_RBRC // ] -#define UK_A KC_A // A -#define UK_S KC_S // S -#define UK_D KC_D // D -#define UK_F KC_F // F -#define UK_G KC_G // G -#define UK_H KC_H // H -#define UK_J KC_J // J -#define UK_K KC_K // K -#define UK_L KC_L // L -#define UK_SCLN KC_SCLN // ; -#define UK_QUOT KC_QUOT // ' -#define UK_HASH KC_NUHS // # -#define UK_BSLS KC_NUBS // (backslash) -#define UK_Z KC_Z // Z -#define UK_X KC_X // X -#define UK_C KC_C // C -#define UK_V KC_V // V -#define UK_B KC_B // B -#define UK_N KC_N // N -#define UK_M KC_M // M -#define UK_COMM KC_COMM // , -#define UK_DOT KC_DOT // . -#define UK_SLSH KC_SLSH // / -#define UK_NOT S(UK_GRV) // ¬ -#define UK_EXLM S(UK_1) // ! -#define UK_DQUO S(UK_2) // " -#define UK_PND S(UK_3) // £ -#define UK_DLR S(UK_4) // $ -#define UK_PERC S(UK_5) // % -#define UK_CIRC S(UK_6) // ^ -#define UK_AMPR S(UK_7) // & -#define UK_ASTR S(UK_8) // * -#define UK_LPRN S(UK_9) // ( -#define UK_RPRN S(UK_0) // ) -#define UK_UNDS S(UK_MINS) // _ -#define UK_PLUS S(UK_EQL) // + -#define UK_LCBR S(UK_LBRC) // { -#define UK_RCBR S(UK_RBRC) // } -#define UK_COLN S(UK_SCLN) // : -#define UK_AT S(UK_QUOT) // @ -#define UK_TILD S(UK_HASH) // ~ -#define UK_PIPE S(UK_BSLS) // | -#define UK_LABK S(UK_COMM) // < -#define UK_RABK S(UK_DOT) // > -#define UK_QUES S(UK_SLSH) // ? -#define UK_BRKP ALGR(UK_GRV) // ¦ -#define UK_EURO ALGR(UK_4) // € -#define UK_EACU ALGR(KC_E) // É -#define UK_UACU ALGR(KC_U) // Ú -#define UK_IACU ALGR(KC_I) // Í -#define UK_OACU ALGR(KC_O) // Ó -#define UK_AACU ALGR(KC_A) // Á - diff --git a/quantum/keymap_extras/keymap_ukrainian.h b/quantum/keymap_extras/keymap_ukrainian.h deleted file mode 100644 index 3f3ec4cec2b5..000000000000 --- a/quantum/keymap_extras/keymap_ukrainian.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define UA_QUOT KC_GRV // ' -#define UA_1 KC_1 // 1 -#define UA_2 KC_2 // 2 -#define UA_3 KC_3 // 3 -#define UA_4 KC_4 // 4 -#define UA_5 KC_5 // 5 -#define UA_6 KC_6 // 6 -#define UA_7 KC_7 // 7 -#define UA_8 KC_8 // 8 -#define UA_9 KC_9 // 9 -#define UA_0 KC_0 // 0 -#define UA_MINS KC_MINS // - -#define UA_EQL KC_EQL // = -#define UA_YOT KC_Q // Й -#define UA_TSE KC_W // Ц -#define UA_U KC_E // У -#define UA_KA KC_R // К -#define UA_E KC_T // Е -#define UA_EN KC_Y // Н -#define UA_HE KC_U // Г -#define UA_SHA KC_I // Ш -#define UA_SHCH KC_O // Щ -#define UA_ZE KC_P // З -#define UA_KHA KC_LBRC // Х -#define UA_YI KC_RBRC // Ї -#define UA_BSLS KC_BSLS // (backslash) -#define UA_EF KC_A // Ф -#define UA_I KC_S // І -#define UA_VE KC_D // В -#define UA_A KC_F // А -#define UA_PE KC_G // П -#define UA_ER KC_H // Р -#define UA_O KC_J // О -#define UA_EL KC_K // Л -#define UA_DE KC_L // Д -#define UA_ZHE KC_SCLN // Ж -#define UA_YE KC_QUOT // Є -#define UA_YA KC_Z // Я -#define UA_CHE KC_X // Ч -#define UA_ES KC_C // С -#define UA_EM KC_V // М -#define UA_Y KC_B // И -#define UA_TE KC_N // Т -#define UA_SOFT KC_M // Ь -#define UA_BE KC_COMM // Б -#define UA_YU KC_DOT // Ю -#define UA_DOT KC_SLSH // . -#define UA_HRYV S(UA_QUOT) // ₴ -#define UA_EXLM S(UA_1) // ! -#define UA_DQUO S(UA_2) // " -#define UA_NUM S(UA_3) // № -#define UA_SCLN S(UA_4) // ; -#define UA_PERC S(UA_5) // % -#define UA_COLN S(UA_6) // : -#define UA_QUES S(UA_7) // ? -#define UA_ASTR S(UA_8) // * -#define UA_LPRN S(UA_9) // ( -#define UA_RPRN S(UA_0) // ) -#define UA_UNDS S(UA_MINS) // _ -#define UA_PLUS S(UA_EQL) // + -#define UA_SLSH S(UA_BSLS) // / -#define UA_COMM S(UA_DOT) // , -#define UA_GE ALGR(UA_HE) // ґ - diff --git a/quantum/keymap_extras/keymap_us.h b/quantum/keymap_extras/keymap_us.h deleted file mode 100644 index 6101c8d8ba88..000000000000 --- a/quantum/keymap_extras/keymap_us.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define KC_TILD S(KC_GRAVE) // ~ -#define KC_EXLM S(KC_1) // ! -#define KC_AT S(KC_2) // @ -#define KC_HASH S(KC_3) // # -#define KC_DLR S(KC_4) // $ -#define KC_PERC S(KC_5) // % -#define KC_CIRC S(KC_6) // ^ -#define KC_AMPR S(KC_7) // & -#define KC_ASTR S(KC_8) // * -#define KC_LPRN S(KC_9) // ( -#define KC_RPRN S(KC_0) // ) -#define KC_UNDS S(KC_MINUS) // _ -#define KC_PLUS S(KC_EQUAL) // + -#define KC_LCBR S(KC_LEFT_BRACKET) // { -#define KC_RCBR S(KC_RIGHT_BRACKET) // } -#define KC_PIPE S(KC_BACKSLASH) // | -#define KC_COLN S(KC_SEMICOLON) // : -#define KC_DQUO S(KC_QUOTE) // " -#define KC_LABK S(KC_COMMA) // < -#define KC_RABK S(KC_DOT) // > -#define KC_QUES S(KC_SLASH) // ? - -#define KC_TILDE KC_TILD -#define KC_EXCLAIM KC_EXLM -#define KC_DOLLAR KC_DLR -#define KC_PERCENT KC_PERC -#define KC_CIRCUMFLEX KC_CIRC -#define KC_AMPERSAND KC_AMPR -#define KC_ASTERISK KC_ASTR -#define KC_LEFT_PAREN KC_LPRN -#define KC_RIGHT_PAREN KC_RPRN -#define KC_UNDERSCORE KC_UNDS -#define KC_LEFT_CURLY_BRACE KC_LCBR -#define KC_RIGHT_CURLY_BRACE KC_RCBR -#define KC_COLON KC_COLN -#define KC_DOUBLE_QUOTE KC_DQUO -#define KC_DQT KC_DQUO -#define KC_LEFT_ANGLE_BRACKET KC_LABK -#define KC_LT KC_LABK -#define KC_RIGHT_ANGLE_BRACKET KC_RABK -#define KC_GT KC_RABK -#define KC_QUESTION KC_QUES diff --git a/quantum/keymap_extras/keymap_us_extended.h b/quantum/keymap_extras/keymap_us_extended.h deleted file mode 100644 index 90da98c756a7..000000000000 --- a/quantum/keymap_extras/keymap_us_extended.h +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define US_GRV KC_GRV // ` -#define US_1 KC_1 // 1 -#define US_2 KC_2 // 2 -#define US_3 KC_3 // 3 -#define US_4 KC_4 // 4 -#define US_5 KC_5 // 5 -#define US_6 KC_6 // 6 -#define US_7 KC_7 // 7 -#define US_8 KC_8 // 8 -#define US_9 KC_9 // 9 -#define US_0 KC_0 // 0 -#define US_MINS KC_MINS // - -#define US_EQL KC_EQL // = -#define US_Q KC_Q // Q -#define US_W KC_W // W -#define US_E KC_E // E -#define US_R KC_R // R -#define US_T KC_T // T -#define US_Y KC_Y // Y -#define US_U KC_U // U -#define US_I KC_I // I -#define US_O KC_O // O -#define US_P KC_P // P -#define US_LBRC KC_LBRC // [ -#define US_RBRC KC_RBRC // ] -#define US_BSLS KC_BSLS // (backslash) -#define US_A KC_A // A -#define US_S KC_S // S -#define US_D KC_D // D -#define US_F KC_F // F -#define US_G KC_G // G -#define US_H KC_H // H -#define US_J KC_J // J -#define US_K KC_K // K -#define US_L KC_L // L -#define US_SCLN KC_SCLN // ; -#define US_QUOT KC_QUOT // ' -#define US_Z KC_Z // Z -#define US_X KC_X // X -#define US_C KC_C // C -#define US_V KC_V // V -#define US_B KC_B // B -#define US_N KC_N // N -#define US_M KC_M // M -#define US_COMM KC_COMM // , -#define US_DOT KC_DOT // . -#define US_SLSH KC_SLSH // / -#define US_TILD S(US_GRV) // ~ -#define US_EXLM S(US_1) // ! -#define US_AT S(US_2) // @ -#define US_HASH S(US_3) // # -#define US_DLR S(US_4) // $ -#define US_PERC S(US_5) // % -#define US_CIRC S(US_6) // ^ -#define US_AMPR S(US_7) // & -#define US_ASTR S(US_8) // * -#define US_LPRN S(US_9) // ( -#define US_RPRN S(US_0) // ) -#define US_UNDS S(US_MINS) // _ -#define US_PLUS S(US_EQL) // + -#define US_LCBR S(US_LBRC) // { -#define US_RCBR S(US_RBRC) // } -#define US_PIPE S(US_BSLS) // | -#define US_COLN S(US_SCLN) // : -#define US_DQUO S(US_QUOT) // " -#define US_LABK S(US_COMM) // < -#define US_RABK S(US_DOT) // > -#define US_QUES S(US_SLSH) // ? -#define US_DGRV ALGR(US_GRV) // ` (dead) -#define US_SUP1 ALGR(US_1) // ¹ -#define US_SUP2 ALGR(US_2) // ² -#define US_SUP3 ALGR(US_3) // ³ -#define US_CURR ALGR(US_4) // ¤ -#define US_EURO ALGR(US_5) // € -#define US_DCIR ALGR(US_6) // ^ (dead) -#define US_HORN ALGR(US_7) // ̛ (dead) -#define US_OGON ALGR(US_8) // ˛ (dead) -#define US_LSQU ALGR(US_9) // ‘ -#define US_RSQU ALGR(US_0) // ’ -#define US_YEN ALGR(US_MINS) // ¥ -#define US_MUL ALGR(US_EQL) // × -#define US_ADIA ALGR(US_Q) // Ä -#define US_ARNG ALGR(US_W) // Å -#define US_EACU ALGR(US_E) // É -#define US_EDIA ALGR(US_R) // Ë -#define US_THRN ALGR(US_T) // Þ -#define US_UDIA ALGR(US_Y) // Ü -#define US_UACU ALGR(US_U) // Ú -#define US_IACU ALGR(US_I) // Í -#define US_OACU ALGR(US_O) // Ó -#define US_ODIA ALGR(US_P) // Ö -#define US_LDAQ ALGR(US_LBRC) // « -#define US_RDAQ ALGR(US_RBRC) // » -#define US_NOT ALGR(US_BSLS) // ¬ -#define US_AACU ALGR(US_A) // Á -#define US_SS ALGR(US_S) // ß -#define US_ETH ALGR(US_D) // Ð -#define US_IDIA ALGR(US_J) // Ï -#define US_OE ALGR(US_K) // Œ -#define US_OSTR ALGR(US_L) // Ø -#define US_PILC ALGR(US_SCLN) // ¶ -#define US_ACUT ALGR(US_QUOT) // ´ (dead) -#define US_AE ALGR(US_Z) // Æ -#define US_OE_2 ALGR(US_X) // Œ -#define US_COPY ALGR(US_C) // © -#define US_REGD ALGR(US_V) // ® -#define US_NTIL ALGR(US_N) // Ñ -#define US_MICR ALGR(US_M) // µ -#define US_CCED ALGR(US_COMM) // Ç -#define US_DOTA ALGR(US_DOT) // ˙ (dead) -#define US_IQUE ALGR(US_SLSH) // ¿ -#define US_DTIL S(ALGR(US_GRV)) // ~ (dead) -#define US_IEXL S(ALGR(US_1)) // ¡ -#define US_DACU S(ALGR(US_2)) // ˝ (dead) -#define US_MACR S(ALGR(US_3)) // ¯ (dead) -#define US_PND S(ALGR(US_4)) // £ -#define US_CEDL S(ALGR(US_5)) // ¸ (dead) -#define US_QRTR S(ALGR(US_6)) // ¼ -#define US_HALF S(ALGR(US_7)) // ½ -#define US_TQTR S(ALGR(US_8)) // ¾ -#define US_BREV S(ALGR(US_9)) // ˘ (dead) -#define US_RNGA S(ALGR(US_0)) // ° (dead) -#define US_DOTB S(ALGR(US_MINS)) // ̣ (dead) -#define US_DIV S(ALGR(US_EQL)) // ÷ -#define US_LDQU S(ALGR(US_LBRC)) // “ -#define US_RDQU S(ALGR(US_RBRC)) // ” -#define US_BRKP S(ALGR(US_BSLS)) // ¦ -#define US_SECT S(ALGR(US_S)) // § -#define US_DEG S(ALGR(US_SCLN)) // ° -#define US_DIAE S(ALGR(US_QUOT)) // ¨ (dead) -#define US_CENT S(ALGR(US_C)) // ¢ -#define US_CARN S(ALGR(US_DOT)) // ˇ (dead) -#define US_HOKA S(ALGR(US_SLSH)) // ̉ (dead) - diff --git a/quantum/keymap_extras/keymap_us_international.h b/quantum/keymap_extras/keymap_us_international.h deleted file mode 100644 index bd5f21ec8c60..000000000000 --- a/quantum/keymap_extras/keymap_us_international.h +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define US_DGRV KC_GRV // ` (dead) -#define US_1 KC_1 // 1 -#define US_2 KC_2 // 2 -#define US_3 KC_3 // 3 -#define US_4 KC_4 // 4 -#define US_5 KC_5 // 5 -#define US_6 KC_6 // 6 -#define US_7 KC_7 // 7 -#define US_8 KC_8 // 8 -#define US_9 KC_9 // 9 -#define US_0 KC_0 // 0 -#define US_MINS KC_MINS // - -#define US_EQL KC_EQL // = -#define US_Q KC_Q // Q -#define US_W KC_W // W -#define US_E KC_E // E -#define US_R KC_R // R -#define US_T KC_T // T -#define US_Y KC_Y // Y -#define US_U KC_U // U -#define US_I KC_I // I -#define US_O KC_O // O -#define US_P KC_P // P -#define US_LBRC KC_LBRC // [ -#define US_RBRC KC_RBRC // ] -#define US_BSLS KC_BSLS // (backslash) -#define US_A KC_A // A -#define US_S KC_S // S -#define US_D KC_D // D -#define US_F KC_F // F -#define US_G KC_G // G -#define US_H KC_H // H -#define US_J KC_J // J -#define US_K KC_K // K -#define US_L KC_L // L -#define US_SCLN KC_SCLN // ; -#define US_ACUT KC_QUOT // ´ (dead) -#define US_Z KC_Z // Z -#define US_X KC_X // X -#define US_C KC_C // C -#define US_V KC_V // V -#define US_B KC_B // B -#define US_N KC_N // N -#define US_M KC_M // M -#define US_COMM KC_COMM // , -#define US_DOT KC_DOT // . -#define US_SLSH KC_SLSH // / -#define US_DTIL S(US_DGRV) // ~ (dead) -#define US_EXLM S(US_1) // ! -#define US_AT S(US_2) // @ -#define US_HASH S(US_3) // # -#define US_DLR S(US_4) // $ -#define US_PERC S(US_5) // % -#define US_DCIR S(US_6) // ^ (dead) -#define US_AMPR S(US_7) // & -#define US_ASTR S(US_8) // * -#define US_LPRN S(US_9) // ( -#define US_RPRN S(US_0) // ) -#define US_UNDS S(US_MINS) // _ -#define US_PLUS S(US_EQL) // + -#define US_LCBR S(US_LBRC) // { -#define US_RCBR S(US_RBRC) // } -#define US_PIPE S(US_BSLS) // | -#define US_COLN S(US_SCLN) // : -#define US_DIAE S(US_ACUT) // ¨ (dead) -#define US_LABK S(US_COMM) // < -#define US_RABK S(US_DOT) // > -#define US_QUES S(US_SLSH) // ? -#define US_IEXL ALGR(US_1) // ¡ -#define US_SUP2 ALGR(US_2) // ² -#define US_SUP3 ALGR(US_3) // ³ -#define US_CURR ALGR(US_4) // ¤ -#define US_EURO ALGR(US_5) // € -#define US_QRTR ALGR(US_6) // ¼ -#define US_HALF ALGR(US_7) // ½ -#define US_TQTR ALGR(US_8) // ¾ -#define US_LSQU ALGR(US_9) // ‘ -#define US_RSQU ALGR(US_0) // ’ -#define US_YEN ALGR(US_MINS) // ¥ -#define US_MUL ALGR(US_EQL) // × -#define US_ADIA ALGR(US_Q) // Ä -#define US_ARNG ALGR(US_W) // Å -#define US_EACU ALGR(US_E) // É -#define US_REGD ALGR(US_R) // ® -#define US_THRN ALGR(US_T) // Þ -#define US_UDIA ALGR(US_Y) // Ü -#define US_UACU ALGR(US_U) // Ú -#define US_IACU ALGR(US_I) // Í -#define US_OACU ALGR(US_O) // Ó -#define US_ODIA ALGR(US_P) // Ö -#define US_LDAQ ALGR(US_LBRC) // « -#define US_RDAQ ALGR(US_RBRC) // » -#define US_NOT ALGR(US_BSLS) // ¬ -#define US_AACU ALGR(US_A) // Á -#define US_SS ALGR(US_S) // ß -#define US_ETH ALGR(US_D) // Ð -#define US_OSTR ALGR(US_L) // Ø -#define US_PILC ALGR(US_SCLN) // ¶ -#define US_NDAC ALGR(US_ACUT) // ´ -#define US_AE ALGR(US_Z) // Æ -#define US_COPY ALGR(US_C) // © -#define US_NTIL ALGR(US_N) // Ñ -#define US_MICR ALGR(US_M) // µ -#define US_CCED ALGR(US_COMM) // Ç -#define US_IQUE ALGR(US_SLSH) // ¿ -#define US_SUP1 S(ALGR(US_1)) // ¹ -#define US_PND S(ALGR(US_4)) // £ -#define US_DIV S(ALGR(US_EQL)) // ÷ -#define US_BRKP S(ALGR(US_BSLS)) // ¦ -#define US_SECT S(ALGR(US_S)) // § -#define US_DEG S(ALGR(US_SCLN)) // ° -#define US_NDDR S(ALGR(US_ACUT)) // ¨ -#define US_CENT S(ALGR(US_C)) // ¢ - diff --git a/quantum/keymap_extras/keymap_us_international_linux.h b/quantum/keymap_extras/keymap_us_international_linux.h deleted file mode 100644 index 4551cbe29ffa..000000000000 --- a/quantum/keymap_extras/keymap_us_international_linux.h +++ /dev/null @@ -1,161 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define US_DGRV KC_GRV // ` (dead) -#define US_1 KC_1 // 1 -#define US_2 KC_2 // 2 -#define US_3 KC_3 // 3 -#define US_4 KC_4 // 4 -#define US_5 KC_5 // 5 -#define US_6 KC_6 // 6 -#define US_7 KC_7 // 7 -#define US_8 KC_8 // 8 -#define US_9 KC_9 // 9 -#define US_0 KC_0 // 0 -#define US_MINS KC_MINS // - -#define US_EQL KC_EQL // = -#define US_Q KC_Q // Q -#define US_W KC_W // W -#define US_E KC_E // E -#define US_R KC_R // R -#define US_T KC_T // T -#define US_Y KC_Y // Y -#define US_U KC_U // U -#define US_I KC_I // I -#define US_O KC_O // O -#define US_P KC_P // P -#define US_LBRC KC_LBRC // [ -#define US_RBRC KC_RBRC // ] -#define US_BSLS KC_BSLS // (backslash) -#define US_A KC_A // A -#define US_S KC_S // S -#define US_D KC_D // D -#define US_F KC_F // F -#define US_G KC_G // G -#define US_H KC_H // H -#define US_J KC_J // J -#define US_K KC_K // K -#define US_L KC_L // L -#define US_SCLN KC_SCLN // ; -#define US_ACUT KC_QUOT // ´ (dead) -#define US_Z KC_Z // Z -#define US_X KC_X // X -#define US_C KC_C // C -#define US_V KC_V // V -#define US_B KC_B // B -#define US_N KC_N // N -#define US_M KC_M // M -#define US_COMM KC_COMM // , -#define US_DOT KC_DOT // . -#define US_SLSH KC_SLSH // / -#define US_DTIL S(US_DGRV) // ~ (dead) -#define US_EXLM S(US_1) // ! -#define US_AT S(US_2) // @ -#define US_HASH S(US_3) // # -#define US_DLR S(US_4) // $ -#define US_PERC S(US_5) // % -#define US_DCIR S(US_6) // ^ (dead) -#define US_AMPR S(US_7) // & -#define US_ASTR S(US_8) // * -#define US_LPRN S(US_9) // ( -#define US_RPRN S(US_0) // ) -#define US_UNDS S(US_MINS) // _ -#define US_PLUS S(US_EQL) // + -#define US_LCBR S(US_LBRC) // { -#define US_RCBR S(US_RBRC) // } -#define US_PIPE S(US_BSLS) // | -#define US_COLN S(US_SCLN) // : -#define US_DIAE S(US_ACUT) // ¨ (dead) -#define US_LABK S(US_COMM) // < -#define US_RABK S(US_DOT) // > -#define US_QUES S(US_SLSH) // ? -#define US_GRV ALGR(US_DGRV) // ` -#define US_IEXL ALGR(US_1) // ¡ -#define US_SUP2 ALGR(US_2) // ² -#define US_SUP3 ALGR(US_3) // ³ -#define US_CURR ALGR(US_4) // ¤ -#define US_EURO ALGR(US_5) // € -#define US_QRTR ALGR(US_6) // ¼ -#define US_HALF ALGR(US_7) // ½ -#define US_TQTR ALGR(US_8) // ¾ -#define US_LSQU ALGR(US_9) // ‘ -#define US_RSQU ALGR(US_0) // ’ -#define US_YEN ALGR(US_MINS) // ¥ -#define US_MUL ALGR(US_EQL) // × -#define US_ADIA ALGR(US_Q) // Ä -#define US_ARNG ALGR(US_W) // Å -#define US_EACU ALGR(US_E) // É -#define US_REGD ALGR(US_R) // ® -#define US_THRN ALGR(US_T) // Þ -#define US_UDIA ALGR(US_Y) // Ü -#define US_UACU ALGR(US_U) // Ú -#define US_IACU ALGR(US_I) // Í -#define US_OACU ALGR(US_O) // Ó -#define US_ODIA ALGR(US_P) // Ö -#define US_LDAQ ALGR(US_LBRC) // « -#define US_RDAQ ALGR(US_RBRC) // » -#define US_NOT ALGR(US_BSLS) // ¬ -#define US_AACU ALGR(US_A) // Á -#define US_SS ALGR(US_S) // ß -#define US_ETH ALGR(US_D) // Ð -#define US_OE ALGR(US_K) // Œ -#define US_OSTR ALGR(US_L) // Ø -#define US_PILC ALGR(US_SCLN) // ¶ -#define US_QUOT ALGR(US_ACUT) // ' -#define US_AE ALGR(US_Z) // Æ -#define US_COPY ALGR(US_C) // © -#define US_NTIL ALGR(US_N) // Ñ -#define US_MICR ALGR(US_M) // µ -#define US_CCED ALGR(US_COMM) // Ç -#define US_DOTA ALGR(US_DOT) // ˙ (dead) -#define US_IQUE ALGR(US_SLSH) // ¿ -#define US_TILD S(ALGR(US_DGRV)) // ~ -#define US_SUP1 S(ALGR(US_1)) // ¹ -#define US_DACU S(ALGR(US_2)) // ˝ (dead) -#define US_MACR S(ALGR(US_3)) // ¯ (dead) -#define US_PND S(ALGR(US_4)) // £ -#define US_CEDL S(ALGR(US_5)) // ¸ (dead) -#define US_CIRC S(ALGR(US_6)) // ^ -#define US_HORN S(ALGR(US_7)) // ̛ (dead) -#define US_OGON S(ALGR(US_8)) // ˛ (dead) -#define US_BREV S(ALGR(US_9)) // ˘ (dead) -#define US_RNGA S(ALGR(US_0)) // ° (dead) -#define US_DOTB S(ALGR(US_MINS)) // ̣ (dead) -#define US_DIV S(ALGR(US_EQL)) // ÷ -#define US_LDQU S(ALGR(US_LBRC)) // “ -#define US_RDQU S(ALGR(US_RBRC)) // ” -#define US_BRKP S(ALGR(US_BSLS)) // ¦ -#define US_SECT S(ALGR(US_S)) // § -#define US_DEG S(ALGR(US_SCLN)) // ° -#define US_DQUO S(ALGR(US_ACUT)) // " -#define US_CENT S(ALGR(US_C)) // ¢ -#define US_CARN S(ALGR(US_DOT)) // ˇ (dead) -#define US_HOKA S(ALGR(US_SLSH)) // ̉ (dead) - diff --git a/quantum/keymap_extras/keymap_workman.h b/quantum/keymap_extras/keymap_workman.h deleted file mode 100644 index 808caec054cd..000000000000 --- a/quantum/keymap_extras/keymap_workman.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define WK_GRV KC_GRV // ` -#define WK_1 KC_1 // 1 -#define WK_2 KC_2 // 2 -#define WK_3 KC_3 // 3 -#define WK_4 KC_4 // 4 -#define WK_5 KC_5 // 5 -#define WK_6 KC_6 // 6 -#define WK_7 KC_7 // 7 -#define WK_8 KC_8 // 8 -#define WK_9 KC_9 // 9 -#define WK_0 KC_0 // 0 -#define WK_MINS KC_MINS // - -#define WK_EQL KC_EQL // = -#define WK_Q KC_Q // Q -#define WK_D KC_W // D -#define WK_R KC_E // R -#define WK_W KC_R // W -#define WK_B KC_T // B -#define WK_J KC_Y // J -#define WK_F KC_U // F -#define WK_U KC_I // U -#define WK_P KC_O // P -#define WK_SCLN KC_P // ; -#define WK_LBRC KC_LBRC // [ -#define WK_RBRC KC_RBRC // ] -#define WK_BSLS KC_BSLS // (backslash) -#define WK_A KC_A // A -#define WK_S KC_S // S -#define WK_H KC_D // H -#define WK_T KC_F // T -#define WK_G KC_G // G -#define WK_Y KC_H // Y -#define WK_N KC_J // N -#define WK_E KC_K // E -#define WK_O KC_L // O -#define WK_I KC_SCLN // I -#define WK_QUOT KC_QUOT // ' -#define WK_Z KC_Z // Z -#define WK_X KC_X // X -#define WK_M KC_C // M -#define WK_C KC_V // C -#define WK_V KC_B // V -#define WK_K KC_N // K -#define WK_L KC_M // L -#define WK_COMM KC_COMM // , -#define WK_DOT KC_DOT // . -#define WK_SLSH KC_SLSH // / -#define WK_TILD S(WK_GRV) // ~ -#define WK_EXLM S(WK_1) // ! -#define WK_AT S(WK_2) // @ -#define WK_HASH S(WK_3) // # -#define WK_DLR S(WK_4) // $ -#define WK_PERC S(WK_5) // % -#define WK_CIRC S(WK_6) // ^ -#define WK_AMPR S(WK_7) // & -#define WK_ASTR S(WK_8) // * -#define WK_LPRN S(WK_9) // ( -#define WK_RPRN S(WK_0) // ) -#define WK_UNDS S(WK_MINS) // _ -#define WK_PLUS S(WK_EQL) // + -#define WK_COLN S(WK_SCLN) // : -#define WK_LCBR S(WK_LBRC) // { -#define WK_RCBR S(WK_RBRC) // } -#define WK_PIPE S(WK_BSLS) // | -#define WK_DQUO S(WK_QUOT) // " -#define WK_LABK S(WK_COMM) // < -#define WK_RABK S(WK_DOT) // > -#define WK_QUES S(WK_SLSH) // ? - diff --git a/quantum/keymap_extras/keymap_workman_zxcvm.h b/quantum/keymap_extras/keymap_workman_zxcvm.h deleted file mode 100644 index f8645ac4cfbe..000000000000 --- a/quantum/keymap_extras/keymap_workman_zxcvm.h +++ /dev/null @@ -1,99 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -#include "keycodes.h" -// clang-format off - -// Aliases -#define WK_GRV KC_GRV // ` -#define WK_1 KC_1 // 1 -#define WK_2 KC_2 // 2 -#define WK_3 KC_3 // 3 -#define WK_4 KC_4 // 4 -#define WK_5 KC_5 // 5 -#define WK_6 KC_6 // 6 -#define WK_7 KC_7 // 7 -#define WK_8 KC_8 // 8 -#define WK_9 KC_9 // 9 -#define WK_0 KC_0 // 0 -#define WK_MINS KC_MINS // - -#define WK_EQL KC_EQL // = -#define WK_Q KC_Q // Q -#define WK_D KC_W // D -#define WK_R KC_E // R -#define WK_W KC_R // W -#define WK_B KC_T // B -#define WK_J KC_Y // J -#define WK_F KC_U // F -#define WK_U KC_I // U -#define WK_P KC_O // P -#define WK_SCLN KC_P // ; -#define WK_LBRC KC_LBRC // [ -#define WK_RBRC KC_RBRC // ] -#define WK_BSLS KC_BSLS // (backslash) -#define WK_A KC_A // A -#define WK_S KC_S // S -#define WK_H KC_D // H -#define WK_T KC_F // T -#define WK_G KC_G // G -#define WK_Y KC_H // Y -#define WK_N KC_J // N -#define WK_E KC_K // E -#define WK_O KC_L // O -#define WK_I KC_SCLN // I -#define WK_QUOT KC_QUOT // ' -#define WK_Z KC_Z // Z -#define WK_X KC_X // X -#define WK_C KC_C // C -#define WK_V KC_V // V -#define WK_M KC_B // M -#define WK_K KC_N // K -#define WK_L KC_M // L -#define WK_COMM KC_COMM // , -#define WK_DOT KC_DOT // . -#define WK_SLSH KC_SLSH // / -#define WK_TILD S(WK_GRV) // ~ -#define WK_EXLM S(WK_1) // ! -#define WK_AT S(WK_2) // @ -#define WK_HASH S(WK_3) // # -#define WK_DLR S(WK_4) // $ -#define WK_PERC S(WK_5) // % -#define WK_CIRC S(WK_6) // ^ -#define WK_AMPR S(WK_7) // & -#define WK_ASTR S(WK_8) // * -#define WK_LPRN S(WK_9) // ( -#define WK_RPRN S(WK_0) // ) -#define WK_UNDS S(WK_MINS) // _ -#define WK_PLUS S(WK_EQL) // + -#define WK_COLN S(WK_SCLN) // : -#define WK_LCBR S(WK_LBRC) // { -#define WK_RCBR S(WK_RBRC) // } -#define WK_PIPE S(WK_BSLS) // | -#define WK_DQUO S(WK_QUOT) // " -#define WK_LABK S(WK_COMM) // < -#define WK_RABK S(WK_DOT) // > -#define WK_QUES S(WK_SLSH) // ? - diff --git a/quantum/keymap_extras/sendstring_belgian.h b/quantum/keymap_extras/sendstring_belgian.h deleted file mode 100644 index 34ca9514c816..000000000000 --- a/quantum/keymap_extras/sendstring_belgian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 kimat - * - * 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 . - */ - -// Sendstring lookup tables for Belgian layouts - -#pragma once - -#include "keymap_belgian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, BE_EXLM, BE_DQUO, BE_DQUO, BE_DLR, BE_UGRV, BE_AMPR, BE_QUOT, - // ( ) * + , - . / - BE_LPRN, BE_RPRN, BE_DLR, BE_EQL, BE_COMM, BE_MINS, BE_SCLN, BE_COLN, - // 0 1 2 3 4 5 6 7 - BE_AGRV, BE_AMPR, BE_EACU, BE_DQUO, BE_QUOT, BE_LPRN, BE_SECT, BE_EGRV, - // 8 9 : ; < = > ? - BE_EXLM, BE_CCED, BE_COLN, BE_SCLN, BE_LABK, BE_EQL, BE_LABK, BE_COMM, - // @ A B C D E F G - BE_EACU, BE_A, BE_B, BE_C, BE_D, BE_E, BE_F, BE_G, - // H I J K L M N O - BE_H, BE_I, BE_J, BE_K, BE_L, BE_M, BE_N, BE_O, - // P Q R S T U V W - BE_P, BE_Q, BE_R, BE_S, BE_T, BE_U, BE_V, BE_W, - // X Y Z [ \ ] ^ _ - BE_X, BE_Y, BE_Z, BE_DCIR, BE_LABK, BE_DLR, BE_SECT, BE_MINS, - // ` a b c d e f g - BE_MICR, BE_A, BE_B, BE_C, BE_D, BE_E, BE_F, BE_G, - // h i j k l m n o - BE_H, BE_I, BE_J, BE_K, BE_L, BE_M, BE_N, BE_O, - // p q r s t u v w - BE_P, BE_Q, BE_R, BE_S, BE_T, BE_U, BE_V, BE_W, - // x y z { | } ~ DEL - BE_X, BE_Y, BE_Z, BE_CCED, BE_AMPR, BE_AGRV, BE_EQL, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_bepo.h b/quantum/keymap_extras/sendstring_bepo.h deleted file mode 100644 index 0f0d5a2111e4..000000000000 --- a/quantum/keymap_extras/sendstring_bepo.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2018 Jonathan Nifenecker - * - * 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 . - */ - -// Sendstring lookup tables for BÉPO layouts - -#pragma once - -#include "keymap_bepo.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, BP_DCIR, BP_DQUO, BP_DLR, BP_DLR, BP_PERC, BP_P, BP_QUOT, - // ( ) * + , - . / - BP_LPRN, BP_RPRN, BP_ASTR, BP_PLUS, BP_COMM, BP_MINS, BP_DOT, BP_SLSH, - // 0 1 2 3 4 5 6 7 - BP_ASTR, BP_DQUO, BP_LDAQ, BP_RDAQ, BP_LPRN, BP_RPRN, BP_AT, BP_PLUS, - // 8 9 : ; < = > ? - BP_MINS, BP_SLSH, BP_DOT, BP_COMM, BP_LDAQ, BP_EQL, BP_RDAQ, BP_QUOT, - // @ A B C D E F G - BP_AT, BP_A, BP_B, BP_C, BP_D, BP_E, BP_F, BP_G, - // H I J K L M N O - BP_H, BP_I, BP_J, BP_K, BP_L, BP_M, BP_N, BP_O, - // P Q R S T U V W - BP_P, BP_Q, BP_R, BP_S, BP_T, BP_U, BP_V, BP_W, - // X Y Z [ \ ] ^ _ - BP_X, BP_Y, BP_Z, BP_LPRN, BP_AGRV, BP_RPRN, BP_AT, KC_SPC, - // ` a b c d e f g - BP_PERC, BP_A, BP_B, BP_C, BP_D, BP_E, BP_F, BP_G, - // h i j k l m n o - BP_H, BP_I, BP_J, BP_K, BP_L, BP_M, BP_N, BP_O, - // p q r s t u v w - BP_P, BP_Q, BP_R, BP_S, BP_T, BP_U, BP_V, BP_W, - // x y z { | } ~ DEL - BP_X, BP_Y, BP_Z, BP_Y, BP_B, BP_X, BP_K, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_brazilian_abnt2.h b/quantum/keymap_extras/sendstring_brazilian_abnt2.h deleted file mode 100644 index b52ce4958ab7..000000000000 --- a/quantum/keymap_extras/sendstring_brazilian_abnt2.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Brazilian (ABNT2) layouts - -#pragma once - -#include "keymap_brazilian_abnt2.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, BR_1, BR_QUOT, BR_3, BR_4, BR_5, BR_7, BR_QUOT, - // ( ) * + , - . / - BR_9, BR_0, BR_8, BR_EQL, BR_COMM, BR_MINS, BR_DOT, BR_SLSH, - // 0 1 2 3 4 5 6 7 - BR_0, BR_1, BR_2, BR_3, BR_4, BR_5, BR_6, BR_7, - // 8 9 : ; < = > ? - BR_8, BR_9, BR_SCLN, BR_SCLN, BR_COMM, BR_EQL, BR_DOT, BR_SLSH, - // @ A B C D E F G - BR_2, BR_A, BR_B, BR_C, BR_D, BR_E, BR_F, BR_G, - // H I J K L M N O - BR_H, BR_I, BR_J, BR_K, BR_L, BR_M, BR_N, BR_O, - // P Q R S T U V W - BR_P, BR_Q, BR_R, BR_S, BR_T, BR_U, BR_V, BR_W, - // X Y Z [ \ ] ^ _ - BR_X, BR_Y, BR_Z, BR_LBRC, BR_BSLS, BR_RBRC, BR_TILD, BR_MINS, - // ` a b c d e f g - BR_ACUT, BR_A, BR_B, BR_C, BR_D, BR_E, BR_F, BR_G, - // h i j k l m n o - BR_H, BR_I, BR_J, BR_K, BR_L, BR_M, BR_N, BR_O, - // p q r s t u v w - BR_P, BR_Q, BR_R, BR_S, BR_T, BR_U, BR_V, BR_W, - // x y z { | } ~ DEL - BR_X, BR_Y, BR_Z, BR_LBRC, BR_BSLS, BR_RBRC, BR_TILD, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_canadian_multilingual.h b/quantum/keymap_extras/sendstring_canadian_multilingual.h deleted file mode 100644 index 92b588c82e40..000000000000 --- a/quantum/keymap_extras/sendstring_canadian_multilingual.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Canadian Multilingual layouts - -#pragma once - -#include "keymap_canadian_multilingual.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, CA_1, CA_DOT, CA_3, CA_4, CA_5, CA_7, CA_COMM, - // ( ) * + , - . / - CA_9, CA_0, CA_8, CA_EQL, CA_COMM, CA_MINS, CA_DOT, CA_SLSH, - // 0 1 2 3 4 5 6 7 - CA_0, CA_1, CA_2, CA_3, CA_4, CA_5, CA_6, CA_7, - // 8 9 : ; < = > ? - CA_8, CA_9, CA_SCLN, CA_SCLN, CA_COMM, CA_EQL, CA_DOT, CA_6, - // @ A B C D E F G - CA_2, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G, - // H I J K L M N O - CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O, - // P Q R S T U V W - CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W, - // X Y Z [ \ ] ^ _ - CA_X, CA_Y, CA_Z, CA_9, CA_SLSH, CA_0, CA_CIRC, CA_MINS, - // ` a b c d e f g - CA_CIRC, CA_A, CA_B, CA_C, CA_D, CA_E, CA_F, CA_G, - // h i j k l m n o - CA_H, CA_I, CA_J, CA_K, CA_L, CA_M, CA_N, CA_O, - // p q r s t u v w - CA_P, CA_Q, CA_R, CA_S, CA_T, CA_U, CA_V, CA_W, - // x y z { | } ~ DEL - CA_X, CA_Y, CA_Z, CA_7, CA_SLSH, CA_8, CA_CCED, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_colemak.h b/quantum/keymap_extras/sendstring_colemak.h deleted file mode 100644 index 3aef96b24afe..000000000000 --- a/quantum/keymap_extras/sendstring_colemak.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -// Sendstring lookup tables for Colemak layouts - -#pragma once - -#include "keymap_colemak.h" - -// clang-format off - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, CM_1, CM_QUOT, CM_3, CM_4, CM_5, CM_7, CM_QUOT, - // ( ) * + , - . / - CM_9, CM_0, CM_8, CM_EQL, CM_COMM, CM_MINS, CM_DOT, CM_SLSH, - // 0 1 2 3 4 5 6 7 - CM_0, CM_1, CM_2, CM_3, CM_4, CM_5, CM_6, CM_7, - // 8 9 : ; < = > ? - CM_8, CM_9, CM_SCLN, CM_SCLN, CM_COMM, CM_EQL, CM_DOT, CM_SLSH, - // @ A B C D E F G - CM_2, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, - // H I J K L M N O - CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, - // P Q R S T U V W - CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, - // X Y Z [ \ ] ^ _ - CM_X, CM_Y, CM_Z, CM_LBRC, CM_BSLS, CM_RBRC, CM_6, CM_MINS, - // ` a b c d e f g - CM_GRV, CM_A, CM_B, CM_C, CM_D, CM_E, CM_F, CM_G, - // h i j k l m n o - CM_H, CM_I, CM_J, CM_K, CM_L, CM_M, CM_N, CM_O, - // p q r s t u v w - CM_P, CM_Q, CM_R, CM_S, CM_T, CM_U, CM_V, CM_W, - // x y z { | } ~ DEL - CM_X, CM_Y, CM_Z, CM_LBRC, CM_BSLS, CM_RBRC, CM_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_croatian.h b/quantum/keymap_extras/sendstring_croatian.h deleted file mode 100644 index bf51c81a8842..000000000000 --- a/quantum/keymap_extras/sendstring_croatian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Croatian layouts - -#pragma once - -#include "keymap_croatian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, HR_1, HR_2, HR_3, HR_4, HR_5, HR_6, HR_QUOT, - // ( ) * + , - . / - HR_8, HR_9, HR_PLUS, HR_PLUS, HR_COMM, HR_MINS, HR_DOT, HR_7, - // 0 1 2 3 4 5 6 7 - HR_0, HR_1, HR_2, HR_3, HR_4, HR_5, HR_6, HR_7, - // 8 9 : ; < = > ? - HR_8, HR_9, HR_DOT, HR_COMM, HR_LABK, HR_0, HR_LABK, HR_QUOT, - // @ A B C D E F G - HR_V, HR_A, HR_B, HR_C, HR_D, HR_E, HR_F, HR_G, - // H I J K L M N O - HR_H, HR_I, HR_J, HR_K, HR_L, HR_M, HR_N, HR_O, - // P Q R S T U V W - HR_P, HR_Q, HR_R, HR_S, HR_T, HR_U, HR_V, HR_W, - // X Y Z [ \ ] ^ _ - HR_X, HR_Y, HR_Z, HR_F, HR_Q, HR_G, HR_3, HR_MINS, - // ` a b c d e f g - HR_7, HR_A, HR_B, HR_C, HR_D, HR_E, HR_F, HR_G, - // h i j k l m n o - HR_H, HR_I, HR_J, HR_K, HR_L, HR_M, HR_N, HR_O, - // p q r s t u v w - HR_P, HR_Q, HR_R, HR_S, HR_T, HR_U, HR_V, HR_W, - // x y z { | } ~ DEL - HR_X, HR_Y, HR_Z, HR_B, HR_W, HR_N, HR_1, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_czech.h b/quantum/keymap_extras/sendstring_czech.h deleted file mode 100644 index 54c331741863..000000000000 --- a/quantum/keymap_extras/sendstring_czech.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Czech layouts - -#pragma once - -#include "keymap_czech.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0), -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, CZ_SECT, CZ_URNG, CZ_X, CZ_URNG, CZ_EQL, CZ_C, CZ_DIAE, - // ( ) * + , - . / - CZ_RPRN, CZ_RPRN, CZ_MINS, CZ_PLUS, CZ_COMM, CZ_MINS, CZ_DOT, CZ_UACU, - // 0 1 2 3 4 5 6 7 - CZ_EACU, CZ_PLUS, CZ_ECAR, CZ_SCAR, CZ_CCAR, CZ_RCAR, CZ_ZCAR, CZ_YACU, - // 8 9 : ; < = > ? - CZ_AACU, CZ_IACU, CZ_DOT, CZ_SCLN, CZ_COMM, CZ_EQL, CZ_DOT, CZ_COMM, - // @ A B C D E F G - CZ_V, CZ_A, CZ_B, CZ_C, CZ_D, CZ_E, CZ_F, CZ_G, - // H I J K L M N O - CZ_H, CZ_I, CZ_J, CZ_K, CZ_L, CZ_M, CZ_N, CZ_O, - // P Q R S T U V W - CZ_P, CZ_Q, CZ_R, CZ_S, CZ_T, CZ_U, CZ_V, CZ_W, - // X Y Z [ \ ] ^ _ - CZ_X, CZ_Y, CZ_Z, CZ_F, CZ_BSLS, CZ_G, CZ_SCAR, CZ_MINS, - // ` a b c d e f g - CZ_YACU, CZ_A, CZ_B, CZ_C, CZ_D, CZ_E, CZ_F, CZ_G, - // h i j k l m n o - CZ_H, CZ_I, CZ_J, CZ_K, CZ_L, CZ_M, CZ_N, CZ_O, - // p q r s t u v w - CZ_P, CZ_Q, CZ_R, CZ_S, CZ_T, CZ_U, CZ_V, CZ_W, - // x y z { | } ~ DEL - CZ_X, CZ_Y, CZ_Z, CZ_B, CZ_BSLS, CZ_N, CZ_PLUS, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_danish.h b/quantum/keymap_extras/sendstring_danish.h deleted file mode 100644 index 6923063ce2ce..000000000000 --- a/quantum/keymap_extras/sendstring_danish.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Danish layouts - -#pragma once - -#include "keymap_danish.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DK_1, DK_2, DK_3, DK_4, DK_5, DK_6, DK_QUOT, - // ( ) * + , - . / - DK_8, DK_9, DK_QUOT, DK_PLUS, DK_COMM, DK_MINS, DK_DOT, DK_7, - // 0 1 2 3 4 5 6 7 - DK_0, DK_1, DK_2, DK_3, DK_4, DK_5, DK_6, DK_7, - // 8 9 : ; < = > ? - DK_8, DK_9, DK_DOT, DK_COMM, DK_LABK, DK_0, DK_LABK, DK_PLUS, - // @ A B C D E F G - DK_2, DK_A, DK_B, DK_C, DK_D, DK_E, DK_F, DK_G, - // H I J K L M N O - DK_H, DK_I, DK_J, DK_K, DK_L, DK_M, DK_N, DK_O, - // P Q R S T U V W - DK_P, DK_Q, DK_R, DK_S, DK_T, DK_U, DK_V, DK_W, - // X Y Z [ \ ] ^ _ - DK_X, DK_Y, DK_Z, DK_8, DK_LABK, DK_9, DK_DIAE, DK_MINS, - // ` a b c d e f g - DK_ACUT, DK_A, DK_B, DK_C, DK_D, DK_E, DK_F, DK_G, - // h i j k l m n o - DK_H, DK_I, DK_J, DK_K, DK_L, DK_M, DK_N, DK_O, - // p q r s t u v w - DK_P, DK_Q, DK_R, DK_S, DK_T, DK_U, DK_V, DK_W, - // x y z { | } ~ DEL - DK_X, DK_Y, DK_Z, DK_7, DK_ACUT, DK_0, DK_DIAE, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_dvorak.h b/quantum/keymap_extras/sendstring_dvorak.h deleted file mode 100644 index 25e1d31423a7..000000000000 --- a/quantum/keymap_extras/sendstring_dvorak.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -// Sendstring lookup tables for Dvorak layouts - -#pragma once - -#include "keymap_dvorak.h" - -// clang-format off - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DV_1, DV_QUOT, DV_3, DV_4, DV_5, DV_7, DV_QUOT, - // ( ) * + , - . / - DV_9, DV_0, DV_8, DV_EQL, DV_COMM, DV_MINS, DV_DOT, DV_SLSH, - // 0 1 2 3 4 5 6 7 - DV_0, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_7, - // 8 9 : ; < = > ? - DV_8, DV_9, DV_SCLN, DV_SCLN, DV_COMM, DV_EQL, DV_DOT, DV_SLSH, - // @ A B C D E F G - DV_2, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // H I J K L M N O - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // P Q R S T U V W - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // X Y Z [ \ ] ^ _ - DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_6, DV_MINS, - // ` a b c d e f g - DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // h i j k l m n o - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // p q r s t u v w - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // x y z { | } ~ DEL - DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_dvorak_fr.h b/quantum/keymap_extras/sendstring_dvorak_fr.h deleted file mode 100644 index 2f4f2817949a..000000000000 --- a/quantum/keymap_extras/sendstring_dvorak_fr.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Copyright 2020 Guillaume Gérard - * - * 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 . - */ - -// Sendstring lookup tables for Dvorak French layouts - -#pragma once - -#include "keymap_dvorak_fr.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DV_DOT, XXXXXXX, DV_TILD, XXXXXXX, DV_RBRC, XXXXXXX, DV_QUOT, - // ( ) * + , - . / - DV_LPRN, DV_RPRN, DV_LDAQ, DV_LBRC, DV_COMM, DV_MINS, DV_DOT, DV_SLSH, - // 0 1 2 3 4 5 6 7 - DV_UNDS, DV_RDAQ, DV_SLSH, DV_MINS, DV_EGRV, DV_BSLS, DV_CIRC, DV_LPRN, - // 8 9 : ; < = > ? - DV_GRV, DV_RPRN, DV_COLN, DV_SCLN, DV_QUOT, DV_DIAE, DV_EACU, DV_COLN, - // @ A B C D E F G - DV_COMM, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // H I J K L M N O - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // P Q R S T U V W - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // X Y Z [ \ ] ^ _ - DV_X, DV_Y, DV_Z, DV_LBRC, DV_BSLS, DV_RBRC, DV_CIRC, DV_UNDS, - // ` a b c d e f g - DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // h i j k l m n o - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // p q r s t u v w - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // x y z { | } ~ DEL - DV_X, DV_Y, DV_Z, XXXXXXX, DV_SCLN, XXXXXXX, DV_TILD, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_dvorak_programmer.h b/quantum/keymap_extras/sendstring_dvorak_programmer.h deleted file mode 100644 index f19bb6f4b215..000000000000 --- a/quantum/keymap_extras/sendstring_dvorak_programmer.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Programmer Dvorak layouts - -#pragma once - -#include "keymap_dvorak_programmer.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 1, 0, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DP_EXLM, DP_QUOT, DP_HASH, DP_DLR, DP_AMPR, DP_AMPR, DP_QUOT, - // ( ) * + , - . / - DP_LPRN, DP_RPRN, DP_ASTR, DP_PLUS, DP_COMM, DP_MINS, DP_DOT, DP_SLSH, - // 0 1 2 3 4 5 6 7 - DP_ASTR, DP_LPRN, DP_RPRN, DP_RCBR, DP_PLUS, DP_LCBR, DP_RBRC, DP_LBRC, - // 8 9 : ; < = > ? - DP_EXLM, DP_EQL, DP_SCLN, DP_SCLN, DP_COMM, DP_EQL, DP_DOT, DP_SLSH, - // @ A B C D E F G - DP_AT, DP_A, DP_B, DP_C, DP_D, DP_E, DP_F, DP_G, - // H I J K L M N O - DP_H, DP_I, DP_J, DP_K, DP_L, DP_M, DP_N, DP_O, - // P Q R S T U V W - DP_P, DP_Q, DP_R, DP_S, DP_T, DP_U, DP_V, DP_W, - // X Y Z [ \ ] ^ _ - DP_X, DP_Y, DP_Z, DP_LBRC, DP_BSLS, DP_RBRC, DP_AT, DP_MINS, - // ` a b c d e f g - DP_HASH, DP_A, DP_B, DP_C, DP_D, DP_E, DP_F, DP_G, - // h i j k l m n o - DP_H, DP_I, DP_J, DP_K, DP_L, DP_M, DP_N, DP_O, - // p q r s t u v w - DP_P, DP_Q, DP_R, DP_S, DP_T, DP_U, DP_V, DP_W, - // x y z { | } ~ DEL - DP_X, DP_Y, DP_Z, DP_LCBR, DP_BSLS, DP_RCBR, DP_DLR, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_estonian.h b/quantum/keymap_extras/sendstring_estonian.h deleted file mode 100644 index 9ea2ab3f8ffb..000000000000 --- a/quantum/keymap_extras/sendstring_estonian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Estonian layouts - -#pragma once - -#include "keymap_estonian.h" -#include "quantum" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, EE_1, EE_2, EE_3, EE_4, EE_5, EE_6, EE_QUOT, - // ( ) * + , - . / - EE_8, EE_9, EE_QUOT, EE_PLUS, EE_COMM, EE_MINS, EE_DOT, EE_7, - // 0 1 2 3 4 5 6 7 - EE_0, EE_1, EE_2, EE_3, EE_4, EE_5, EE_6, EE_7, - // 8 9 : ; < = > ? - EE_8, EE_9, EE_DOT, EE_COMM, EE_LABK, EE_0, EE_LABK, EE_PLUS, - // @ A B C D E F G - EE_2, EE_A, EE_B, EE_C, EE_D, EE_E, EE_F, EE_G, - // H I J K L M N O - EE_H, EE_I, EE_J, EE_K, EE_L, EE_M, EE_N, EE_O, - // P Q R S T U V W - EE_P, EE_Q, EE_R, EE_S, EE_T, EE_U, EE_V, EE_W, - // X Y Z [ \ ] ^ _ - EE_X, EE_Y, EE_Z, EE_8, EE_PLUS, EE_9, EE_ADIA, EE_MINS, - // ` a b c d e f g - EE_ACUT, EE_A, EE_B, EE_C, EE_D, EE_E, EE_F, EE_G, - // h i j k l m n o - EE_H, EE_I, EE_J, EE_K, EE_L, EE_M, EE_N, EE_O, - // p q r s t u v w - EE_P, EE_Q, EE_R, EE_S, EE_T, EE_U, EE_V, EE_W, - // x y z { | } ~ DEL - EE_X, EE_Y, EE_Z, EE_7, EE_LABK, EE_0, EE_CARN, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_finnish.h b/quantum/keymap_extras/sendstring_finnish.h deleted file mode 100644 index 197836ba83da..000000000000 --- a/quantum/keymap_extras/sendstring_finnish.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Finnish layouts - -#pragma once - -#include "keymap_finnish.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, FI_1, FI_2, FI_3, FI_4, FI_5, FI_6, FI_QUOT, - // ( ) * + , - . / - FI_8, FI_9, FI_QUOT, FI_PLUS, FI_COMM, FI_MINS, FI_DOT, FI_7, - // 0 1 2 3 4 5 6 7 - FI_0, FI_1, FI_2, FI_3, FI_4, FI_5, FI_6, FI_7, - // 8 9 : ; < = > ? - FI_8, FI_9, FI_DOT, FI_COMM, FI_LABK, FI_0, FI_LABK, FI_PLUS, - // @ A B C D E F G - FI_2, FI_A, FI_B, FI_C, FI_D, FI_E, FI_F, FI_G, - // H I J K L M N O - FI_H, FI_I, FI_J, FI_K, FI_L, FI_M, FI_N, FI_O, - // P Q R S T U V W - FI_P, FI_Q, FI_R, FI_S, FI_T, FI_U, FI_V, FI_W, - // X Y Z [ \ ] ^ _ - FI_X, FI_Y, FI_Z, FI_8, FI_PLUS, FI_9, FI_DIAE, FI_MINS, - // ` a b c d e f g - FI_ACUT, FI_A, FI_B, FI_C, FI_D, FI_E, FI_F, FI_G, - // h i j k l m n o - FI_H, FI_I, FI_J, FI_K, FI_L, FI_M, FI_N, FI_O, - // p q r s t u v w - FI_P, FI_Q, FI_R, FI_S, FI_T, FI_U, FI_V, FI_W, - // x y z { | } ~ DEL - FI_X, FI_Y, FI_Z, FI_7, FI_LABK, FI_0, FI_DIAE, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_french.h b/quantum/keymap_extras/sendstring_french.h deleted file mode 100644 index a37a5d314bdc..000000000000 --- a/quantum/keymap_extras/sendstring_french.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -// Sendstring lookup tables for French (AZERTY) layouts - -#pragma once - -#include "keymap_french.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, FR_EXLM, FR_DQUO, FR_DQUO, FR_DLR, FR_UGRV, FR_AMPR, FR_QUOT, - // ( ) * + , - . / - FR_LPRN, FR_RPRN, FR_ASTR, FR_EQL, FR_COMM, FR_MINS, FR_SCLN, FR_COLN, - // 0 1 2 3 4 5 6 7 - FR_AGRV, FR_AMPR, FR_EACU, FR_DQUO, FR_QUOT, FR_LPRN, FR_MINS, FR_EGRV, - // 8 9 : ; < = > ? - FR_UNDS, FR_CCED, FR_COLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_COMM, - // @ A B C D E F G - FR_AGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // H I J K L M N O - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // P Q R S T U V W - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // X Y Z [ \ ] ^ _ - FR_X, FR_Y, FR_Z, FR_LPRN, FR_UNDS, FR_RPRN, FR_CCED, FR_UNDS, - // ` a b c d e f g - FR_EGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // h i j k l m n o - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // p q r s t u v w - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // x y z { | } ~ DEL - FR_X, FR_Y, FR_Z, FR_QUOT, FR_MINS, FR_EQL, FR_EACU, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_french_afnor.h b/quantum/keymap_extras/sendstring_french_afnor.h deleted file mode 100644 index 1408634a266b..000000000000 --- a/quantum/keymap_extras/sendstring_french_afnor.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 Guillaume Gérard - * - * 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 . - */ - -// Sendstring lookup tables for French (AZERTY - AFNOR NF Z71-300) layouts - -#pragma once - -#include "keymap_french_afnor.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 1, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, FR_COMM, FR_QUOT, FR_AT, FR_D, FR_P, FR_ECIR, FR_QUOT, - // ( ) * + , - . / - FR_LPRN, FR_RPRN, FR_ASTR, FR_PLUS, FR_COMM, FR_MINS, FR_DOT, FR_SLSH, - // 0 1 2 3 4 5 6 7 - FR_RDAQ, FR_AGRV, FR_EACU, FR_EGRV, FR_ECIR, FR_LPRN, FR_RPRN, FR_LSQU, - // 8 9 : ; < = > ? - FR_RSQU, FR_LDAQ, FR_COLN, FR_SCLN, FR_LABK, FR_SCLN, FR_LABK, FR_DOT, - // @ A B C D E F G - FR_AT, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // H I J K L M N O - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // P Q R S T U V W - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // X Y Z [ \ ] ^ _ - FR_X, FR_Y, FR_Z, FR_LPRN, FR_SLSH, FR_RPRN, FR_DCIR, FR_RSQU, - // ` a b c d e f g - FR_EGRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // h i j k l m n o - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // p q r s t u v w - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // x y z { | } ~ DEL - FR_X, FR_Y, FR_Z, FR_T, FR_L, FR_Y, FR_N, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_french_mac_iso.h b/quantum/keymap_extras/sendstring_french_mac_iso.h deleted file mode 100644 index 1033c3991fe4..000000000000 --- a/quantum/keymap_extras/sendstring_french_mac_iso.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for macOS French (AZERTY) layouts - -#pragma once - -#include "keymap_french_mac_iso.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, FR_EXLM, FR_DQUO, FR_AT, FR_DLR, FR_LUGR, FR_AMPR, FR_QUOT, - // ( ) * + , - . / - FR_LPRN, FR_RPRN, FR_DLR, FR_EQL, FR_COMM, FR_MINS, FR_SCLN, FR_COLN, - // 0 1 2 3 4 5 6 7 - FR_LAGR, FR_AMPR, FR_LEAC, FR_DQUO, FR_QUOT, FR_LPRN, FR_SECT, FR_LEGR, - // 8 9 : ; < = > ? - FR_EXLM, FR_LCCE, FR_COLN, FR_SCLN, FR_LABK, FR_EQL, FR_LABK, FR_COMM, - // @ A B C D E F G - FR_AT, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // H I J K L M N O - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // P Q R S T U V W - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // X Y Z [ \ ] ^ _ - FR_X, FR_Y, FR_Z, FR_LPRN, FR_COLN, FR_RPRN, FR_CIRC, FR_MINS, - // ` a b c d e f g - FR_GRV, FR_A, FR_B, FR_C, FR_D, FR_E, FR_F, FR_G, - // h i j k l m n o - FR_H, FR_I, FR_J, FR_K, FR_L, FR_M, FR_N, FR_O, - // p q r s t u v w - FR_P, FR_Q, FR_R, FR_S, FR_T, FR_U, FR_V, FR_W, - // x y z { | } ~ DEL - FR_X, FR_Y, FR_Z, FR_LPRN, FR_L, FR_RPRN, FR_N, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_german.h b/quantum/keymap_extras/sendstring_german.h deleted file mode 100644 index 69c7dd996ede..000000000000 --- a/quantum/keymap_extras/sendstring_german.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2018 Patrick Hener - * - * 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 . - */ - -// Sendstring lookup tables for German layouts - -#pragma once - -#include "keymap_german.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DE_1, DE_2, DE_HASH, DE_4, DE_5, DE_6, DE_HASH, - // ( ) * + , - . / - DE_8, DE_9, DE_PLUS, DE_PLUS, DE_COMM, DE_MINS, DE_DOT, DE_7, - // 0 1 2 3 4 5 6 7 - DE_0, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, - // 8 9 : ; < = > ? - DE_8, DE_9, DE_DOT, DE_COMM, DE_LABK, DE_0, DE_LABK, DE_SS, - // @ A B C D E F G - DE_Q, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G, - // H I J K L M N O - DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O, - // P Q R S T U V W - DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W, - // X Y Z [ \ ] ^ _ - DE_X, DE_Y, DE_Z, DE_8, DE_SS, DE_9, DE_CIRC, DE_MINS, - // ` a b c d e f g - DE_ACUT, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G, - // h i j k l m n o - DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O, - // p q r s t u v w - DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W, - // x y z { | } ~ DEL - DE_X, DE_Y, DE_Z, DE_7, DE_LABK, DE_0, DE_PLUS, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_german_mac_iso.h b/quantum/keymap_extras/sendstring_german_mac_iso.h deleted file mode 100644 index 8345dbaaa145..000000000000 --- a/quantum/keymap_extras/sendstring_german_mac_iso.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for macOS German layouts - -#pragma once - -#include "keymap_german_mac_iso.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 1, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DE_1, DE_2, DE_HASH, DE_4, DE_5, DE_6, DE_HASH, - // ( ) * + , - . / - DE_8, DE_9, DE_PLUS, DE_PLUS, DE_COMM, DE_MINS, DE_DOT, DE_7, - // 0 1 2 3 4 5 6 7 - DE_0, DE_1, DE_2, DE_3, DE_4, DE_5, DE_6, DE_7, - // 8 9 : ; < = > ? - DE_8, DE_9, DE_DOT, DE_COMM, DE_LABK, DE_0, DE_LABK, DE_SS, - // @ A B C D E F G - DE_L, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G, - // H I J K L M N O - DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O, - // P Q R S T U V W - DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W, - // X Y Z [ \ ] ^ _ - DE_X, DE_Y, DE_Z, DE_5, DE_7, DE_6, DE_CIRC, DE_MINS, - // ` a b c d e f g - DE_ACUT, DE_A, DE_B, DE_C, DE_D, DE_E, DE_F, DE_G, - // h i j k l m n o - DE_H, DE_I, DE_J, DE_K, DE_L, DE_M, DE_N, DE_O, - // p q r s t u v w - DE_P, DE_Q, DE_R, DE_S, DE_T, DE_U, DE_V, DE_W, - // x y z { | } ~ DEL - DE_X, DE_Y, DE_Z, DE_8, DE_7, DE_9, DE_N, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_hungarian.h b/quantum/keymap_extras/sendstring_hungarian.h deleted file mode 100644 index 9169ba255757..000000000000 --- a/quantum/keymap_extras/sendstring_hungarian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Hungarian layouts - -#pragma once - -#include "keymap_hungarian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 0, 1), - KCLUT_ENTRY(1, 1, 0, 1, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 0, 1, 0, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, HU_4, HU_2, HU_X, HU_EACU, HU_5, HU_C, HU_1, - // ( ) * + , - . / - HU_8, HU_9, HU_MINS, HU_3, HU_COMM, HU_MINS, HU_DOT, HU_6, - // 0 1 2 3 4 5 6 7 - HU_0, HU_1, HU_2, HU_3, HU_4, HU_5, HU_6, HU_7, - // 8 9 : ; < = > ? - HU_8, HU_9, HU_DOT, HU_COMM, HU_M, HU_7, HU_DOT, HU_COMM, - // @ A B C D E F G - HU_V, HU_A, HU_B, HU_C, HU_D, HU_E, HU_F, HU_G, - // H I J K L M N O - HU_H, HU_I, HU_J, HU_K, HU_L, HU_M, HU_N, HU_O, - // P Q R S T U V W - HU_P, HU_Q, HU_R, HU_S, HU_T, HU_U, HU_V, HU_W, - // X Y Z [ \ ] ^ _ - HU_X, HU_Y, HU_Z, HU_F, HU_Q, HU_G, HU_3, HU_MINS, - // ` a b c d e f g - HU_7, HU_A, HU_B, HU_C, HU_D, HU_E, HU_F, HU_G, - // h i j k l m n o - HU_H, HU_I, HU_J, HU_K, HU_L, HU_M, HU_N, HU_O, - // p q r s t u v w - HU_P, HU_Q, HU_R, HU_S, HU_T, HU_U, HU_V, HU_W, - // x y z { | } ~ DEL - HU_X, HU_Y, HU_Z, HU_B, HU_W, HU_N, HU_1, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_icelandic.h b/quantum/keymap_extras/sendstring_icelandic.h deleted file mode 100644 index b25a4e76e7a9..000000000000 --- a/quantum/keymap_extras/sendstring_icelandic.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Icelandic layouts - -#pragma once - -#include "keymap_icelandic.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, IS_1, IS_2, IS_3, IS_4, IS_5, IS_6, IS_QUOT, - // ( ) * + , - . / - IS_8, IS_9, IS_PLUS, IS_PLUS, IS_COMM, IS_MINS, IS_DOT, IS_7, - // 0 1 2 3 4 5 6 7 - IS_0, IS_1, IS_2, IS_3, IS_4, IS_5, IS_6, IS_7, - // 8 9 : ; < = > ? - IS_8, IS_9, IS_DOT, IS_COMM, IS_LABK, IS_0, IS_LABK, IS_QUOT, - // @ A B C D E F G - IS_Q, IS_A, IS_B, IS_C, IS_D, IS_E, IS_F, IS_G, - // H I J K L M N O - IS_H, IS_I, IS_J, IS_K, IS_L, IS_M, IS_N, IS_O, - // P Q R S T U V W - IS_P, IS_Q, IS_R, IS_S, IS_T, IS_U, IS_V, IS_W, - // X Y Z [ \ ] ^ _ - IS_X, IS_Y, IS_Z, IS_8, IS_ODIA, IS_9, IS_ACUT, IS_MINS, - // ` a b c d e f g - IS_PLUS, IS_A, IS_B, IS_C, IS_D, IS_E, IS_F, IS_G, - // h i j k l m n o - IS_H, IS_I, IS_J, IS_K, IS_L, IS_M, IS_N, IS_O, - // p q r s t u v w - IS_P, IS_Q, IS_R, IS_S, IS_T, IS_U, IS_V, IS_W, - // x y z { | } ~ DEL - IS_X, IS_Y, IS_Z, IS_7, IS_LABK, IS_0, IS_QUOT, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_italian.h b/quantum/keymap_extras/sendstring_italian.h deleted file mode 100644 index dad4902d34de..000000000000 --- a/quantum/keymap_extras/sendstring_italian.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Italian layouts - -#pragma once - -#include "keymap_italian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, IT_1, IT_2, IT_AGRV, IT_4, IT_5, IT_6, IT_QUOT, - // ( ) * + , - . / - IT_8, IT_9, IT_PLUS, IT_PLUS, IT_COMM, IT_MINS, IT_DOT, IT_7, - // 0 1 2 3 4 5 6 7 - IT_0, IT_1, IT_2, IT_3, IT_4, IT_5, IT_6, IT_7, - // 8 9 : ; < = > ? - IT_8, IT_9, IT_DOT, IT_COMM, IT_LABK, IT_0, IT_LABK, IT_QUOT, - // @ A B C D E F G - IT_OGRV, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // H I J K L M N O - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // P Q R S T U V W - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // X Y Z [ \ ] ^ _ - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_IGRV, IT_MINS, - // ` a b c d e f g - XXXXXXX, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // h i j k l m n o - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // p q r s t u v w - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // x y z { | } ~ DEL - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, XXXXXXX, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_italian_mac_ansi.h b/quantum/keymap_extras/sendstring_italian_mac_ansi.h deleted file mode 100644 index 97b5164e23b3..000000000000 --- a/quantum/keymap_extras/sendstring_italian_mac_ansi.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for macOS Italian ANSI layouts - -#pragma once - -#include "keymap_italian_mac_ansi.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, IT_1, IT_2, IT_AGRV, IT_4, IT_5, IT_6, IT_QUOT, - // ( ) * + , - . / - IT_8, IT_9, IT_PLUS, IT_PLUS, IT_COMM, IT_MINS, IT_DOT, IT_7, - // 0 1 2 3 4 5 6 7 - IT_0, IT_1, IT_2, IT_3, IT_4, IT_5, IT_6, IT_7, - // 8 9 : ; < = > ? - IT_8, IT_9, IT_DOT, IT_COMM, IT_LABK, IT_0, IT_LABK, IT_QUOT, - // @ A B C D E F G - IT_OGRV, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // H I J K L M N O - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // P Q R S T U V W - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // X Y Z [ \ ] ^ _ - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_IGRV, IT_MINS, - // ` a b c d e f g - IT_BSLS, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // h i j k l m n o - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // p q r s t u v w - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // x y z { | } ~ DEL - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_5, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_italian_mac_iso.h b/quantum/keymap_extras/sendstring_italian_mac_iso.h deleted file mode 100644 index d82e8bbddf1f..000000000000 --- a/quantum/keymap_extras/sendstring_italian_mac_iso.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for macOS Italian ISO layouts - -#pragma once - -#include "keymap_italian_mac_iso.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, IT_1, IT_2, IT_AGRV, IT_4, IT_5, IT_6, IT_QUOT, - // ( ) * + , - . / - IT_8, IT_9, IT_PLUS, IT_PLUS, IT_COMM, IT_MINS, IT_DOT, IT_7, - // 0 1 2 3 4 5 6 7 - IT_0, IT_1, IT_2, IT_3, IT_4, IT_5, IT_6, IT_7, - // 8 9 : ; < = > ? - IT_8, IT_9, IT_DOT, IT_COMM, IT_LABK, IT_0, IT_LABK, IT_QUOT, - // @ A B C D E F G - IT_OGRV, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // H I J K L M N O - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // P Q R S T U V W - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // X Y Z [ \ ] ^ _ - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_IGRV, IT_MINS, - // ` a b c d e f g - IT_BSLS, IT_A, IT_B, IT_C, IT_D, IT_E, IT_F, IT_G, - // h i j k l m n o - IT_H, IT_I, IT_J, IT_K, IT_L, IT_M, IT_N, IT_O, - // p q r s t u v w - IT_P, IT_Q, IT_R, IT_S, IT_T, IT_U, IT_V, IT_W, - // x y z { | } ~ DEL - IT_X, IT_Y, IT_Z, IT_EGRV, IT_BSLS, IT_PLUS, IT_5, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_japanese.h b/quantum/keymap_extras/sendstring_japanese.h deleted file mode 100644 index 13628d702388..000000000000 --- a/quantum/keymap_extras/sendstring_japanese.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -// Sendstring lookup tables for JIS layouts - -#pragma once - -#include "keymap_japanese.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, - // ( ) * + , - . / - KC_8, KC_9, JP_COLN, JP_SCLN, JP_COMM, JP_MINS, JP_DOT, JP_SLSH, - // 0 1 2 3 4 5 6 7 - KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, - // 8 9 : ; < = > ? - KC_8, KC_9, JP_COLN, JP_SCLN, JP_COMM, JP_MINS, JP_DOT, JP_SLSH, - // @ A B C D E F G - JP_AT, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, - // H I J K L M N O - KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, - // P Q R S T U V W - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, - // X Y Z [ \ ] ^ _ - KC_X, KC_Y, KC_Z, JP_LBRC, JP_BSLS, JP_RBRC, JP_CIRC, JP_BSLS, - // ` a b c d e f g - JP_AT, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, - // h i j k l m n o - KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, - // p q r s t u v w - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, - // x y z { | } ~ DEL - KC_X, KC_Y, KC_Z, JP_LBRC, JP_YEN, JP_RBRC, JP_CIRC, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_latvian.h b/quantum/keymap_extras/sendstring_latvian.h deleted file mode 100644 index bd73a01e4843..000000000000 --- a/quantum/keymap_extras/sendstring_latvian.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Latvian layouts - -#pragma once - -#include "keymap_latvian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, LV_1, LV_QUOT, LV_3, LV_4, LV_5, LV_7, LV_QUOT, - // ( ) * + , - . / - LV_9, LV_0, LV_8, LV_EQL, LV_COMM, LV_MINS, LV_DOT, LV_SLSH, - // 0 1 2 3 4 5 6 7 - LV_0, LV_1, LV_2, LV_3, LV_4, LV_5, LV_6, LV_7, - // 8 9 : ; < = > ? - LV_8, LV_9, LV_SCLN, LV_SCLN, LV_COMM, LV_EQL, LV_DOT, LV_SLSH, - // @ A B C D E F G - LV_2, LV_A, LV_B, LV_C, LV_D, LV_E, LV_F, LV_G, - // H I J K L M N O - LV_H, LV_I, LV_J, LV_K, LV_L, LV_M, LV_N, LV_O, - // P Q R S T U V W - LV_P, LV_Q, LV_R, LV_S, LV_T, LV_U, LV_V, LV_W, - // X Y Z [ \ ] ^ _ - LV_X, LV_Y, LV_Z, LV_LBRC, LV_BSLS, LV_RBRC, LV_6, LV_MINS, - // ` a b c d e f g - LV_GRV, LV_A, LV_B, LV_C, LV_D, LV_E, LV_F, LV_G, - // h i j k l m n o - LV_H, LV_I, LV_J, LV_K, LV_L, LV_M, LV_N, LV_O, - // p q r s t u v w - LV_P, LV_Q, LV_R, LV_S, LV_T, LV_U, LV_V, LV_W, - // x y z { | } ~ DEL - LV_X, LV_Y, LV_Z, LV_LBRC, LV_BSLS, LV_RBRC, LV_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_lithuanian_azerty.h b/quantum/keymap_extras/sendstring_lithuanian_azerty.h deleted file mode 100644 index a886411143e5..000000000000 --- a/quantum/keymap_extras/sendstring_lithuanian_azerty.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Lithuanian ĄŽERTY layouts - -#pragma once - -#include "keymap_lithuanian_azerty.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, LT_EXLM, LT_EDOT, LT_SLSH, LT_SCLN, LT_X, LT_DOT, LT_QUES, - // ( ) * + , - . / - LT_LPRN, LT_RPRN, LT_EQL, LT_QUES, LT_COMM, LT_MINS, LT_DOT, LT_SLSH, - // 0 1 2 3 4 5 6 7 - LT_RPRN, LT_EXLM, LT_MINS, LT_SLSH, LT_SCLN, LT_COLN, LT_COMM, LT_DOT, - // 8 9 : ; < = > ? - LT_EQL, LT_LPRN, LT_COLN, LT_SCLN, LT_LABK, LT_EQL, LT_LABK, LT_QUES, - // @ A B C D E F G - LT_EXLM, LT_A, LT_B, LT_C, LT_D, LT_E, LT_F, LT_G, - // H I J K L M N O - LT_H, LT_I, LT_J, LT_K, LT_L, LT_M, LT_N, LT_O, - // P Q R S T U V W - LT_P, LT_Q, LT_R, LT_S, LT_T, LT_U, LT_V, LT_W, - // X Y Z [ \ ] ^ _ - LT_X, LT_Y, LT_Z, LT_LPRN, LT_EOGO, LT_RPRN, LT_COMM, LT_MINS, - // ` a b c d e f g - LT_GRV, LT_A, LT_B, LT_C, LT_D, LT_E, LT_F, LT_G, - // h i j k l m n o - LT_H, LT_I, LT_J, LT_K, LT_L, LT_M, LT_N, LT_O, - // p q r s t u v w - LT_P, LT_Q, LT_R, LT_S, LT_T, LT_U, LT_V, LT_W, - // x y z { | } ~ DEL - LT_X, LT_Y, LT_Z, LT_IOGO, LT_Q, LT_W, LT_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_lithuanian_qwerty.h b/quantum/keymap_extras/sendstring_lithuanian_qwerty.h deleted file mode 100644 index 69cb94de7135..000000000000 --- a/quantum/keymap_extras/sendstring_lithuanian_qwerty.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Lithuanian QWERTY layouts - -#pragma once - -#include "keymap_lithuanian_qwerty.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, LT_1, LT_QUOT, LT_3, LT_4, LT_5, LT_7, LT_QUOT, - // ( ) * + , - . / - LT_9, LT_0, LT_8, LT_ZCAR, LT_COMM, LT_MINS, LT_DOT, LT_SLSH, - // 0 1 2 3 4 5 6 7 - LT_0, LT_AOGO, LT_CCAR, LT_EOGO, LT_EDOT, LT_IOGO, LT_SCAR, LT_UOGO, - // 8 9 : ; < = > ? - LT_UMAC, LT_9, LT_SCLN, LT_SCLN, LT_COMM, LT_PLUS, LT_DOT, LT_SLSH, - // @ A B C D E F G - LT_CCAR, LT_A, LT_B, LT_C, LT_D, LT_E, LT_F, LT_G, - // H I J K L M N O - LT_H, LT_I, LT_J, LT_K, LT_L, LT_M, LT_N, LT_O, - // P Q R S T U V W - LT_P, LT_Q, LT_R, LT_S, LT_T, LT_U, LT_V, LT_W, - // X Y Z [ \ ] ^ _ - LT_X, LT_Y, LT_Z, LT_LBRC, LT_BSLS, LT_RBRC, LT_SCAR, LT_MINS, - // ` a b c d e f g - LT_GRV, LT_A, LT_B, LT_C, LT_D, LT_E, LT_F, LT_G, - // h i j k l m n o - LT_H, LT_I, LT_J, LT_K, LT_L, LT_M, LT_N, LT_O, - // p q r s t u v w - LT_P, LT_Q, LT_R, LT_S, LT_T, LT_U, LT_V, LT_W, - // x y z { | } ~ DEL - LT_X, LT_Y, LT_Z, LT_LBRC, LT_BSLS, LT_RBRC, LT_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_norman.h b/quantum/keymap_extras/sendstring_norman.h deleted file mode 100644 index 21dbbdd7054d..000000000000 --- a/quantum/keymap_extras/sendstring_norman.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2019 Torben Hoffmann - * - * 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 . - */ - -// Sendstring lookup tables for Norman layouts - -#pragma once - -#include "keymap_norman.h" - -// clang-format off - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, NM_1, NM_QUOT, NM_3, NM_4, NM_5, NM_7, NM_QUOT, - // ( ) * + , - . / - NM_9, NM_0, NM_8, NM_EQL, NM_COMM, NM_MINS, NM_DOT, NM_SLSH, - // 0 1 2 3 4 5 6 7 - NM_0, NM_1, NM_2, NM_3, NM_4, NM_5, NM_6, NM_7, - // 8 9 : ; < = > ? - NM_8, NM_9, NM_SCLN, NM_SCLN, NM_COMM, NM_EQL, NM_DOT, NM_SLSH, - // @ A B C D E F G - NM_2, NM_A, NM_B, NM_C, NM_D, NM_E, NM_F, NM_G, - // H I J K L M N O - NM_H, NM_I, NM_J, NM_K, NM_L, NM_M, NM_N, NM_O, - // P Q R S T U V W - NM_P, NM_Q, NM_R, NM_S, NM_T, NM_U, NM_V, NM_W, - // X Y Z [ \ ] ^ _ - NM_X, NM_Y, NM_Z, NM_LBRC, NM_BSLS, NM_RBRC, NM_6, NM_MINS, - // ` a b c d e f g - NM_GRV, NM_A, NM_B, NM_C, NM_D, NM_E, NM_F, NM_G, - // h i j k l m n o - NM_H, NM_I, NM_J, NM_K, NM_L, NM_M, NM_N, NM_O, - // p q r s t u v w - NM_P, NM_Q, NM_R, NM_S, NM_T, NM_U, NM_V, NM_W, - // x y z { | } ~ DEL - NM_X, NM_Y, NM_Z, NM_LBRC, NM_BSLS, NM_RBRC, NM_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_norwegian.h b/quantum/keymap_extras/sendstring_norwegian.h deleted file mode 100644 index 28813da51f46..000000000000 --- a/quantum/keymap_extras/sendstring_norwegian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Norwegian layouts - -#pragma once - -#include "keymap_norwegian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, NO_1, NO_2, NO_3, NO_4, NO_5, NO_6, NO_QUOT, - // ( ) * + , - . / - NO_8, NO_9, NO_QUOT, NO_PLUS, NO_COMM, NO_MINS, NO_DOT, NO_7, - // 0 1 2 3 4 5 6 7 - NO_0, NO_1, NO_2, NO_3, NO_4, NO_5, NO_6, NO_7, - // 8 9 : ; < = > ? - NO_8, NO_9, NO_DOT, NO_COMM, NO_LABK, NO_0, NO_LABK, NO_PLUS, - // @ A B C D E F G - NO_2, NO_A, NO_B, NO_C, NO_D, NO_E, NO_F, NO_G, - // H I J K L M N O - NO_H, NO_I, NO_J, NO_K, NO_L, NO_M, NO_N, NO_O, - // P Q R S T U V W - NO_P, NO_Q, NO_R, NO_S, NO_T, NO_U, NO_V, NO_W, - // X Y Z [ \ ] ^ _ - NO_X, NO_Y, NO_Z, NO_8, NO_BSLS, NO_9, NO_DIAE, NO_MINS, - // ` a b c d e f g - NO_BSLS, NO_A, NO_B, NO_C, NO_D, NO_E, NO_F, NO_G, - // h i j k l m n o - NO_H, NO_I, NO_J, NO_K, NO_L, NO_M, NO_N, NO_O, - // p q r s t u v w - NO_P, NO_Q, NO_R, NO_S, NO_T, NO_U, NO_V, NO_W, - // x y z { | } ~ DEL - NO_X, NO_Y, NO_Z, NO_7, NO_PIPE, NO_0, NO_DIAE, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_portuguese.h b/quantum/keymap_extras/sendstring_portuguese.h deleted file mode 100644 index 37db5f97aab9..000000000000 --- a/quantum/keymap_extras/sendstring_portuguese.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Portuguese layouts - -#pragma once - -#include "keymap_portuguese.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_QUOT, - // ( ) * + , - . / - PT_8, PT_9, PT_PLUS, PT_PLUS, PT_COMM, PT_MINS, PT_DOT, PT_7, - // 0 1 2 3 4 5 6 7 - PT_0, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_7, - // 8 9 : ; < = > ? - PT_8, PT_9, PT_DOT, PT_COMM, PT_LABK, PT_0, PT_LABK, PT_QUOT, - // @ A B C D E F G - PT_2, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G, - // H I J K L M N O - PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O, - // P Q R S T U V W - PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W, - // X Y Z [ \ ] ^ _ - PT_X, PT_Y, PT_Z, PT_8, PT_BSLS, PT_9, PT_TILD, PT_MINS, - // ` a b c d e f g - PT_ACUT, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G, - // h i j k l m n o - PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O, - // p q r s t u v w - PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W, - // x y z { | } ~ DEL - PT_X, PT_Y, PT_Z, PT_7, PT_BSLS, PT_0, PT_TILD, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_portuguese_mac_iso.h b/quantum/keymap_extras/sendstring_portuguese_mac_iso.h deleted file mode 100644 index 5d43c66279be..000000000000 --- a/quantum/keymap_extras/sendstring_portuguese_mac_iso.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Portuguese layouts - -#pragma once - -#include "keymap_portuguese_mac_iso.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 0, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_QUOT, - // ( ) * + , - . / - PT_8, PT_9, PT_PLUS, PT_PLUS, PT_COMM, PT_MINS, PT_DOT, PT_7, - // 0 1 2 3 4 5 6 7 - PT_0, PT_1, PT_2, PT_3, PT_4, PT_5, PT_6, PT_7, - // 8 9 : ; < = > ? - PT_8, PT_9, PT_DOT, PT_COMM, PT_LABK, PT_0, PT_LABK, PT_QUOT, - // @ A B C D E F G - PT_2, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G, - // H I J K L M N O - PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O, - // P Q R S T U V W - PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W, - // X Y Z [ \ ] ^ _ - PT_X, PT_Y, PT_Z, PT_8, PT_BSLS, PT_9, PT_TILD, PT_MINS, - // ` a b c d e f g - PT_ACUT, PT_A, PT_B, PT_C, PT_D, PT_E, PT_F, PT_G, - // h i j k l m n o - PT_H, PT_I, PT_J, PT_K, PT_L, PT_M, PT_N, PT_O, - // p q r s t u v w - PT_P, PT_Q, PT_R, PT_S, PT_T, PT_U, PT_V, PT_W, - // x y z { | } ~ DEL - PT_X, PT_Y, PT_Z, PT_8, PT_BSLS, PT_9, PT_TILD, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_romanian.h b/quantum/keymap_extras/sendstring_romanian.h deleted file mode 100644 index 9b5bee4a13e6..000000000000 --- a/quantum/keymap_extras/sendstring_romanian.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Romanian layouts - -#pragma once - -#include "keymap_romanian.h" -#include "quantum" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 0, 0, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 0, 1, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, RO_1, RO_TCOM, RO_3, RO_4, RO_5, RO_7, RO_TCOM, - // ( ) * + , - . / - RO_9, RO_0, RO_8, RO_EQL, RO_COMM, RO_MINS, RO_DOT, RO_SLSH, - // 0 1 2 3 4 5 6 7 - RO_0, RO_1, RO_2, RO_3, RO_4, RO_5, RO_6, RO_7, - // 8 9 : ; < = > ? - RO_8, RO_9, RO_DOT, RO_COMM, RO_COMM, RO_EQL, RO_DOT, RO_SLSH, - // @ A B C D E F G - RO_2, RO_A, RO_B, RO_C, RO_D, RO_E, RO_F, RO_G, - // H I J K L M N O - RO_H, RO_I, RO_J, RO_K, RO_L, RO_M, RO_N, RO_O, - // P Q R S T U V W - RO_P, RO_Q, RO_R, RO_S, RO_T, RO_U, RO_V, RO_W, - // X Y Z [ \ ] ^ _ - RO_X, RO_Y, RO_Z, RO_ABRV, RO_BSLS, RO_ICIR, RO_6, RO_MINS, - // ` a b c d e f g - RO_DLQU, RO_A, RO_B, RO_C, RO_D, RO_E, RO_F, RO_G, - // h i j k l m n o - RO_H, RO_I, RO_J, RO_K, RO_L, RO_M, RO_N, RO_O, - // p q r s t u v w - RO_P, RO_Q, RO_R, RO_S, RO_T, RO_U, RO_V, RO_W, - // x y z { | } ~ DEL - RO_X, RO_Y, RO_Z, RO_ABRV, RO_BSLS, RO_ICIR, RO_DLQU, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_serbian_latin.h b/quantum/keymap_extras/sendstring_serbian_latin.h deleted file mode 100644 index 7e19a62595c2..000000000000 --- a/quantum/keymap_extras/sendstring_serbian_latin.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Serbian (Latin) layouts - -#pragma once - -#include "keymap_serbian_latin.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, RS_1, RS_2, RS_3, RS_4, RS_5, RS_6, RS_QUOT, - // ( ) * + , - . / - RS_8, RS_9, RS_PLUS, RS_PLUS, RS_COMM, RS_MINS, RS_DOT, RS_7, - // 0 1 2 3 4 5 6 7 - RS_0, RS_1, RS_2, RS_3, RS_4, RS_5, RS_6, RS_7, - // 8 9 : ; < = > ? - RS_8, RS_9, RS_DOT, RS_COMM, RS_LABK, RS_0, RS_LABK, RS_QUOT, - // @ A B C D E F G - RS_V, RS_A, RS_B, RS_C, RS_D, RS_E, RS_F, RS_G, - // H I J K L M N O - RS_H, RS_I, RS_J, RS_K, RS_L, RS_M, RS_N, RS_O, - // P Q R S T U V W - RS_P, RS_Q, RS_R, RS_S, RS_T, RS_U, RS_V, RS_W, - // X Y Z [ \ ] ^ _ - RS_X, RS_Y, RS_Z, RS_F, RS_Q, RS_G, RS_3, RS_MINS, - // ` a b c d e f g - RS_7, RS_A, RS_B, RS_C, RS_D, RS_E, RS_F, RS_G, - // h i j k l m n o - RS_H, RS_I, RS_J, RS_K, RS_L, RS_M, RS_N, RS_O, - // p q r s t u v w - RS_P, RS_Q, RS_R, RS_S, RS_T, RS_U, RS_V, RS_W, - // x y z { | } ~ DEL - RS_X, RS_Y, RS_Z, RS_B, RS_W, RS_N, RS_1, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_slovak.h b/quantum/keymap_extras/sendstring_slovak.h deleted file mode 100644 index c94cca1379fc..000000000000 --- a/quantum/keymap_extras/sendstring_slovak.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Slovak layouts - -#pragma once - -#include "keymap_slovak.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, SK_SECT, SK_OCIR, SK_X, SK_OCIR, SK_EQL, SK_AMPR, SK_P, - // ( ) * + , - . / - SK_ADIA, SK_NCAR, SK_AMPR, SK_PLUS, SK_COMM, SK_MINS, SK_DOT, SK_UACU, - // 0 1 2 3 4 5 6 7 - SK_EACU, SK_PLUS, SK_LCAR, SK_SCAR, SK_CCAR, SK_TCAR, SK_ZCAR, SK_YACU, - // 8 9 : ; < = > ? - SK_AACU, SK_IACU, SK_DOT, SK_SCLN, SK_AMPR, SK_EQL, SK_Y, SK_COMM, - // @ A B C D E F G - SK_V, SK_A, SK_B, SK_C, SK_D, SK_E, SK_F, SK_G, - // H I J K L M N O - SK_H, SK_I, SK_J, SK_K, SK_L, SK_M, SK_N, SK_O, - // P Q R S T U V W - SK_P, SK_Q, SK_R, SK_S, SK_T, SK_U, SK_V, SK_W, - // X Y Z [ \ ] ^ _ - SK_X, SK_Y, SK_Z, SK_F, SK_Q, SK_G, SK_3, SK_MINS, - // ` a b c d e f g - SK_7, SK_A, SK_B, SK_C, SK_D, SK_E, SK_F, SK_G, - // h i j k l m n o - SK_H, SK_I, SK_J, SK_K, SK_L, SK_M, SK_N, SK_O, - // p q r s t u v w - SK_P, SK_Q, SK_R, SK_S, SK_T, SK_U, SK_V, SK_W, - // x y z { | } ~ DEL - SK_X, SK_Y, SK_Z, SK_B, SK_W, SK_N, SK_1, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_slovenian.h b/quantum/keymap_extras/sendstring_slovenian.h deleted file mode 100644 index 117af7e76d69..000000000000 --- a/quantum/keymap_extras/sendstring_slovenian.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Slovenian layouts - -#pragma once - -#include "keymap_slovenian.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, SI_1, SI_2, SI_3, SI_4, SI_5, SI_6, SI_QUOT, - // ( ) * + , - . / - SI_8, SI_9, SI_PLUS, SI_PLUS, SI_COMM, SI_MINS, SI_DOT, SI_7, - // 0 1 2 3 4 5 6 7 - SI_0, SI_1, SI_2, SI_3, SI_4, SI_5, SI_6, SI_7, - // 8 9 : ; < = > ? - SI_8, SI_9, SI_DOT, SI_COMM, SI_LABK, SI_0, SI_LABK, SI_QUOT, - // @ A B C D E F G - SI_V, SI_A, SI_B, SI_C, SI_D, SI_E, SI_F, SI_G, - // H I J K L M N O - SI_H, SI_I, SI_J, SI_K, SI_L, SI_M, SI_N, SI_O, - // P Q R S T U V W - SI_P, SI_Q, SI_R, SI_S, SI_T, SI_U, SI_V, SI_W, - // X Y Z [ \ ] ^ _ - SI_X, SI_Y, SI_Z, SI_F, SI_Q, SI_G, SI_3, SI_MINS, - // ` a b c d e f g - SI_7, SI_A, SI_B, SI_C, SI_D, SI_E, SI_F, SI_G, - // h i j k l m n o - SI_H, SI_I, SI_J, SI_K, SI_L, SI_M, SI_N, SI_O, - // p q r s t u v w - SI_P, SI_Q, SI_R, SI_S, SI_T, SI_U, SI_V, SI_W, - // x y z { | } ~ DEL - SI_X, SI_Y, SI_Z, SI_B, SI_W, SI_N, SI_1, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_spanish.h b/quantum/keymap_extras/sendstring_spanish.h deleted file mode 100644 index 680e99ef4efb..000000000000 --- a/quantum/keymap_extras/sendstring_spanish.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2018 Daniel Rodríguez - * - * 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 . - */ - -// Sendstring lookup tables for Spanish layouts - -#pragma once - -#include "keymap_spanish.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_QUOT, - // ( ) * + , - . / - ES_8, ES_9, ES_PLUS, ES_PLUS, ES_COMM, ES_MINS, ES_DOT, ES_7, - // 0 1 2 3 4 5 6 7 - ES_0, ES_1, ES_2, ES_3, ES_4, ES_5, ES_6, ES_7, - // 8 9 : ; < = > ? - ES_8, ES_9, ES_DOT, ES_COMM, ES_LABK, ES_0, ES_LABK, ES_QUOT, - // @ A B C D E F G - ES_2, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G, - // H I J K L M N O - ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O, - // P Q R S T U V W - ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W, - // X Y Z [ \ ] ^ _ - ES_X, ES_Y, ES_Z, ES_GRV, ES_MORD, ES_PLUS, ES_GRV, ES_MINS, - // ` a b c d e f g - ES_GRV, ES_A, ES_B, ES_C, ES_D, ES_E, ES_F, ES_G, - // h i j k l m n o - ES_H, ES_I, ES_J, ES_K, ES_L, ES_M, ES_N, ES_O, - // p q r s t u v w - ES_P, ES_Q, ES_R, ES_S, ES_T, ES_U, ES_V, ES_W, - // x y z { | } ~ DEL - ES_X, ES_Y, ES_Z, ES_ACUT, ES_1, ES_CCED, ES_4, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_spanish_dvorak.h b/quantum/keymap_extras/sendstring_spanish_dvorak.h deleted file mode 100644 index ccf945824732..000000000000 --- a/quantum/keymap_extras/sendstring_spanish_dvorak.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 José Andrés García - * - * 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 . - */ - -// Sendstring lookup tables for Spanish Dvorak layout - -#pragma once - -#include "keymap_spanish_dvorak.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_QUOT, - // ( ) * + , - . / - DV_8, DV_9, DV_PLUS, DV_PLUS, DV_COMM, DV_MINS, DV_DOT, DV_7, - // 0 1 2 3 4 5 6 7 - DV_0, DV_1, DV_2, DV_3, DV_4, DV_5, DV_6, DV_7, - // 8 9 : ; < = > ? - DV_8, DV_9, DV_DOT, DV_COMM, DV_LABK, DV_0, DV_LABK, DV_QUOT, - // @ A B C D E F G - DV_2, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // H I J K L M N O - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // P Q R S T U V W - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // X Y Z [ \ ] ^ _ - DV_X, DV_Y, DV_Z, DV_GRV, DV_MORD, DV_PLUS, DV_GRV, DV_MINS, - // ` a b c d e f g - DV_GRV, DV_A, DV_B, DV_C, DV_D, DV_E, DV_F, DV_G, - // h i j k l m n o - DV_H, DV_I, DV_J, DV_K, DV_L, DV_M, DV_N, DV_O, - // p q r s t u v w - DV_P, DV_Q, DV_R, DV_S, DV_T, DV_U, DV_V, DV_W, - // x y z { | } ~ DEL - DV_X, DV_Y, DV_Z, DV_ACUT, DV_1, DV_CCED, DV_4, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_swedish.h b/quantum/keymap_extras/sendstring_swedish.h deleted file mode 100644 index d4513429927b..000000000000 --- a/quantum/keymap_extras/sendstring_swedish.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Swedish layouts - -#pragma once - -#include "keymap_swedish.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, SE_1, SE_2, SE_3, SE_4, SE_5, SE_6, SE_QUOT, - // ( ) * + , - . / - SE_8, SE_9, SE_QUOT, SE_PLUS, SE_COMM, SE_MINS, SE_DOT, SE_7, - // 0 1 2 3 4 5 6 7 - SE_0, SE_1, SE_2, SE_3, SE_4, SE_5, SE_6, SE_7, - // 8 9 : ; < = > ? - SE_8, SE_9, SE_DOT, SE_COMM, SE_LABK, SE_0, SE_LABK, SE_PLUS, - // @ A B C D E F G - SE_2, SE_A, SE_B, SE_C, SE_D, SE_E, SE_F, SE_G, - // H I J K L M N O - SE_H, SE_I, SE_J, SE_K, SE_L, SE_M, SE_N, SE_O, - // P Q R S T U V W - SE_P, SE_Q, SE_R, SE_S, SE_T, SE_U, SE_V, SE_W, - // X Y Z [ \ ] ^ _ - SE_X, SE_Y, SE_Z, SE_8, SE_PLUS, SE_9, SE_DIAE, SE_MINS, - // ` a b c d e f g - SE_ACUT, SE_A, SE_B, SE_C, SE_D, SE_E, SE_F, SE_G, - // h i j k l m n o - SE_H, SE_I, SE_J, SE_K, SE_L, SE_M, SE_N, SE_O, - // p q r s t u v w - SE_P, SE_Q, SE_R, SE_S, SE_T, SE_U, SE_V, SE_W, - // x y z { | } ~ DEL - SE_X, SE_Y, SE_Z, SE_7, SE_LABK, SE_0, SE_DIAE, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_swiss_de.h b/quantum/keymap_extras/sendstring_swiss_de.h deleted file mode 100644 index f6aa19210c63..000000000000 --- a/quantum/keymap_extras/sendstring_swiss_de.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Swiss German layouts - -#pragma once - -#include "keymap_swiss_de.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, CH_DIAE, CH_2, CH_3, CH_DLR, CH_5, CH_6, CH_QUOT, - // ( ) * + , - . / - CH_8, CH_9, CH_3, CH_1, CH_COMM, CH_MINS, CH_DOT, CH_7, - // 0 1 2 3 4 5 6 7 - CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7, - // 8 9 : ; < = > ? - CH_8, CH_9, CH_DOT, CH_COMM, CH_LABK, CH_0, CH_LABK, CH_QUOT, - // @ A B C D E F G - CH_2, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G, - // H I J K L M N O - CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O, - // P Q R S T U V W - CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W, - // X Y Z [ \ ] ^ _ - CH_X, CH_Y, CH_Z, CH_UDIA, CH_LABK, CH_DIAE, CH_CIRC, CH_MINS, - // ` a b c d e f g - CH_CIRC, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G, - // h i j k l m n o - CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O, - // p q r s t u v w - CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W, - // x y z { | } ~ DEL - CH_X, CH_Y, CH_Z, CH_ADIA, CH_7, CH_DLR, CH_CIRC, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_swiss_fr.h b/quantum/keymap_extras/sendstring_swiss_fr.h deleted file mode 100644 index 7d04cc539a9c..000000000000 --- a/quantum/keymap_extras/sendstring_swiss_fr.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ - -// Sendstring lookup tables for Swiss French layouts - -#pragma once - -#include "keymap_swiss_fr.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 0, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, CH_DIAE, CH_2, CH_3, CH_DLR, CH_5, CH_6, CH_QUOT, - // ( ) * + , - . / - CH_8, CH_9, CH_3, CH_0, CH_COMM, CH_MINS, CH_DOT, CH_7, - // 0 1 2 3 4 5 6 7 - CH_0, CH_1, CH_2, CH_3, CH_4, CH_5, CH_6, CH_7, - // 8 9 : ; < = > ? - CH_8, CH_9, CH_DOT, CH_COMM, CH_LABK, CH_0, CH_LABK, CH_QUOT, - // @ A B C D E F G - CH_2, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G, - // H I J K L M N O - CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O, - // P Q R S T U V W - CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W, - // X Y Z [ \ ] ^ _ - CH_X, CH_Y, CH_Z, CH_EGRV, CH_LABK, CH_DIAE, CH_CIRC, CH_MINS, - // ` a b c d e f g - CH_CIRC, CH_A, CH_B, CH_C, CH_D, CH_E, CH_F, CH_G, - // h i j k l m n o - CH_H, CH_I, CH_J, CH_K, CH_L, CH_M, CH_N, CH_O, - // p q r s t u v w - CH_P, CH_Q, CH_R, CH_S, CH_T, CH_U, CH_V, CH_W, - // x y z { | } ~ DEL - CH_X, CH_Y, CH_Z, CH_AGRV, CH_7, CH_DLR, CH_CIRC, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_turkish_f.h b/quantum/keymap_extras/sendstring_turkish_f.h deleted file mode 100644 index cabd5c5dc5c0..000000000000 --- a/quantum/keymap_extras/sendstring_turkish_f.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Turkish F layouts - -#pragma once - -#include "keymap_turkish_f.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, TR_1, TR_2, TR_3, TR_4, TR_5, TR_6, TR_7, - // ( ) * + , - . / - TR_8, TR_9, TR_PLUS, TR_PLUS, TR_COMM, TR_MINS, TR_DOT, TR_SLSH, - // 0 1 2 3 4 5 6 7 - TR_0, TR_1, TR_2, TR_3, TR_4, TR_5, TR_6, TR_7, - // 8 9 : ; < = > ? - TR_8, TR_9, TR_DOT, TR_COMM, TR_LABK, TR_0, TR_LABK, TR_SLSH, - // @ A B C D E F G - TR_F, TR_A, TR_B, TR_C, TR_D, TR_E, TR_F, TR_G, - // H I J K L M N O - TR_H, TR_I, TR_J, TR_K, TR_L, TR_M, TR_N, TR_O, - // P Q R S T U V W - TR_P, TR_Q, TR_R, TR_S, TR_T, TR_U, TR_V, TR_W, - // X Y Z [ \ ] ^ _ - TR_X, TR_Y, TR_Z, TR_8, TR_SLSH, TR_9, TR_3, TR_MINS, - // ` a b c d e f g - TR_X, TR_A, TR_B, TR_C, TR_D, TR_E, TR_F, TR_G, - // h i j k l m n o - TR_H, TR_I, TR_J, TR_K, TR_L, TR_M, TR_N, TR_O, - // p q r s t u v w - TR_P, TR_Q, TR_R, TR_S, TR_T, TR_U, TR_V, TR_W, - // x y z { | } ~ DEL - TR_X, TR_Y, TR_Z, TR_7, TR_MINS, TR_0, TR_W, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_turkish_q.h b/quantum/keymap_extras/sendstring_turkish_q.h deleted file mode 100644 index 986f02233339..000000000000 --- a/quantum/keymap_extras/sendstring_turkish_q.h +++ /dev/null @@ -1,120 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -// Sendstring lookup tables for Turkish Q layouts - -#pragma once - -#include "keymap_turkish_q.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 0, 0, 0, 1, 1, 1), - KCLUT_ENTRY(1, 1, 0, 1, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 1, 0, 1, 1, 1), - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 1, 1, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 0, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, TR_1, TR_DQUO, TR_3, TR_4, TR_5, TR_6, TR_2, - // ( ) * + , - . / - TR_8, TR_9, TR_ASTR, TR_4, TR_COMM, TR_MINS, TR_DOT, TR_7, - // 0 1 2 3 4 5 6 7 - TR_0, TR_1, TR_2, TR_3, TR_4, TR_5, TR_6, TR_7, - // 8 9 : ; < = > ? - TR_8, TR_9, TR_DOT, TR_COMM, TR_LABK, TR_0, TR_LABK, TR_ASTR, - // @ A B C D E F G - TR_Q, TR_A, TR_B, TR_C, TR_D, TR_E, TR_F, TR_G, - // H I J K L M N O - TR_H, TR_I, TR_J, TR_K, TR_L, TR_M, TR_N, TR_O, - // P Q R S T U V W - TR_P, TR_Q, TR_R, TR_S, TR_T, TR_U, TR_V, TR_W, - // X Y Z [ \ ] ^ _ - TR_X, TR_Y, TR_Z, TR_8, TR_ASTR, TR_9, TR_3, TR_MINS, - // ` a b c d e f g - TR_COMM, TR_A, TR_B, TR_C, TR_D, TR_E, TR_F, TR_G, - // h i j k l m n o - TR_H, TR_I, TR_J, TR_K, TR_L, TR_M, TR_N, TR_O, - // p q r s t u v w - TR_P, TR_Q, TR_R, TR_S, TR_T, TR_U, TR_V, TR_W, - // x y z { | } ~ DEL - TR_X, TR_Y, TR_Z, TR_7, TR_MINS, TR_0, TR_UDIA, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_uk.h b/quantum/keymap_extras/sendstring_uk.h deleted file mode 100644 index bbd30769b009..000000000000 --- a/quantum/keymap_extras/sendstring_uk.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Copyright 2019 Rys Sommefeldt - * - * 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 . - */ - -// Sendstring lookup tables for UK layouts - -#pragma once - -#include "keymap_uk.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 0, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, UK_1, UK_2, UK_HASH, UK_4, UK_5, UK_7, UK_QUOT, - // ( ) * + , - . / - UK_9, UK_0, UK_8, UK_EQL, UK_COMM, UK_MINS, UK_DOT, UK_SLSH, - // 0 1 2 3 4 5 6 7 - UK_0, UK_1, UK_2, UK_3, UK_4, UK_5, UK_6, UK_7, - // 8 9 : ; < = > ? - UK_8, UK_9, UK_SCLN, UK_SCLN, UK_COMM, UK_EQL, UK_DOT, UK_SLSH, - // @ A B C D E F G - UK_QUOT, UK_A, UK_B, UK_C, UK_D, UK_E, UK_F, UK_G, - // H I J K L M N O - UK_H, UK_I, UK_J, UK_K, UK_L, UK_M, UK_N, UK_O, - // P Q R S T U V W - UK_P, UK_Q, UK_R, UK_S, UK_T, UK_U, UK_V, UK_W, - // X Y Z [ \ ] ^ _ - UK_X, UK_Y, UK_Z, UK_LBRC, UK_BSLS, UK_RBRC, UK_6, UK_MINS, - // ` a b c d e f g - UK_GRV, UK_A, UK_B, UK_C, UK_D, UK_E, UK_F, UK_G, - // h i j k l m n o - UK_H, UK_I, UK_J, UK_K, UK_L, UK_M, UK_N, UK_O, - // p q r s t u v w - UK_P, UK_Q, UK_R, UK_S, UK_T, UK_U, UK_V, UK_W, - // x y z { | } ~ DEL - UK_X, UK_Y, UK_Z, UK_LBRC, UK_BSLS, UK_RBRC, UK_HASH, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_us_international.h b/quantum/keymap_extras/sendstring_us_international.h deleted file mode 100644 index d1694ff0f0fb..000000000000 --- a/quantum/keymap_extras/sendstring_us_international.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2019 Rys Sommefeldt - * - * 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 . - */ - -// Sendstring lookup tables for US International layouts - -#pragma once - -#include "keymap_us_international.h" -#include "quantum.h" - -// clang-format off - -const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0), -}; - -__attribute__((weak)) const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 1, 0, 0, 0, 0, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), - KCLUT_ENTRY(1, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 1, 0), -}; - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, US_1, US_ACUT, US_3, US_4, US_5, US_7, US_ACUT, - // ( ) * + , - . / - US_9, US_0, US_8, US_EQL, US_COMM, US_MINS, US_DOT, US_SLSH, - // 0 1 2 3 4 5 6 7 - US_0, US_1, US_2, US_3, US_4, US_5, US_6, US_7, - // 8 9 : ; < = > ? - US_8, US_9, US_SCLN, US_SCLN, US_COMM, US_EQL, US_DOT, US_SLSH, - // @ A B C D E F G - US_2, US_A, US_B, US_C, US_D, US_E, US_F, US_G, - // H I J K L M N O - US_H, US_I, US_J, US_K, US_L, US_M, US_N, US_O, - // P Q R S T U V W - US_P, US_Q, US_R, US_S, US_T, US_U, US_V, US_W, - // X Y Z [ \ ] ^ _ - US_X, US_Y, US_Z, US_LBRC, US_BSLS, US_RBRC, US_6, US_MINS, - // ` a b c d e f g - US_DGRV, US_A, US_B, US_C, US_D, US_E, US_F, US_G, - // h i j k l m n o - US_H, US_I, US_J, US_K, US_L, US_M, US_N, US_O, - // p q r s t u v w - US_P, US_Q, US_R, US_S, US_T, US_U, US_V, US_W, - // x y z { | } ~ DEL - US_X, US_Y, US_Z, US_LBRC, US_BSLS, US_RBRC, US_DGRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_workman.h b/quantum/keymap_extras/sendstring_workman.h deleted file mode 100644 index 04f8e3908a45..000000000000 --- a/quantum/keymap_extras/sendstring_workman.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2018 Jacob Jerrell - * - * 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 . - */ - -// Sendstring lookup tables for Workman layouts - -#pragma once - -#include "keymap_workman.h" - -// clang-format off - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, WK_1, WK_QUOT, WK_3, WK_4, WK_5, WK_7, WK_QUOT, - // ( ) * + , - . / - WK_9, WK_0, WK_8, WK_EQL, WK_COMM, WK_MINS, WK_DOT, WK_SLSH, - // 0 1 2 3 4 5 6 7 - WK_0, WK_1, WK_2, WK_3, WK_4, WK_5, WK_6, WK_7, - // 8 9 : ; < = > ? - WK_8, WK_9, WK_SCLN, WK_SCLN, WK_COMM, WK_EQL, WK_DOT, WK_SLSH, - // @ A B C D E F G - WK_2, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G, - // H I J K L M N O - WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O, - // P Q R S T U V W - WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W, - // X Y Z [ \ ] ^ _ - WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_6, WK_MINS, - // ` a b c d e f g - WK_GRV, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G, - // h i j k l m n o - WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O, - // p q r s t u v w - WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W, - // x y z { | } ~ DEL - WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_GRV, KC_DEL -}; diff --git a/quantum/keymap_extras/sendstring_workman_zxcvm.h b/quantum/keymap_extras/sendstring_workman_zxcvm.h deleted file mode 100644 index e7605d7cce13..000000000000 --- a/quantum/keymap_extras/sendstring_workman_zxcvm.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Copyright 2018 Jacob Jerrell - * - * 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 . - */ - -// Sendstring lookup tables for Workman ZXCVM layouts - -#pragma once - -#include "keymap_workman_zxcvm.h" - -// clang-format off - -const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, WK_1, WK_QUOT, WK_3, WK_4, WK_5, WK_7, WK_QUOT, - // ( ) * + , - . / - WK_9, WK_0, WK_8, WK_EQL, WK_COMM, WK_MINS, WK_DOT, WK_SLSH, - // 0 1 2 3 4 5 6 7 - WK_0, WK_1, WK_2, WK_3, WK_4, WK_5, WK_6, WK_7, - // 8 9 : ; < = > ? - WK_8, WK_9, WK_SCLN, WK_SCLN, WK_COMM, WK_EQL, WK_DOT, WK_SLSH, - // @ A B C D E F G - WK_2, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G, - // H I J K L M N O - WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O, - // P Q R S T U V W - WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W, - // X Y Z [ \ ] ^ _ - WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_6, WK_MINS, - // ` a b c d e f g - WK_GRV, WK_A, WK_B, WK_C, WK_D, WK_E, WK_F, WK_G, - // h i j k l m n o - WK_H, WK_I, WK_J, WK_K, WK_L, WK_M, WK_N, WK_O, - // p q r s t u v w - WK_P, WK_Q, WK_R, WK_S, WK_T, WK_U, WK_V, WK_W, - // x y z { | } ~ DEL - WK_X, WK_Y, WK_Z, WK_LBRC, WK_BSLS, WK_RBRC, WK_GRV, KC_DEL -}; diff --git a/quantum/keymap_introspection.c b/quantum/keymap_introspection.c deleted file mode 100644 index e4a01d2e9a0a..000000000000 --- a/quantum/keymap_introspection.c +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -// Pull the actual keymap code so that we can inspect stuff from it -#include KEYMAP_C - -// Allow for keymap or userspace rules.mk to specify an alternate location for the keymap array -#ifdef INTROSPECTION_KEYMAP_C -# include INTROSPECTION_KEYMAP_C -#endif // INTROSPECTION_KEYMAP_C - -#include "keymap_introspection.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Key mapping - -#define NUM_KEYMAP_LAYERS_RAW ((uint8_t)(sizeof(keymaps) / ((MATRIX_ROWS) * (MATRIX_COLS) * sizeof(uint16_t)))) - -uint8_t keymap_layer_count_raw(void) { - return NUM_KEYMAP_LAYERS_RAW; -} - -__attribute__((weak)) uint8_t keymap_layer_count(void) { - return keymap_layer_count_raw(); -} - -#ifdef DYNAMIC_KEYMAP_ENABLE -_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by DYNAMIC_KEYMAP_LAYER_COUNT"); -#else -_Static_assert(NUM_KEYMAP_LAYERS_RAW <= MAX_LAYER, "Number of keymap layers exceeds maximum set by LAYER_STATE_(8|16|32)BIT"); -#endif - -uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t column) { - if (layer_num < NUM_KEYMAP_LAYERS_RAW && row < MATRIX_ROWS && column < MATRIX_COLS) { - return pgm_read_word(&keymaps[layer_num][row][column]); - } - return KC_TRNS; -} - -__attribute__((weak)) uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column) { - return keycode_at_keymap_location_raw(layer_num, row, column); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Encoder mapping - -#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) - -# define NUM_ENCODERMAP_LAYERS_RAW ((uint8_t)(sizeof(encoder_map) / ((NUM_ENCODERS) * (NUM_DIRECTIONS) * sizeof(uint16_t)))) - -uint8_t encodermap_layer_count_raw(void) { - return NUM_ENCODERMAP_LAYERS_RAW; -} - -__attribute__((weak)) uint8_t encodermap_layer_count(void) { - return encodermap_layer_count_raw(); -} - -_Static_assert(NUM_KEYMAP_LAYERS_RAW == NUM_ENCODERMAP_LAYERS_RAW, "Number of encoder_map layers doesn't match the number of keymap layers"); - -uint16_t keycode_at_encodermap_location_raw(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { - if (layer_num < NUM_ENCODERMAP_LAYERS_RAW && encoder_idx < NUM_ENCODERS) { - return pgm_read_word(&encoder_map[layer_num][encoder_idx][clockwise ? 0 : 1]); - } - return KC_TRNS; -} - -__attribute__((weak)) uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx, bool clockwise) { - return keycode_at_encodermap_location_raw(layer_num, encoder_idx, clockwise); -} - -#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Combos - -#if defined(COMBO_ENABLE) - -uint16_t combo_count_raw(void) { - return sizeof(key_combos) / sizeof(combo_t); -} -__attribute__((weak)) uint16_t combo_count(void) { - return combo_count_raw(); -} - -combo_t* combo_get_raw(uint16_t combo_idx) { - return &key_combos[combo_idx]; -} -__attribute__((weak)) combo_t* combo_get(uint16_t combo_idx) { - return combo_get_raw(combo_idx); -} - -#endif // defined(COMBO_ENABLE) diff --git a/quantum/keymap_introspection.h b/quantum/keymap_introspection.h deleted file mode 100644 index 2012a2b8cc6c..000000000000 --- a/quantum/keymap_introspection.h +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#include -#include - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Key mapping - -// Get the number of layers defined in the keymap, stored in firmware rather than any other persistent storage -uint8_t keymap_layer_count_raw(void); -// Get the number of layers defined in the keymap, potentially stored dynamically -uint8_t keymap_layer_count(void); - -// Get the keycode for the keymap location, stored in firmware rather than any other persistent storage -uint16_t keycode_at_keymap_location_raw(uint8_t layer_num, uint8_t row, uint8_t column); -// Get the keycode for the keymap location, potentially stored dynamically -uint16_t keycode_at_keymap_location(uint8_t layer_num, uint8_t row, uint8_t column); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Encoder mapping - -#if defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) - -// Get the number of layers defined in the encoder map, stored in firmware rather than any other persistent storage -uint8_t encodermap_layer_count_raw(void); -// Get the number of layers defined in the encoder map, potentially stored dynamically -uint8_t encodermap_layer_count(void); - -// Get the keycode for the encoder mapping location, stored in firmware rather than any other persistent storage -uint16_t keycode_at_encodermap_location_raw(uint8_t layer_num, uint8_t encoder_idx, bool clockwise); -// Get the keycode for the encoder mapping location, potentially stored dynamically -uint16_t keycode_at_encodermap_location(uint8_t layer_num, uint8_t encoder_idx, bool clockwise); - -#endif // defined(ENCODER_ENABLE) && defined(ENCODER_MAP_ENABLE) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Combos - -#if defined(COMBO_ENABLE) - -// Forward declaration of combo_t so we don't need to deal with header reordering -struct combo_t; -typedef struct combo_t combo_t; - -// Get the number of combos defined in the user's keymap, stored in firmware rather than any other persistent storage -uint16_t combo_count_raw(void); -// Get the number of combos defined in the user's keymap, potentially stored dynamically -uint16_t combo_count(void); - -// Get the keycode for the encoder mapping location, stored in firmware rather than any other persistent storage -combo_t* combo_get_raw(uint16_t combo_idx); -// Get the keycode for the encoder mapping location, potentially stored dynamically -combo_t* combo_get(uint16_t combo_idx); - -#endif // defined(COMBO_ENABLE) diff --git a/quantum/leader.c b/quantum/leader.c deleted file mode 100644 index 272609ad0cfa..000000000000 --- a/quantum/leader.c +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "leader.h" -#include "timer.h" -#include "util.h" - -#include - -#ifndef LEADER_TIMEOUT -# define LEADER_TIMEOUT 300 -#endif - -// Leader key stuff -bool leading = false; -uint16_t leader_time = 0; -uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; -uint8_t leader_sequence_size = 0; - -__attribute__((weak)) void leader_start_user(void) {} - -__attribute__((weak)) void leader_end_user(void) {} - -void leader_start(void) { - if (leading) { - return; - } - leader_start_user(); - leading = true; - leader_time = timer_read(); - leader_sequence_size = 0; - memset(leader_sequence, 0, sizeof(leader_sequence)); -} - -void leader_end(void) { - leading = false; - leader_end_user(); -} - -void leader_task(void) { - if (leader_sequence_active() && leader_sequence_timed_out()) { - leader_end(); - } -} - -bool leader_sequence_active(void) { - return leading; -} - -bool leader_sequence_add(uint16_t keycode) { - if (leader_sequence_size >= ARRAY_SIZE(leader_sequence)) { - return false; - } - -#if defined(LEADER_NO_TIMEOUT) - if (leader_sequence_size == 0) { - leader_reset_timer(); - } -#endif - - leader_sequence[leader_sequence_size] = keycode; - leader_sequence_size++; - - return true; -} - -bool leader_sequence_timed_out(void) { -#if defined(LEADER_NO_TIMEOUT) - return leader_sequence_size > 0 && timer_elapsed(leader_time) > LEADER_TIMEOUT; -#else - return timer_elapsed(leader_time) > LEADER_TIMEOUT; -#endif -} - -void leader_reset_timer(void) { - leader_time = timer_read(); -} - -bool leader_sequence_is(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5) { - return leader_sequence[0] == kc1 && leader_sequence[1] == kc2 && leader_sequence[2] == kc3 && leader_sequence[3] == kc4 && leader_sequence[4] == kc5; -} - -bool leader_sequence_one_key(uint16_t kc) { - return leader_sequence_is(kc, 0, 0, 0, 0); -} - -bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2) { - return leader_sequence_is(kc1, kc2, 0, 0, 0); -} - -bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3) { - return leader_sequence_is(kc1, kc2, kc3, 0, 0); -} - -bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4) { - return leader_sequence_is(kc1, kc2, kc3, kc4, 0); -} - -bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5) { - return leader_sequence_is(kc1, kc2, kc3, kc4, kc5); -} diff --git a/quantum/leader.h b/quantum/leader.h deleted file mode 100644 index 3177fcd1962c..000000000000 --- a/quantum/leader.h +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -/** - * \file - * - * \defgroup leader Leader Key - * \{ - */ - -/** - * \brief User callback, invoked when the leader sequence begins. - */ -void leader_start_user(void); - -/** - * \brief User callback, invoked when the leader sequence ends. - */ -void leader_end_user(void); - -/** - * Begin the leader sequence, resetting the buffer and timer. - */ -void leader_start(void); - -/** - * End the leader sequence. - */ -void leader_end(void); - -void leader_task(void); - -/** - * Whether the leader sequence is active. - */ -bool leader_sequence_active(void); - -/** - * Add the given keycode to the sequence buffer. - * - * If `LEADER_NO_TIMEOUT` is defined, the timer is reset if the buffer is empty. - * - * \param keycode The keycode to add. - * - * \return `true` if the keycode was added, `false` if the buffer is full. - */ -bool leader_sequence_add(uint16_t keycode); - -/** - * Whether the leader sequence has reached the timeout. - * - * If `LEADER_NO_TIMEOUT` is defined, the buffer must also contain at least one key. - */ -bool leader_sequence_timed_out(void); - -/** - * Reset the leader sequence timer. - */ -void leader_reset_timer(void); - -/** - * Check the sequence buffer for the given keycode. - * - * \param kc The keycode to check. - * - * \return `true` if the sequence buffer matches. - */ -bool leader_sequence_one_key(uint16_t kc); - -/** - * Check the sequence buffer for the given keycodes. - * - * \param kc1 The first keycode to check. - * \param kc2 The second keycode to check. - * - * \return `true` if the sequence buffer matches. - */ -bool leader_sequence_two_keys(uint16_t kc1, uint16_t kc2); - -/** - * Check the sequence buffer for the given keycodes. - * - * \param kc1 The first keycode to check. - * \param kc2 The second keycode to check. - * \param kc3 The third keycode to check. - * - * \return `true` if the sequence buffer matches. - */ -bool leader_sequence_three_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3); - -/** - * Check the sequence buffer for the given keycodes. - * - * \param kc1 The first keycode to check. - * \param kc2 The second keycode to check. - * \param kc3 The third keycode to check. - * \param kc4 The fourth keycode to check. - * - * \return `true` if the sequence buffer matches. - */ -bool leader_sequence_four_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4); - -/** - * Check the sequence buffer for the given keycodes. - * - * \param kc1 The first keycode to check. - * \param kc2 The second keycode to check. - * \param kc3 The third keycode to check. - * \param kc4 The fourth keycode to check. - * \param kc5 The fifth keycode to check. - * - * \return `true` if the sequence buffer matches. - */ -bool leader_sequence_five_keys(uint16_t kc1, uint16_t kc2, uint16_t kc3, uint16_t kc4, uint16_t kc5); - -/** \} */ diff --git a/quantum/led.c b/quantum/led.c deleted file mode 100644 index 42144566fdd6..000000000000 --- a/quantum/led.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Copyright 2020 zvecr - * - * 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 . - */ -#include "led.h" -#include "host.h" -#include "timer.h" -#include "debug.h" -#include "gpio.h" - -#ifdef BACKLIGHT_CAPS_LOCK -# ifdef BACKLIGHT_ENABLE -# include "backlight.h" -extern backlight_config_t backlight_config; -# else -# pragma message "Cannot use BACKLIGHT_CAPS_LOCK without backlight being enabled" -# undef BACKLIGHT_CAPS_LOCK -# endif -#endif - -#ifndef LED_PIN_ON_STATE -# define LED_PIN_ON_STATE 1 -#endif - -#ifdef BACKLIGHT_CAPS_LOCK -/** \brief Caps Lock indicator using backlight (for keyboards without dedicated LED) - */ -static void handle_backlight_caps_lock(led_t led_state) { - // Use backlight as Caps Lock indicator - uint8_t bl_toggle_lvl = 0; - - if (led_state.caps_lock && !backlight_config.enable) { - // Turning Caps Lock ON and backlight is disabled in config - // Toggling backlight to the brightest level - bl_toggle_lvl = BACKLIGHT_LEVELS; - } else if (!led_state.caps_lock && backlight_config.enable) { - // Turning Caps Lock OFF and backlight is enabled in config - // Toggling backlight and restoring config level - bl_toggle_lvl = backlight_config.level; - } - - // Set level without modify backlight_config to keep ability to restore state - backlight_set(bl_toggle_lvl); -} -#endif - -static uint32_t last_led_modification_time = 0; -uint32_t last_led_activity_time(void) { - return last_led_modification_time; -} -uint32_t last_led_activity_elapsed(void) { - return timer_elapsed32(last_led_modification_time); -} - -/** \brief Lock LED set callback - keymap/user level - * - * \deprecated Use led_update_user() instead. - */ -__attribute__((weak)) void led_set_user(uint8_t usb_led) {} - -/** \brief Lock LED update callback - keymap/user level - * - * \return True if led_update_kb() should run its own code, false otherwise. - */ -__attribute__((weak)) bool led_update_user(led_t led_state) { - return true; -} - -/** \brief Lock LED update callback - keyboard level - * - * \return Ignored for now. - */ -__attribute__((weak)) bool led_update_kb(led_t led_state) { - bool res = led_update_user(led_state); - if (res) { - led_update_ports(led_state); - } - return res; -} - -/** \brief Write LED state to hardware - */ -__attribute__((weak)) void led_update_ports(led_t led_state) { -#if LED_PIN_ON_STATE == 0 - // invert the whole thing to avoid having to conditionally !led_state.x later - led_state.raw = ~led_state.raw; -#endif - -#ifdef LED_NUM_LOCK_PIN - writePin(LED_NUM_LOCK_PIN, led_state.num_lock); -#endif -#ifdef LED_CAPS_LOCK_PIN - writePin(LED_CAPS_LOCK_PIN, led_state.caps_lock); -#endif -#ifdef LED_SCROLL_LOCK_PIN - writePin(LED_SCROLL_LOCK_PIN, led_state.scroll_lock); -#endif -#ifdef LED_COMPOSE_PIN - writePin(LED_COMPOSE_PIN, led_state.compose); -#endif -#ifdef LED_KANA_PIN - writePin(LED_KANA_PIN, led_state.kana); -#endif -} - -/** \brief Initialise any LED related hardware and/or state - */ -__attribute__((weak)) void led_init_ports(void) { -#ifdef LED_NUM_LOCK_PIN - setPinOutput(LED_NUM_LOCK_PIN); - writePin(LED_NUM_LOCK_PIN, !LED_PIN_ON_STATE); -#endif -#ifdef LED_CAPS_LOCK_PIN - setPinOutput(LED_CAPS_LOCK_PIN); - writePin(LED_CAPS_LOCK_PIN, !LED_PIN_ON_STATE); -#endif -#ifdef LED_SCROLL_LOCK_PIN - setPinOutput(LED_SCROLL_LOCK_PIN); - writePin(LED_SCROLL_LOCK_PIN, !LED_PIN_ON_STATE); -#endif -#ifdef LED_COMPOSE_PIN - setPinOutput(LED_COMPOSE_PIN); - writePin(LED_COMPOSE_PIN, !LED_PIN_ON_STATE); -#endif -#ifdef LED_KANA_PIN - setPinOutput(LED_KANA_PIN); - writePin(LED_KANA_PIN, !LED_PIN_ON_STATE); -#endif -} - -/** \brief Entrypoint for protocol to LED binding - */ -__attribute__((weak)) void led_set(uint8_t usb_led) { -#ifdef BACKLIGHT_CAPS_LOCK - handle_backlight_caps_lock((led_t)usb_led); -#endif - - led_set_user(usb_led); - led_update_kb((led_t)usb_led); -} - -/** \brief Trigger behaviour on transition to suspend - */ -void led_suspend(void) { - uint8_t leds_off = 0; -#ifdef BACKLIGHT_CAPS_LOCK - if (is_backlight_enabled()) { - // Don't try to turn off Caps Lock indicator as it is backlight and backlight is already off - leds_off |= (1 << USB_LED_CAPS_LOCK); - } -#endif - led_set(leds_off); -} - -/** \brief Trigger behaviour on transition from suspend - */ -void led_wakeup(void) { - led_set(host_keyboard_leds()); -} - -/** \brief set host led state - * - * Only sets state if change detected - */ -void led_task(void) { - static uint8_t last_led_status = 0; - - // update LED - uint8_t led_status = host_keyboard_leds(); - if (last_led_status != led_status) { - last_led_status = led_status; - last_led_modification_time = timer_read32(); - - if (debug_keyboard) { - debug("led_task: "); - debug_hex8(led_status); - debug("\n"); - } - led_set(led_status); - } -} diff --git a/quantum/led.h b/quantum/led.h deleted file mode 100644 index b9ad7ed9ae7c..000000000000 --- a/quantum/led.h +++ /dev/null @@ -1,71 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include - -/* FIXME: Add doxygen comments here. */ - -/* keyboard LEDs */ -#define USB_LED_NUM_LOCK 0 -#define USB_LED_CAPS_LOCK 1 -#define USB_LED_SCROLL_LOCK 2 -#define USB_LED_COMPOSE 3 -#define USB_LED_KANA 4 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef union { - uint8_t raw; - struct { - bool num_lock : 1; - bool caps_lock : 1; - bool scroll_lock : 1; - bool compose : 1; - bool kana : 1; - uint8_t reserved : 3; - }; -} led_t; - -void led_set(uint8_t usb_led); - -void led_init_ports(void); - -void led_suspend(void); - -void led_wakeup(void); - -void led_task(void); - -/* Deprecated callbacks */ -void led_set_user(uint8_t usb_led); - -/* Callbacks */ -bool led_update_user(led_t led_state); -bool led_update_kb(led_t led_state); -void led_update_ports(led_t led_state); - -uint32_t last_led_activity_time(void); // Timestamp of the LED activity -uint32_t last_led_activity_elapsed(void); // Number of milliseconds since the last LED activity - -#ifdef __cplusplus -} -#endif diff --git a/quantum/led_matrix/animations/alpha_mods_anim.h b/quantum/led_matrix/animations/alpha_mods_anim.h deleted file mode 100644 index 01acb3f933c7..000000000000 --- a/quantum/led_matrix/animations/alpha_mods_anim.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_ALPHAS_MODS -LED_MATRIX_EFFECT(ALPHAS_MODS) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -// alphas = val1, mods = val2 -bool ALPHAS_MODS(effect_params_t* params) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t val1 = led_matrix_eeconfig.val; - uint8_t val2 = val1 + led_matrix_eeconfig.speed; - - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_MODIFIER)) { - led_matrix_set_value(i, val2); - } else { - led_matrix_set_value(i, val1); - } - } - return led_matrix_check_finished_leds(led_max); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_ALPHAS_MODS diff --git a/quantum/led_matrix/animations/band_anim.h b/quantum/led_matrix/animations/band_anim.h deleted file mode 100644 index d9491849eaed..000000000000 --- a/quantum/led_matrix/animations/band_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_BAND -LED_MATRIX_EFFECT(BAND) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t BAND_math(uint8_t val, uint8_t i, uint8_t time) { - int16_t v = val - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8; - return scale8(v < 0 ? 0 : v, val); -} - -bool BAND(effect_params_t* params) { - return effect_runner_i(params, &BAND_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_BAND diff --git a/quantum/led_matrix/animations/band_pinwheel_anim.h b/quantum/led_matrix/animations/band_pinwheel_anim.h deleted file mode 100644 index 482d183eb6e4..000000000000 --- a/quantum/led_matrix/animations/band_pinwheel_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_BAND_PINWHEEL -LED_MATRIX_EFFECT(BAND_PINWHEEL) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t BAND_PINWHEEL_math(uint8_t val, int16_t dx, int16_t dy, uint8_t time) { - return scale8(val - time - atan2_8(dy, dx) * 3, val); -} - -bool BAND_PINWHEEL(effect_params_t* params) { - return effect_runner_dx_dy(params, &BAND_PINWHEEL_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_BAND_PINWHEEL diff --git a/quantum/led_matrix/animations/band_spiral_anim.h b/quantum/led_matrix/animations/band_spiral_anim.h deleted file mode 100644 index ef93d192701c..000000000000 --- a/quantum/led_matrix/animations/band_spiral_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_BAND_SPIRAL -LED_MATRIX_EFFECT(BAND_SPIRAL) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t BAND_SPIRAL_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - return scale8(val + dist - time - atan2_8(dy, dx), val); -} - -bool BAND_SPIRAL(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_BAND_SPIRAL diff --git a/quantum/led_matrix/animations/breathing_anim.h b/quantum/led_matrix/animations/breathing_anim.h deleted file mode 100644 index 0bd4cb0cc388..000000000000 --- a/quantum/led_matrix/animations/breathing_anim.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_BREATHING -LED_MATRIX_EFFECT(BREATHING) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -bool BREATHING(effect_params_t* params) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t val = led_matrix_eeconfig.val; - uint16_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 8); - val = scale8(abs8(sin8(time) - 128) * 2, val); - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - led_matrix_set_value(i, val); - } - return led_matrix_check_finished_leds(led_max); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_BREATHING diff --git a/quantum/led_matrix/animations/cycle_left_right_anim.h b/quantum/led_matrix/animations/cycle_left_right_anim.h deleted file mode 100644 index 0a339e6d62b7..000000000000 --- a/quantum/led_matrix/animations/cycle_left_right_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_CYCLE_LEFT_RIGHT -LED_MATRIX_EFFECT(CYCLE_LEFT_RIGHT) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t CYCLE_LEFT_RIGHT_math(uint8_t val, uint8_t i, uint8_t time) { - return scale8(g_led_config.point[i].x - time, val); -} - -bool CYCLE_LEFT_RIGHT(effect_params_t* params) { - return effect_runner_i(params, &CYCLE_LEFT_RIGHT_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_CYCLE_LEFT_RIGHT diff --git a/quantum/led_matrix/animations/cycle_out_in_anim.h b/quantum/led_matrix/animations/cycle_out_in_anim.h deleted file mode 100644 index 8311d97fe894..000000000000 --- a/quantum/led_matrix/animations/cycle_out_in_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_CYCLE_OUT_IN -LED_MATRIX_EFFECT(CYCLE_OUT_IN) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t CYCLE_OUT_IN_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - return scale8(3 * dist / 2 + time, val); -} - -bool CYCLE_OUT_IN(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &CYCLE_OUT_IN_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_CYCLE_OUT_IN diff --git a/quantum/led_matrix/animations/cycle_up_down_anim.h b/quantum/led_matrix/animations/cycle_up_down_anim.h deleted file mode 100644 index 7e2d71a0f1f3..000000000000 --- a/quantum/led_matrix/animations/cycle_up_down_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_CYCLE_UP_DOWN -LED_MATRIX_EFFECT(CYCLE_UP_DOWN) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t CYCLE_UP_DOWN_math(uint8_t val, uint8_t i, uint8_t time) { - return scale8(g_led_config.point[i].y - time, val); -} - -bool CYCLE_UP_DOWN(effect_params_t* params) { - return effect_runner_i(params, &CYCLE_UP_DOWN_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_CYCLE_UP_DOWN diff --git a/quantum/led_matrix/animations/dual_beacon_anim.h b/quantum/led_matrix/animations/dual_beacon_anim.h deleted file mode 100644 index 1dfb5ffe5231..000000000000 --- a/quantum/led_matrix/animations/dual_beacon_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_DUAL_BEACON -LED_MATRIX_EFFECT(DUAL_BEACON) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t DUAL_BEACON_math(uint8_t val, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { - return scale8(((g_led_config.point[i].y - k_led_matrix_center.y) * cos + (g_led_config.point[i].x - k_led_matrix_center.x) * sin) / 128, val); -} - -bool DUAL_BEACON(effect_params_t* params) { - return effect_runner_sin_cos_i(params, &DUAL_BEACON_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_DUAL_BEACON diff --git a/quantum/led_matrix/animations/led_matrix_effects.inc b/quantum/led_matrix/animations/led_matrix_effects.inc deleted file mode 100644 index ad1f46b2422c..000000000000 --- a/quantum/led_matrix/animations/led_matrix_effects.inc +++ /dev/null @@ -1,18 +0,0 @@ -// Add your new core led matrix effect here, order determines enum order -#include "solid_anim.h" -#include "alpha_mods_anim.h" -#include "breathing_anim.h" -#include "band_anim.h" -#include "band_pinwheel_anim.h" -#include "band_spiral_anim.h" -#include "cycle_left_right_anim.h" -#include "cycle_up_down_anim.h" -#include "cycle_out_in_anim.h" -#include "dual_beacon_anim.h" -#include "solid_reactive_simple_anim.h" -#include "solid_reactive_wide.h" -#include "solid_reactive_cross.h" -#include "solid_reactive_nexus.h" -#include "solid_splash_anim.h" -#include "wave_left_right_anim.h" -#include "wave_up_down_anim.h" diff --git a/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h deleted file mode 100644 index fa9b7dbbfa55..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_dx_dy.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -typedef uint8_t (*dx_dy_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t time); - -bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 2); - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - int16_t dx = g_led_config.point[i].x - k_led_matrix_center.x; - int16_t dy = g_led_config.point[i].y - k_led_matrix_center.y; - led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, time)); - } - return led_matrix_check_finished_leds(led_max); -} diff --git a/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h deleted file mode 100644 index 061a5f07febd..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_dx_dy_dist.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -typedef uint8_t (*dx_dy_dist_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint8_t time); - -bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 2); - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - int16_t dx = g_led_config.point[i].x - k_led_matrix_center.x; - int16_t dy = g_led_config.point[i].y - k_led_matrix_center.y; - uint8_t dist = sqrt16(dx * dx + dy * dy); - led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, dx, dy, dist, time)); - } - return led_matrix_check_finished_leds(led_max); -} diff --git a/quantum/led_matrix/animations/runners/effect_runner_i.h b/quantum/led_matrix/animations/runners/effect_runner_i.h deleted file mode 100644 index f6f8c0dee0c7..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_i.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -typedef uint8_t (*i_f)(uint8_t val, uint8_t i, uint8_t time); - -bool effect_runner_i(effect_params_t* params, i_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 4); - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, i, time)); - } - return led_matrix_check_finished_leds(led_max); -} diff --git a/quantum/led_matrix/animations/runners/effect_runner_reactive.h b/quantum/led_matrix/animations/runners/effect_runner_reactive.h deleted file mode 100644 index 846845874425..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_reactive.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - -typedef uint8_t (*reactive_f)(uint8_t val, uint16_t offset); - -bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint16_t max_tick = 65535 / led_matrix_eeconfig.speed; - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - uint16_t tick = max_tick; - // Reverse search to find most recent key hit - for (int8_t j = g_last_hit_tracker.count - 1; j >= 0; j--) { - if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) { - tick = g_last_hit_tracker.tick[j]; - break; - } - } - - uint16_t offset = scale16by8(tick, led_matrix_eeconfig.speed); - led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, offset)); - } - return led_matrix_check_finished_leds(led_max); -} - -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h deleted file mode 100644 index aec4a6ffdafb..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_reactive_splash.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - -typedef uint8_t (*reactive_splash_f)(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick); - -bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, reactive_splash_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t count = g_last_hit_tracker.count; - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - uint8_t val = 0; - for (uint8_t j = start; j < count; j++) { - int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j]; - int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j]; - uint8_t dist = sqrt16(dx * dx + dy * dy); - uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], led_matrix_eeconfig.speed); - val = effect_func(val, dx, dy, dist, tick); - } - led_matrix_set_value(i, scale8(val, led_matrix_eeconfig.val)); - } - return led_matrix_check_finished_leds(led_max); -} - -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h deleted file mode 100644 index 3145e27139de..000000000000 --- a/quantum/led_matrix/animations/runners/effect_runner_sin_cos_i.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -typedef uint8_t (*sin_cos_i_f)(uint8_t val, int8_t sin, int8_t cos, uint8_t i, uint8_t time); - -bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint16_t time = scale16by8(g_led_timer, led_matrix_eeconfig.speed / 4); - int8_t cos_value = cos8(time) - 128; - int8_t sin_value = sin8(time) - 128; - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - led_matrix_set_value(i, effect_func(led_matrix_eeconfig.val, cos_value, sin_value, i, time)); - } - return led_matrix_check_finished_leds(led_max); -} diff --git a/quantum/led_matrix/animations/runners/led_matrix_runners.inc b/quantum/led_matrix/animations/runners/led_matrix_runners.inc deleted file mode 100644 index c09022bb0fad..000000000000 --- a/quantum/led_matrix/animations/runners/led_matrix_runners.inc +++ /dev/null @@ -1,6 +0,0 @@ -#include "effect_runner_dx_dy_dist.h" -#include "effect_runner_dx_dy.h" -#include "effect_runner_i.h" -#include "effect_runner_sin_cos_i.h" -#include "effect_runner_reactive.h" -#include "effect_runner_reactive_splash.h" diff --git a/quantum/led_matrix/animations/solid_anim.h b/quantum/led_matrix/animations/solid_anim.h deleted file mode 100644 index 895542e15294..000000000000 --- a/quantum/led_matrix/animations/solid_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -LED_MATRIX_EFFECT(SOLID) -#ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -bool SOLID(effect_params_t* params) { - LED_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t val = led_matrix_eeconfig.val; - for (uint8_t i = led_min; i < led_max; i++) { - LED_MATRIX_TEST_LED_FLAGS(); - led_matrix_set_value(i, val); - } - return led_matrix_check_finished_leds(led_max); -} - -#endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/led_matrix/animations/solid_reactive_cross.h b/quantum/led_matrix/animations/solid_reactive_cross.h deleted file mode 100644 index 55a2556996ff..000000000000 --- a/quantum/led_matrix/animations/solid_reactive_cross.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS) - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS -LED_MATRIX_EFFECT(SOLID_REACTIVE_CROSS) -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS -LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTICROSS) -# endif - -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t SOLID_REACTIVE_CROSS_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick + dist; - dx = dx < 0 ? dx * -1 : dx; - dy = dy < 0 ? dy * -1 : dy; - dx = dx * 16 > 255 ? 255 : dx * 16; - dy = dy * 16 > 255 ? 255 : dy * 16; - effect += dx > dy ? dy : dx; - if (effect > 255) effect = 255; - return qadd8(val, 255 - effect); -} - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS -bool SOLID_REACTIVE_CROSS(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_CROSS_math); -} -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS -bool SOLID_REACTIVE_MULTICROSS(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_CROSS_math); -} -# endif - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_CROSS) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTICROSS) -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/solid_reactive_nexus.h b/quantum/led_matrix/animations/solid_reactive_nexus.h deleted file mode 100644 index b1ec54e3b129..000000000000 --- a/quantum/led_matrix/animations/solid_reactive_nexus.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS) - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS -LED_MATRIX_EFFECT(SOLID_REACTIVE_NEXUS) -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS -LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTINEXUS) -# endif - -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t SOLID_REACTIVE_NEXUS_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick - dist; - if (effect > 255) effect = 255; - if (dist > 72) effect = 255; - if ((dx > 8 || dx < -8) && (dy > 8 || dy < -8)) effect = 255; - return qadd8(val, 255 - effect); -} - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS -bool SOLID_REACTIVE_NEXUS(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_NEXUS_math); -} -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS -bool SOLID_REACTIVE_MULTINEXUS(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_NEXUS_math); -} -# endif - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_NEXUS) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTINEXUS) -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/solid_reactive_simple_anim.h b/quantum/led_matrix/animations/solid_reactive_simple_anim.h deleted file mode 100644 index 3b289c78dd4c..000000000000 --- a/quantum/led_matrix/animations/solid_reactive_simple_anim.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE -LED_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t SOLID_REACTIVE_SIMPLE_math(uint8_t val, uint16_t offset) { - return scale8(255 - offset, val); -} - -bool SOLID_REACTIVE_SIMPLE(effect_params_t* params) { - return effect_runner_reactive(params, &SOLID_REACTIVE_SIMPLE_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // ENABLE_LED_MATRIX_SOLID_REACTIVE_SIMPLE -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/solid_reactive_wide.h b/quantum/led_matrix/animations/solid_reactive_wide.h deleted file mode 100644 index dda54eab2c66..000000000000 --- a/quantum/led_matrix/animations/solid_reactive_wide.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE) - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE -LED_MATRIX_EFFECT(SOLID_REACTIVE_WIDE) -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE -LED_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE) -# endif - -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t SOLID_REACTIVE_WIDE_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick + dist * 5; - if (effect > 255) effect = 255; - return qadd8(val, 255 - effect); -} - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE -bool SOLID_REACTIVE_WIDE(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_WIDE_math); -} -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE -bool SOLID_REACTIVE_MULTIWIDE(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_WIDE_math); -} -# endif - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_WIDE) || defined(ENABLE_LED_MATRIX_SOLID_REACTIVE_MULTIWIDE) -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/solid_splash_anim.h b/quantum/led_matrix/animations/solid_splash_anim.h deleted file mode 100644 index b8b6e8ea5ef4..000000000000 --- a/quantum/led_matrix/animations/solid_splash_anim.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_LED_MATRIX_SOLID_SPLASH) || defined(ENABLE_LED_MATRIX_SOLID_MULTISPLASH) - -# ifdef ENABLE_LED_MATRIX_SOLID_SPLASH -LED_MATRIX_EFFECT(SOLID_SPLASH) -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_MULTISPLASH -LED_MATRIX_EFFECT(SOLID_MULTISPLASH) -# endif - -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -uint8_t SOLID_SPLASH_math(uint8_t val, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick - dist; - if (effect > 255) effect = 255; - return qadd8(val, 255 - effect); -} - -# ifdef ENABLE_LED_MATRIX_SOLID_SPLASH -bool SOLID_SPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_SPLASH_math); -} -# endif - -# ifdef ENABLE_LED_MATRIX_SOLID_MULTISPLASH -bool SOLID_MULTISPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_SPLASH_math); -} -# endif - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // defined(ENABLE_LED_MATRIX_SPLASH) || defined(ENABLE_LED_MATRIX_MULTISPLASH) -#endif // LED_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/led_matrix/animations/wave_left_right_anim.h b/quantum/led_matrix/animations/wave_left_right_anim.h deleted file mode 100644 index 8dedd647388d..000000000000 --- a/quantum/led_matrix/animations/wave_left_right_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_WAVE_LEFT_RIGHT -LED_MATRIX_EFFECT(WAVE_LEFT_RIGHT) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t WAVE_LEFT_RIGHT_math(uint8_t val, uint8_t i, uint8_t time) { - return scale8(sin8(g_led_config.point[i].x - time), val); -} - -bool WAVE_LEFT_RIGHT(effect_params_t* params) { - return effect_runner_i(params, &WAVE_LEFT_RIGHT_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_WAVE_LEFT_RIGHT diff --git a/quantum/led_matrix/animations/wave_up_down_anim.h b/quantum/led_matrix/animations/wave_up_down_anim.h deleted file mode 100644 index 4564f3e493e2..000000000000 --- a/quantum/led_matrix/animations/wave_up_down_anim.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifdef ENABLE_LED_MATRIX_WAVE_UP_DOWN -LED_MATRIX_EFFECT(WAVE_UP_DOWN) -# ifdef LED_MATRIX_CUSTOM_EFFECT_IMPLS - -static uint8_t WAVE_UP_DOWN_math(uint8_t val, uint8_t i, uint8_t time) { - return scale8(sin8(g_led_config.point[i].y - time), val); -} - -bool WAVE_UP_DOWN(effect_params_t* params) { - return effect_runner_i(params, &WAVE_UP_DOWN_math); -} - -# endif // LED_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_LED_MATRIX_WAVE_UP_DOWN diff --git a/quantum/led_matrix/led_matrix.c b/quantum/led_matrix/led_matrix.c deleted file mode 100644 index 828d61641a1b..000000000000 --- a/quantum/led_matrix/led_matrix.c +++ /dev/null @@ -1,640 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2017 Jack Humbert - * Copyright 2018 Yiancar - * Copyright 2019 Clueboard - * - * 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 . - */ - -#include "led_matrix.h" -#include "progmem.h" -#include "eeprom.h" -#include -#include -#include "led_tables.h" - -#include - -#ifndef LED_MATRIX_CENTER -const led_point_t k_led_matrix_center = {112, 32}; -#else -const led_point_t k_led_matrix_center = LED_MATRIX_CENTER; -#endif - -// Generic effect runners -#include "led_matrix_runners.inc" - -// ------------------------------------------ -// -----Begin led effect includes macros----- -#define LED_MATRIX_EFFECT(name) -#define LED_MATRIX_CUSTOM_EFFECT_IMPLS - -#include "led_matrix_effects.inc" -#ifdef LED_MATRIX_CUSTOM_KB -# include "led_matrix_kb.inc" -#endif -#ifdef LED_MATRIX_CUSTOM_USER -# include "led_matrix_user.inc" -#endif - -#undef LED_MATRIX_CUSTOM_EFFECT_IMPLS -#undef LED_MATRIX_EFFECT -// -----End led effect includes macros------- -// ------------------------------------------ - -#ifndef LED_MATRIX_TIMEOUT -# define LED_MATRIX_TIMEOUT 0 -#endif - -#if !defined(LED_MATRIX_MAXIMUM_BRIGHTNESS) || LED_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX -# undef LED_MATRIX_MAXIMUM_BRIGHTNESS -# define LED_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX -#endif - -#if !defined(LED_MATRIX_VAL_STEP) -# define LED_MATRIX_VAL_STEP 8 -#endif - -#if !defined(LED_MATRIX_SPD_STEP) -# define LED_MATRIX_SPD_STEP 16 -#endif - -#if !defined(LED_MATRIX_DEFAULT_MODE) -# define LED_MATRIX_DEFAULT_MODE LED_MATRIX_SOLID -#endif - -#if !defined(LED_MATRIX_DEFAULT_VAL) -# define LED_MATRIX_DEFAULT_VAL LED_MATRIX_MAXIMUM_BRIGHTNESS -#endif - -#if !defined(LED_MATRIX_DEFAULT_SPD) -# define LED_MATRIX_DEFAULT_SPD UINT8_MAX / 2 -#endif - -// globals -led_eeconfig_t led_matrix_eeconfig; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr -uint32_t g_led_timer; -#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS -uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}}; -#endif // LED_MATRIX_FRAMEBUFFER_EFFECTS -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -last_hit_t g_last_hit_tracker; -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - -// internals -static bool suspend_state = false; -static uint8_t led_last_enable = UINT8_MAX; -static uint8_t led_last_effect = UINT8_MAX; -static effect_params_t led_effect_params = {0, LED_FLAG_ALL, false}; -static led_task_states led_task_state = SYNCING; -#if LED_MATRIX_TIMEOUT > 0 -static uint32_t led_anykey_timer; -#endif // LED_MATRIX_TIMEOUT > 0 - -// double buffers -static uint32_t led_timer_buffer; -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -static last_hit_t last_hit_buffer; -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - -// split led matrix -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) -const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; -#endif - -EECONFIG_DEBOUNCE_HELPER(led_matrix, EECONFIG_LED_MATRIX, led_matrix_eeconfig); - -void eeconfig_update_led_matrix(void) { - eeconfig_flush_led_matrix(true); -} - -void eeconfig_update_led_matrix_default(void) { - dprintf("eeconfig_update_led_matrix_default\n"); - led_matrix_eeconfig.enable = 1; - led_matrix_eeconfig.mode = LED_MATRIX_DEFAULT_MODE; - led_matrix_eeconfig.val = LED_MATRIX_DEFAULT_VAL; - led_matrix_eeconfig.speed = LED_MATRIX_DEFAULT_SPD; - led_matrix_eeconfig.flags = LED_FLAG_ALL; - eeconfig_flush_led_matrix(true); -} - -void eeconfig_debug_led_matrix(void) { - dprintf("led_matrix_eeconfig EEPROM\n"); - dprintf("led_matrix_eeconfig.enable = %d\n", led_matrix_eeconfig.enable); - dprintf("led_matrix_eeconfig.mode = %d\n", led_matrix_eeconfig.mode); - dprintf("led_matrix_eeconfig.val = %d\n", led_matrix_eeconfig.val); - dprintf("led_matrix_eeconfig.speed = %d\n", led_matrix_eeconfig.speed); - dprintf("led_matrix_eeconfig.flags = %d\n", led_matrix_eeconfig.flags); -} - -__attribute__((weak)) uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { - return 0; -} - -uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { - uint8_t led_count = led_matrix_map_row_column_to_led_kb(row, column, led_i); - uint8_t led_index = g_led_config.matrix_co[row][column]; - if (led_index != NO_LED) { - led_i[led_count] = led_index; - led_count++; - } - return led_count; -} - -void led_matrix_update_pwm_buffers(void) { - led_matrix_driver.flush(); -} - -void led_matrix_set_value(int index, uint8_t value) { -#ifdef USE_CIE1931_CURVE - value = pgm_read_byte(&CIE1931_CURVE[value]); -#endif - led_matrix_driver.set_value(index, value); -} - -void led_matrix_set_value_all(uint8_t value) { -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - for (uint8_t i = 0; i < LED_MATRIX_LED_COUNT; i++) - led_matrix_set_value(i, value); -#else -# ifdef USE_CIE1931_CURVE - led_matrix_driver.set_value_all(pgm_read_byte(&CIE1931_CURVE[value])); -# else - led_matrix_driver.set_value_all(value); -# endif -#endif -} - -void process_led_matrix(uint8_t row, uint8_t col, bool pressed) { -#ifndef LED_MATRIX_SPLIT - if (!is_keyboard_master()) return; -#endif -#if LED_MATRIX_TIMEOUT > 0 - led_anykey_timer = 0; -#endif // LED_MATRIX_TIMEOUT > 0 - -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - uint8_t led[LED_HITS_TO_REMEMBER]; - uint8_t led_count = 0; - -# if defined(LED_MATRIX_KEYRELEASES) - if (!pressed) -# elif defined(LED_MATRIX_KEYPRESSES) - if (pressed) -# endif // defined(LED_MATRIX_KEYRELEASES) - { - led_count = led_matrix_map_row_column_to_led(row, col, led); - } - - if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) { - memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count); - memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count); - memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit - memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count); - last_hit_buffer.count = LED_HITS_TO_REMEMBER - led_count; - } - - for (uint8_t i = 0; i < led_count; i++) { - uint8_t index = last_hit_buffer.count; - last_hit_buffer.x[index] = g_led_config.point[led[i]].x; - last_hit_buffer.y[index] = g_led_config.point[led[i]].y; - last_hit_buffer.index[index] = led[i]; - last_hit_buffer.tick[index] = 0; - last_hit_buffer.count++; - } -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - -#if defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_LED_MATRIX_TYPING_HEATMAP) - if (led_matrix_eeconfig.mode == LED_MATRIX_TYPING_HEATMAP) { - process_led_matrix_typing_heatmap(row, col); - } -#endif // defined(LED_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_LED_MATRIX_TYPING_HEATMAP) -} - -static bool led_matrix_none(effect_params_t *params) { - if (!params->init) { - return false; - } - - led_matrix_set_value_all(0); - return false; -} - -static void led_task_timers(void) { -#if defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0 - uint32_t deltaTime = sync_timer_elapsed32(led_timer_buffer); -#endif // defined(LED_MATRIX_KEYREACTIVE_ENABLED) || LED_MATRIX_TIMEOUT > 0 - led_timer_buffer = sync_timer_read32(); - - // Update double buffer timers -#if LED_MATRIX_TIMEOUT > 0 - if (led_anykey_timer < UINT32_MAX) { - if (UINT32_MAX - deltaTime < led_anykey_timer) { - led_anykey_timer = UINT32_MAX; - } else { - led_anykey_timer += deltaTime; - } - } -#endif // LED_MATRIX_TIMEOUT > 0 - - // Update double buffer last hit timers -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - uint8_t count = last_hit_buffer.count; - for (uint8_t i = 0; i < count; ++i) { - if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) { - last_hit_buffer.count--; - continue; - } - last_hit_buffer.tick[i] += deltaTime; - } -#endif // LED_MATRIX_KEYREACTIVE_ENABLED -} - -static void led_task_sync(void) { - eeconfig_flush_led_matrix(false); - // next task - if (sync_timer_elapsed32(g_led_timer) >= LED_MATRIX_LED_FLUSH_LIMIT) led_task_state = STARTING; -} - -static void led_task_start(void) { - // reset iter - led_effect_params.iter = 0; - - // update double buffers - g_led_timer = led_timer_buffer; -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - g_last_hit_tracker = last_hit_buffer; -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - - // next task - led_task_state = RENDERING; -} - -static void led_task_render(uint8_t effect) { - bool rendering = false; - led_effect_params.init = (effect != led_last_effect) || (led_matrix_eeconfig.enable != led_last_enable); - if (led_effect_params.flags != led_matrix_eeconfig.flags) { - led_effect_params.flags = led_matrix_eeconfig.flags; - led_matrix_set_value_all(0); - } - - // each effect can opt to do calculations - // and/or request PWM buffer updates. - switch (effect) { - case LED_MATRIX_NONE: - rendering = led_matrix_none(&led_effect_params); - break; - -// --------------------------------------------- -// -----Begin led effect switch case macros----- -#define LED_MATRIX_EFFECT(name, ...) \ - case LED_MATRIX_##name: \ - rendering = name(&led_effect_params); \ - break; -#include "led_matrix_effects.inc" -#undef LED_MATRIX_EFFECT - -#if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) -# define LED_MATRIX_EFFECT(name, ...) \ - case LED_MATRIX_CUSTOM_##name: \ - rendering = name(&led_effect_params); \ - break; -# ifdef LED_MATRIX_CUSTOM_KB -# include "led_matrix_kb.inc" -# endif -# ifdef LED_MATRIX_CUSTOM_USER -# include "led_matrix_user.inc" -# endif -# undef LED_MATRIX_EFFECT -#endif - // -----End led effect switch case macros------- - // --------------------------------------------- - } - - led_effect_params.iter++; - - // next task - if (!rendering) { - led_task_state = FLUSHING; - if (!led_effect_params.init && effect == LED_MATRIX_NONE) { - // We only need to flush once if we are LED_MATRIX_NONE - led_task_state = SYNCING; - } - } -} - -static void led_task_flush(uint8_t effect) { - // update last trackers after the first full render so we can init over several frames - led_last_effect = effect; - led_last_enable = led_matrix_eeconfig.enable; - - // update pwm buffers - led_matrix_update_pwm_buffers(); - - // next task - led_task_state = SYNCING; -} - -void led_matrix_task(void) { - led_task_timers(); - - // Ideally we would also stop sending zeros to the LED driver PWM buffers - // while suspended and just do a software shutdown. This is a cheap hack for now. - bool suspend_backlight = suspend_state || -#if LED_MATRIX_TIMEOUT > 0 - (led_anykey_timer > (uint32_t)LED_MATRIX_TIMEOUT) || -#endif // LED_MATRIX_TIMEOUT > 0 - false; - - uint8_t effect = suspend_backlight || !led_matrix_eeconfig.enable ? 0 : led_matrix_eeconfig.mode; - - switch (led_task_state) { - case STARTING: - led_task_start(); - break; - case RENDERING: - led_task_render(effect); - if (effect) { - led_matrix_indicators(); - led_matrix_indicators_advanced(&led_effect_params); - } - break; - case FLUSHING: - led_task_flush(effect); - break; - case SYNCING: - led_task_sync(); - break; - } -} - -void led_matrix_indicators(void) { - led_matrix_indicators_kb(); - led_matrix_indicators_user(); -} - -__attribute__((weak)) bool led_matrix_indicators_kb(void) { - return led_matrix_indicators_user(); -} - -__attribute__((weak)) bool led_matrix_indicators_user(void) { - return true; -} - -void led_matrix_indicators_advanced(effect_params_t *params) { - /* special handling is needed for "params->iter", since it's already been incremented. - * Could move the invocations to led_task_render, but then it's missing a few checks - * and not sure which would be better. Otherwise, this should be called from - * led_task_render, right before the iter++ line. - */ -#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < LED_MATRIX_LED_COUNT - uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * (params->iter - 1); - uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT; - if (max > LED_MATRIX_LED_COUNT) max = LED_MATRIX_LED_COUNT; -#else - uint8_t min = 0; - uint8_t max = LED_MATRIX_LED_COUNT; -#endif - led_matrix_indicators_advanced_kb(min, max); - led_matrix_indicators_advanced_user(min, max); -} - -__attribute__((weak)) bool led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) { - return led_matrix_indicators_advanced_user(led_min, led_max); -} - -__attribute__((weak)) bool led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - return true; -} - -void led_matrix_init(void) { - led_matrix_driver.init(); - -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED - g_last_hit_tracker.count = 0; - for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { - g_last_hit_tracker.tick[i] = UINT16_MAX; - } - - last_hit_buffer.count = 0; - for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { - last_hit_buffer.tick[i] = UINT16_MAX; - } -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - - if (!eeconfig_is_enabled()) { - dprintf("led_matrix_init_drivers eeconfig is not enabled.\n"); - eeconfig_init(); - eeconfig_update_led_matrix_default(); - } - - eeconfig_init_led_matrix(); - if (!led_matrix_eeconfig.mode) { - dprintf("led_matrix_init_drivers led_matrix_eeconfig.mode = 0. Write default values to EEPROM.\n"); - eeconfig_update_led_matrix_default(); - } - eeconfig_debug_led_matrix(); // display current eeprom values -} - -void led_matrix_set_suspend_state(bool state) { -#ifdef LED_DISABLE_WHEN_USB_SUSPENDED - if (state && !suspend_state && is_keyboard_master()) { // only run if turning off, and only once - led_task_render(0); // turn off all LEDs when suspending - led_task_flush(0); // and actually flash led state to LEDs - } - suspend_state = state; -#endif -} - -bool led_matrix_get_suspend_state(void) { - return suspend_state; -} - -void led_matrix_toggle_eeprom_helper(bool write_to_eeprom) { - led_matrix_eeconfig.enable ^= 1; - led_task_state = STARTING; - eeconfig_flag_led_matrix(write_to_eeprom); - dprintf("led matrix toggle [%s]: led_matrix_eeconfig.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.enable); -} -void led_matrix_toggle_noeeprom(void) { - led_matrix_toggle_eeprom_helper(false); -} -void led_matrix_toggle(void) { - led_matrix_toggle_eeprom_helper(true); -} - -void led_matrix_enable(void) { - led_matrix_enable_noeeprom(); - eeconfig_flag_led_matrix(true); -} - -void led_matrix_enable_noeeprom(void) { - if (!led_matrix_eeconfig.enable) led_task_state = STARTING; - led_matrix_eeconfig.enable = 1; -} - -void led_matrix_disable(void) { - led_matrix_disable_noeeprom(); - eeconfig_flag_led_matrix(true); -} - -void led_matrix_disable_noeeprom(void) { - if (led_matrix_eeconfig.enable) led_task_state = STARTING; - led_matrix_eeconfig.enable = 0; -} - -uint8_t led_matrix_is_enabled(void) { - return led_matrix_eeconfig.enable; -} - -void led_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { - if (!led_matrix_eeconfig.enable) { - return; - } - if (mode < 1) { - led_matrix_eeconfig.mode = 1; - } else if (mode >= LED_MATRIX_EFFECT_MAX) { - led_matrix_eeconfig.mode = LED_MATRIX_EFFECT_MAX - 1; - } else { - led_matrix_eeconfig.mode = mode; - } - led_task_state = STARTING; - eeconfig_flag_led_matrix(write_to_eeprom); - dprintf("led matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.mode); -} -void led_matrix_mode_noeeprom(uint8_t mode) { - led_matrix_mode_eeprom_helper(mode, false); -} -void led_matrix_mode(uint8_t mode) { - led_matrix_mode_eeprom_helper(mode, true); -} - -uint8_t led_matrix_get_mode(void) { - return led_matrix_eeconfig.mode; -} - -void led_matrix_step_helper(bool write_to_eeprom) { - uint8_t mode = led_matrix_eeconfig.mode + 1; - led_matrix_mode_eeprom_helper((mode < LED_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom); -} -void led_matrix_step_noeeprom(void) { - led_matrix_step_helper(false); -} -void led_matrix_step(void) { - led_matrix_step_helper(true); -} - -void led_matrix_step_reverse_helper(bool write_to_eeprom) { - uint8_t mode = led_matrix_eeconfig.mode - 1; - led_matrix_mode_eeprom_helper((mode < 1) ? LED_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom); -} -void led_matrix_step_reverse_noeeprom(void) { - led_matrix_step_reverse_helper(false); -} -void led_matrix_step_reverse(void) { - led_matrix_step_reverse_helper(true); -} - -void led_matrix_set_val_eeprom_helper(uint8_t val, bool write_to_eeprom) { - if (!led_matrix_eeconfig.enable) { - return; - } - led_matrix_eeconfig.val = (val > LED_MATRIX_MAXIMUM_BRIGHTNESS) ? LED_MATRIX_MAXIMUM_BRIGHTNESS : val; - eeconfig_flag_led_matrix(write_to_eeprom); - dprintf("led matrix set val [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.val); -} -void led_matrix_set_val_noeeprom(uint8_t val) { - led_matrix_set_val_eeprom_helper(val, false); -} -void led_matrix_set_val(uint8_t val) { - led_matrix_set_val_eeprom_helper(val, true); -} - -uint8_t led_matrix_get_val(void) { - return led_matrix_eeconfig.val; -} - -void led_matrix_increase_val_helper(bool write_to_eeprom) { - led_matrix_set_val_eeprom_helper(qadd8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); -} -void led_matrix_increase_val_noeeprom(void) { - led_matrix_increase_val_helper(false); -} -void led_matrix_increase_val(void) { - led_matrix_increase_val_helper(true); -} - -void led_matrix_decrease_val_helper(bool write_to_eeprom) { - led_matrix_set_val_eeprom_helper(qsub8(led_matrix_eeconfig.val, LED_MATRIX_VAL_STEP), write_to_eeprom); -} -void led_matrix_decrease_val_noeeprom(void) { - led_matrix_decrease_val_helper(false); -} -void led_matrix_decrease_val(void) { - led_matrix_decrease_val_helper(true); -} - -void led_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { - led_matrix_eeconfig.speed = speed; - eeconfig_flag_led_matrix(write_to_eeprom); - dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.speed); -} -void led_matrix_set_speed_noeeprom(uint8_t speed) { - led_matrix_set_speed_eeprom_helper(speed, false); -} -void led_matrix_set_speed(uint8_t speed) { - led_matrix_set_speed_eeprom_helper(speed, true); -} - -uint8_t led_matrix_get_speed(void) { - return led_matrix_eeconfig.speed; -} - -void led_matrix_increase_speed_helper(bool write_to_eeprom) { - led_matrix_set_speed_eeprom_helper(qadd8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); -} -void led_matrix_increase_speed_noeeprom(void) { - led_matrix_increase_speed_helper(false); -} -void led_matrix_increase_speed(void) { - led_matrix_increase_speed_helper(true); -} - -void led_matrix_decrease_speed_helper(bool write_to_eeprom) { - led_matrix_set_speed_eeprom_helper(qsub8(led_matrix_eeconfig.speed, LED_MATRIX_SPD_STEP), write_to_eeprom); -} -void led_matrix_decrease_speed_noeeprom(void) { - led_matrix_decrease_speed_helper(false); -} -void led_matrix_decrease_speed(void) { - led_matrix_decrease_speed_helper(true); -} - -void led_matrix_set_flags_eeprom_helper(led_flags_t flags, bool write_to_eeprom) { - led_matrix_eeconfig.flags = flags; - eeconfig_flag_led_matrix(write_to_eeprom); - dprintf("led matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", led_matrix_eeconfig.flags); -} - -led_flags_t led_matrix_get_flags(void) { - return led_matrix_eeconfig.flags; -} - -void led_matrix_set_flags(led_flags_t flags) { - led_matrix_set_flags_eeprom_helper(flags, true); -} - -void led_matrix_set_flags_noeeprom(led_flags_t flags) { - led_matrix_set_flags_eeprom_helper(flags, false); -} diff --git a/quantum/led_matrix/led_matrix.h b/quantum/led_matrix/led_matrix.h deleted file mode 100644 index c7d360f366dc..000000000000 --- a/quantum/led_matrix/led_matrix.h +++ /dev/null @@ -1,201 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2017 Jack Humbert - * Copyright 2018 Yiancar - * Copyright 2019 Clueboard - * Copyright 2021 Leo Deng - * - * 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 . - */ - -#pragma once - -#include -#include -#include "led_matrix_types.h" -#include "quantum.h" - -#ifdef IS31FL3731 -# include "is31fl3731-simple.h" -#elif defined(IS31FLCOMMON) -# include "is31flcommon.h" -#endif -#ifdef IS31FL3733 -# include "is31fl3733-simple.h" -#endif -#ifdef CKLED2001 -# include "ckled2001-simple.h" -#endif - -#ifndef LED_MATRIX_LED_FLUSH_LIMIT -# define LED_MATRIX_LED_FLUSH_LIMIT 16 -#endif - -#ifndef LED_MATRIX_LED_PROCESS_LIMIT -# define LED_MATRIX_LED_PROCESS_LIMIT (LED_MATRIX_LED_COUNT + 4) / 5 -#endif - -#if defined(LED_MATRIX_LED_PROCESS_LIMIT) && LED_MATRIX_LED_PROCESS_LIMIT > 0 && LED_MATRIX_LED_PROCESS_LIMIT < LED_MATRIX_LED_COUNT -# if defined(LED_MATRIX_SPLIT) -# define LED_MATRIX_USE_LIMITS(min, max) \ - uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \ - uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT; \ - if (max > LED_MATRIX_LED_COUNT) max = LED_MATRIX_LED_COUNT; \ - uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; \ - if (is_keyboard_left() && (max > k_led_matrix_split[0])) max = k_led_matrix_split[0]; \ - if (!(is_keyboard_left()) && (min < k_led_matrix_split[0])) min = k_led_matrix_split[0]; -# else -# define LED_MATRIX_USE_LIMITS(min, max) \ - uint8_t min = LED_MATRIX_LED_PROCESS_LIMIT * params->iter; \ - uint8_t max = min + LED_MATRIX_LED_PROCESS_LIMIT; \ - if (max > LED_MATRIX_LED_COUNT) max = LED_MATRIX_LED_COUNT; -# endif -#else -# if defined(LED_MATRIX_SPLIT) -# define LED_MATRIX_USE_LIMITS(min, max) \ - uint8_t min = 0; \ - uint8_t max = LED_MATRIX_LED_COUNT; \ - const uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; \ - if (is_keyboard_left() && (max > k_led_matrix_split[0])) max = k_led_matrix_split[0]; \ - if (!(is_keyboard_left()) && (min < k_led_matrix_split[0])) min = k_led_matrix_split[0]; -# else -# define LED_MATRIX_USE_LIMITS(min, max) \ - uint8_t min = 0; \ - uint8_t max = LED_MATRIX_LED_COUNT; -# endif -#endif - -#define LED_MATRIX_TEST_LED_FLAGS() \ - if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue - -enum led_matrix_effects { - LED_MATRIX_NONE = 0, - -// -------------------------------------- -// -----Begin led effect enum macros----- -#define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_##name, -#include "led_matrix_effects.inc" -#undef LED_MATRIX_EFFECT - -#if defined(LED_MATRIX_CUSTOM_KB) || defined(LED_MATRIX_CUSTOM_USER) -# define LED_MATRIX_EFFECT(name, ...) LED_MATRIX_CUSTOM_##name, -# ifdef LED_MATRIX_CUSTOM_KB -# include "led_matrix_kb.inc" -# endif -# ifdef LED_MATRIX_CUSTOM_USER -# include "led_matrix_user.inc" -# endif -# undef LED_MATRIX_EFFECT -#endif - // -------------------------------------- - // -----End led effect enum macros------- - - LED_MATRIX_EFFECT_MAX -}; - -void eeconfig_update_led_matrix_default(void); -void eeconfig_update_led_matrix(void); -void eeconfig_debug_led_matrix(void); - -uint8_t led_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); -uint8_t led_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); - -void led_matrix_set_value(int index, uint8_t value); -void led_matrix_set_value_all(uint8_t value); - -void process_led_matrix(uint8_t row, uint8_t col, bool pressed); - -void led_matrix_task(void); - -// This runs after another backlight effect and replaces -// values already set -void led_matrix_indicators(void); -bool led_matrix_indicators_kb(void); -bool led_matrix_indicators_user(void); - -void led_matrix_indicators_advanced(effect_params_t *params); -bool led_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max); -bool led_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max); - -void led_matrix_init(void); - -void led_matrix_set_suspend_state(bool state); -bool led_matrix_get_suspend_state(void); -void led_matrix_toggle(void); -void led_matrix_toggle_noeeprom(void); -void led_matrix_enable(void); -void led_matrix_enable_noeeprom(void); -void led_matrix_disable(void); -void led_matrix_disable_noeeprom(void); -uint8_t led_matrix_is_enabled(void); -void led_matrix_mode(uint8_t mode); -void led_matrix_mode_noeeprom(uint8_t mode); -uint8_t led_matrix_get_mode(void); -void led_matrix_step(void); -void led_matrix_step_noeeprom(void); -void led_matrix_step_reverse(void); -void led_matrix_step_reverse_noeeprom(void); -void led_matrix_set_val(uint8_t val); -void led_matrix_set_val_noeeprom(uint8_t val); -uint8_t led_matrix_get_val(void); -void led_matrix_increase_val(void); -void led_matrix_increase_val_noeeprom(void); -void led_matrix_decrease_val(void); -void led_matrix_decrease_val_noeeprom(void); -void led_matrix_set_speed(uint8_t speed); -void led_matrix_set_speed_noeeprom(uint8_t speed); -uint8_t led_matrix_get_speed(void); -void led_matrix_increase_speed(void); -void led_matrix_increase_speed_noeeprom(void); -void led_matrix_decrease_speed(void); -void led_matrix_decrease_speed_noeeprom(void); -led_flags_t led_matrix_get_flags(void); -void led_matrix_set_flags(led_flags_t flags); -void led_matrix_set_flags_noeeprom(led_flags_t flags); - -typedef struct { - /* Perform any initialisation required for the other driver functions to work. */ - void (*init)(void); - - /* Set the brightness of a single LED in the buffer. */ - void (*set_value)(int index, uint8_t value); - /* Set the brightness of all LEDS on the keyboard in the buffer. */ - void (*set_value_all)(uint8_t value); - /* Flush any buffered changes to the hardware. */ - void (*flush)(void); -} led_matrix_driver_t; - -static inline bool led_matrix_check_finished_leds(uint8_t led_idx) { -#if defined(LED_MATRIX_SPLIT) - if (is_keyboard_left()) { - uint8_t k_led_matrix_split[2] = LED_MATRIX_SPLIT; - return led_idx < k_led_matrix_split[0]; - } else - return led_idx < LED_MATRIX_LED_COUNT; -#else - return led_idx < LED_MATRIX_LED_COUNT; -#endif -} - -extern const led_matrix_driver_t led_matrix_driver; - -extern led_eeconfig_t led_matrix_eeconfig; - -extern uint32_t g_led_timer; -extern led_config_t g_led_config; -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -extern last_hit_t g_last_hit_tracker; -#endif -#ifdef LED_MATRIX_FRAMEBUFFER_EFFECTS -extern uint8_t g_led_frame_buffer[MATRIX_ROWS][MATRIX_COLS]; -#endif diff --git a/quantum/led_matrix/led_matrix_drivers.c b/quantum/led_matrix/led_matrix_drivers.c deleted file mode 100644 index 2c09ba82b1f0..000000000000 --- a/quantum/led_matrix/led_matrix_drivers.c +++ /dev/null @@ -1,247 +0,0 @@ -/* Copyright 2018 James Laird-Wah - * Copyright 2019 Clueboard - * - * 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 . - */ - -#include "led_matrix.h" - -/* Each driver needs to define a struct: - * - * const led_matrix_driver_t led_matrix_driver; - * - * All members must be provided. Keyboard custom drivers must define this - * in their own files. - */ - -#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FLCOMMON) || defined(CKLED2001) -# include "i2c_master.h" - -static void init(void) { - i2c_init(); - -# if defined(IS31FL3731) - IS31FL3731_init(LED_DRIVER_ADDR_1); -# if defined(LED_DRIVER_ADDR_2) - IS31FL3731_init(LED_DRIVER_ADDR_2); -# if defined(LED_DRIVER_ADDR_3) - IS31FL3731_init(LED_DRIVER_ADDR_3); -# if defined(LED_DRIVER_ADDR_4) - IS31FL3731_init(LED_DRIVER_ADDR_4); -# endif -# endif -# endif - -# elif defined(IS31FL3733) -# if !defined(LED_DRIVER_SYNC_1) -# define LED_DRIVER_SYNC_1 0 -# endif - IS31FL3733_init(LED_DRIVER_ADDR_1, LED_DRIVER_SYNC_1); -# if defined(LED_DRIVER_ADDR_2) -# if !defined(LED_DRIVER_SYNC_2) -# define LED_DRIVER_SYNC_2 0 -# endif - IS31FL3733_init(LED_DRIVER_ADDR_2, LED_DRIVER_SYNC_2); -# if defined(LED_DRIVER_ADDR_3) -# if !defined(LED_DRIVER_SYNC_3) -# define LED_DRIVER_SYNC_3 0 -# endif - IS31FL3733_init(LED_DRIVER_ADDR_3, LED_DRIVER_SYNC_3); -# if defined(LED_DRIVER_ADDR_4) -# if !defined(LED_DRIVER_SYNC_4) -# define LED_DRIVER_SYNC_4 0 -# endif - IS31FL3733_init(LED_DRIVER_ADDR_4, LED_DRIVER_SYNC_4); -# endif -# endif -# endif - -# elif defined(IS31FLCOMMON) - IS31FL_common_init(DRIVER_ADDR_1, ISSI_SSR_1); -# if defined(LED_DRIVER_ADDR_2) - IS31FL_common_init(DRIVER_ADDR_2, ISSI_SSR_2); -# if defined(LED_DRIVER_ADDR_3) - IS31FL_common_init(DRIVER_ADDR_3, ISSI_SSR_3); -# if defined(LED_DRIVER_ADDR_4) - IS31FL_common_init(DRIVER_ADDR_4, ISSI_SSR_4); -# endif -# endif -# endif -# elif defined(CKLED2001) -# if defined(LED_DRIVER_SHUTDOWN_PIN) - setPinOutput(LED_DRIVER_SHUTDOWN_PIN); - writePinHigh(LED_DRIVER_SHUTDOWN_PIN); -# endif - - CKLED2001_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - CKLED2001_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - CKLED2001_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - CKLED2001_init(DRIVER_ADDR_4); -# endif -# endif -# endif -# endif - - for (int index = 0; index < LED_MATRIX_LED_COUNT; index++) { -# if defined(IS31FL3731) - IS31FL3731_set_led_control_register(index, true); -# elif defined(IS31FL3733) - IS31FL3733_set_led_control_register(index, true); -# elif defined(IS31FLCOMMON) - IS31FL_simple_set_scaling_buffer(index, true); -# elif defined(CKLED2001) - CKLED2001_set_led_control_register(index, true); -# endif - } - -// This actually updates the LED drivers -# if defined(IS31FL3731) - IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL3731_update_led_control_registers(LED_DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FL3733) - IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL3733_update_led_control_registers(LED_DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FLCOMMON) -# ifdef ISSI_MANUAL_SCALING - IS31FL_set_manual_scaling_buffer(); -# endif - IS31FL_common_update_scaling_register(DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL_common_update_scaling_register(DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL_common_update_scaling_register(DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL_common_update_scaling_register(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -# elif defined(CKLED2001) - CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -# endif -} - -# if defined(IS31FL3731) -static void flush(void) { - IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL3731_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const led_matrix_driver_t led_matrix_driver = { - .init = init, - .flush = flush, - .set_value = IS31FL3731_set_value, - .set_value_all = IS31FL3731_set_value_all, -}; - -# elif defined(IS31FL3733) -static void flush(void) { - IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL3733_update_pwm_buffers(LED_DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const led_matrix_driver_t led_matrix_driver = { - .init = init, - .flush = flush, - .set_value = IS31FL3733_set_value, - .set_value_all = IS31FL3733_set_value_all, -}; - -# elif defined(IS31FLCOMMON) -static void flush(void) { - IS31FL_common_update_pwm_register(DRIVER_ADDR_1, 0); -# if defined(LED_DRIVER_ADDR_2) - IS31FL_common_update_pwm_register(DRIVER_ADDR_2, 1); -# if defined(LED_DRIVER_ADDR_3) - IS31FL_common_update_pwm_register(DRIVER_ADDR_3, 2); -# if defined(LED_DRIVER_ADDR_4) - IS31FL_common_update_pwm_register(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const led_matrix_driver_t led_matrix_driver = { - .init = init, - .flush = flush, - .set_value = IS31FL_simple_set_brightness, - .set_value_all = IS31FL_simple_set_brigntness_all, -}; -# elif defined(CKLED2001) -static void flush(void) { - CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const led_matrix_driver_t led_matrix_driver = { - .init = init, - .flush = flush, - .set_value = CKLED2001_set_value, - .set_value_all = CKLED2001_set_value_all, -}; -# endif -#endif diff --git a/quantum/led_matrix/led_matrix_types.h b/quantum/led_matrix/led_matrix_types.h deleted file mode 100644 index 6709a558bb94..000000000000 --- a/quantum/led_matrix/led_matrix_types.h +++ /dev/null @@ -1,98 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -#pragma once - -#include -#include - -#if defined(__GNUC__) -# define PACKED __attribute__((__packed__)) -#else -# define PACKED -#endif - -#if defined(_MSC_VER) -# pragma pack(push, 1) -#endif - -#if defined(LED_MATRIX_KEYPRESSES) || defined(LED_MATRIX_KEYRELEASES) -# define LED_MATRIX_KEYREACTIVE_ENABLED -#endif - -// Last led hit -#ifndef LED_HITS_TO_REMEMBER -# define LED_HITS_TO_REMEMBER 8 -#endif // LED_HITS_TO_REMEMBER - -#ifdef LED_MATRIX_KEYREACTIVE_ENABLED -typedef struct PACKED { - uint8_t count; - uint8_t x[LED_HITS_TO_REMEMBER]; - uint8_t y[LED_HITS_TO_REMEMBER]; - uint8_t index[LED_HITS_TO_REMEMBER]; - uint16_t tick[LED_HITS_TO_REMEMBER]; -} last_hit_t; -#endif // LED_MATRIX_KEYREACTIVE_ENABLED - -typedef enum led_task_states { STARTING, RENDERING, FLUSHING, SYNCING } led_task_states; - -typedef uint8_t led_flags_t; - -typedef struct PACKED { - uint8_t iter; - led_flags_t flags; - bool init; -} effect_params_t; - -typedef struct PACKED { - uint8_t x; - uint8_t y; -} led_point_t; - -#define HAS_FLAGS(bits, flags) ((bits & flags) == flags) -#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00) - -#define LED_FLAG_ALL 0xFF -#define LED_FLAG_NONE 0x00 -#define LED_FLAG_MODIFIER 0x01 -#define LED_FLAG_KEYLIGHT 0x04 -#define LED_FLAG_INDICATOR 0x08 - -#define NO_LED 255 - -typedef struct PACKED { - uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS]; - led_point_t point[LED_MATRIX_LED_COUNT]; - uint8_t flags[LED_MATRIX_LED_COUNT]; -} led_config_t; - -typedef union { - uint32_t raw; - struct PACKED { - uint8_t enable : 2; - uint8_t mode : 6; - uint8_t val; - uint8_t speed; - led_flags_t flags; - }; -} led_eeconfig_t; - -_Static_assert(sizeof(led_eeconfig_t) == sizeof(uint32_t), "LED Matrix EECONFIG out of spec."); - -#if defined(_MSC_VER) -# pragma pack(pop) -#endif diff --git a/quantum/led_tables.c b/quantum/led_tables.c deleted file mode 100644 index 9fbe642cc76e..000000000000 --- a/quantum/led_tables.c +++ /dev/null @@ -1,43 +0,0 @@ -/* -Copyright 2017 Fred Sundvik - -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 . -*/ - -#include "led_tables.h" - -// clang-format off - -#ifdef USE_CIE1931_CURVE -// Lightness curve using the CIE 1931 lightness formula -// Generated by the python script provided in http://jared.geek.nz/2013/feb/linear-led-pwm -const uint8_t CIE1931_CURVE[256] PROGMEM = { - 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, - 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, - 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, - 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 15, 16, 16, 17, 17, 17, - 18, 18, 19, 19, 20, 20, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, - 26, 26, 27, 27, 28, 29, 29, 30, 30, 31, 32, 32, 33, 34, 34, 35, - 36, 36, 37, 38, 38, 39, 40, 41, 41, 42, 43, 44, 45, 45, 46, 47, - 48, 49, 50, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 76, 77, 78, 79, - 80, 81, 83, 84, 85, 86, 88, 89, 90, 91, 93, 94, 95, 97, 98, 100, - 101, 102, 104, 105, 107, 108, 109, 111, 112, 114, 115, 117, 119, 120, 122, 123, - 125, 126, 128, 130, 131, 133, 135, 136, 138, 140, 142, 143, 145, 147, 149, 150, - 152, 154, 156, 158, 160, 162, 163, 165, 167, 169, 171, 173, 175, 177, 179, 181, - 183, 186, 188, 190, 192, 194, 196, 198, 201, 203, 205, 207, 209, 212, 214, 216, - 219, 221, 223, 226, 228, 231, 233, 235, 238, 240, 243, 245, 248, 250, 253, 255 -}; -#endif - -// clang-format on diff --git a/quantum/logging/debug.c b/quantum/logging/debug.c deleted file mode 100644 index ca7654eda2aa..000000000000 --- a/quantum/logging/debug.c +++ /dev/null @@ -1,25 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ -#include "debug.h" - -debug_config_t debug_config = { - .enable = false, // - .matrix = false, // - .keyboard = false, // - .mouse = false, // - .reserved = 0 // -}; diff --git a/quantum/logging/debug.h b/quantum/logging/debug.h deleted file mode 100644 index 841531035691..000000000000 --- a/quantum/logging/debug.h +++ /dev/null @@ -1,169 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include "print.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Debug output control - */ -typedef union { - struct { - bool enable : 1; - bool matrix : 1; - bool keyboard : 1; - bool mouse : 1; - uint8_t reserved : 4; - }; - uint8_t raw; -} debug_config_t; - -extern debug_config_t debug_config; - -#ifdef __cplusplus -} -#endif - -/* for backward compatibility */ -#define debug_enable (debug_config.enable) -#define debug_matrix (debug_config.matrix) -#define debug_keyboard (debug_config.keyboard) -#define debug_mouse (debug_config.mouse) - -/* - * Debug print utils - */ -#ifndef NO_DEBUG - -# define dprint(s) \ - do { \ - if (debug_enable) print(s); \ - } while (0) -# define dprintln(s) \ - do { \ - if (debug_enable) println(s); \ - } while (0) -# define dprintf(fmt, ...) \ - do { \ - if (debug_enable) xprintf(fmt, ##__VA_ARGS__); \ - } while (0) -# define dmsg(s) dprintf("%s at %d: %s\n", __FILE__, __LINE__, s) - -/* Deprecated. DO NOT USE these anymore, use dprintf instead. */ -# define debug(s) \ - do { \ - if (debug_enable) print(s); \ - } while (0) -# define debugln(s) \ - do { \ - if (debug_enable) println(s); \ - } while (0) -# define debug_msg(s) \ - do { \ - if (debug_enable) { \ - print(__FILE__); \ - print(" at "); \ - print_dec(__LINE__); \ - print(" in "); \ - print(": "); \ - print(s); \ - } \ - } while (0) -# define debug_dec(data) \ - do { \ - if (debug_enable) print_dec(data); \ - } while (0) -# define debug_decs(data) \ - do { \ - if (debug_enable) print_decs(data); \ - } while (0) -# define debug_hex4(data) \ - do { \ - if (debug_enable) print_hex4(data); \ - } while (0) -# define debug_hex8(data) \ - do { \ - if (debug_enable) print_hex8(data); \ - } while (0) -# define debug_hex16(data) \ - do { \ - if (debug_enable) print_hex16(data); \ - } while (0) -# define debug_hex32(data) \ - do { \ - if (debug_enable) print_hex32(data); \ - } while (0) -# define debug_bin8(data) \ - do { \ - if (debug_enable) print_bin8(data); \ - } while (0) -# define debug_bin16(data) \ - do { \ - if (debug_enable) print_bin16(data); \ - } while (0) -# define debug_bin32(data) \ - do { \ - if (debug_enable) print_bin32(data); \ - } while (0) -# define debug_bin_reverse8(data) \ - do { \ - if (debug_enable) print_bin_reverse8(data); \ - } while (0) -# define debug_bin_reverse16(data) \ - do { \ - if (debug_enable) print_bin_reverse16(data); \ - } while (0) -# define debug_bin_reverse32(data) \ - do { \ - if (debug_enable) print_bin_reverse32(data); \ - } while (0) -# define debug_hex(data) debug_hex8(data) -# define debug_bin(data) debug_bin8(data) -# define debug_bin_reverse(data) debug_bin8(data) - -#else /* NO_DEBUG */ - -# define dprint(s) -# define dprintln(s) -# define dprintf(fmt, ...) -# define dmsg(s) -# define debug(s) -# define debugln(s) -# define debug_msg(s) -# define debug_dec(data) -# define debug_decs(data) -# define debug_hex4(data) -# define debug_hex8(data) -# define debug_hex16(data) -# define debug_hex32(data) -# define debug_bin8(data) -# define debug_bin16(data) -# define debug_bin32(data) -# define debug_bin_reverse8(data) -# define debug_bin_reverse16(data) -# define debug_bin_reverse32(data) -# define debug_hex(data) -# define debug_bin(data) -# define debug_bin_reverse(data) - -#endif /* NO_DEBUG */ diff --git a/quantum/logging/print.c b/quantum/logging/print.c deleted file mode 100644 index 17e6737ac444..000000000000 --- a/quantum/logging/print.c +++ /dev/null @@ -1,33 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ -#include -#include "sendchar.h" - -// bind lib/printf to console interface - sendchar - -static int8_t null_sendchar_func(uint8_t c) { - return 0; -} -static sendchar_func_t func = null_sendchar_func; - -void print_set_sendchar(sendchar_func_t send) { - func = send; -} - -void putchar_(char character) { - func(character); -} diff --git a/quantum/logging/print.h b/quantum/logging/print.h deleted file mode 100644 index 4c4195de50ff..000000000000 --- a/quantum/logging/print.h +++ /dev/null @@ -1,151 +0,0 @@ -/* Copyright 2012 Jun Wako */ -/* Very basic print functions, intended to be used with usb_debug_only.c - * http://www.pjrc.com/teensy/ - * Copyright (c) 2008 PJRC.COM, LLC - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -#pragma once - -#include -#include -#include "util.h" -#include "sendchar.h" -#include "progmem.h" - -void print_set_sendchar(sendchar_func_t func); - -/** - * @brief This macro suppress format warnings for the function that is passed - * in. The main use-case is that `b` format specifier for printing binary - * numbers is not in the official C standard. Inclusion is planned for the - * upcoming C2X C standard, but until then GCC will always output a warning for - * a unknown format specifier. - */ -#define IGNORE_FORMAT_WARNING(func) \ - do { \ - _Pragma("GCC diagnostic push"); \ - _Pragma("GCC diagnostic ignored \"-Wformat\""); \ - _Pragma("GCC diagnostic ignored \"-Wformat-extra-args\""); \ - func; \ - _Pragma("GCC diagnostic pop"); \ - } while (0) - -#ifndef NO_PRINT -# if __has_include_next("_print.h") -# include_next "_print.h" /* Include the platforms print.h */ -# else -// Fall back to lib/printf -# include "printf.h" // lib/printf/printf.h - -// Create user & normal print defines -# define print(s) printf(s) -# define println(s) printf(s "\r\n") -# define xprintf printf -# define uprint(s) printf(s) -# define uprintln(s) printf(s "\r\n") -# define uprintf printf - -# endif /* __has_include_next("_print.h") */ -#else /* NO_PRINT */ -# undef xprintf -// Remove print defines -# define print(s) -# define println(s) -# define xprintf(fmt, ...) -# define uprintf(fmt, ...) -# define uprint(s) -# define uprintln(s) - -#endif /* NO_PRINT */ - -#ifdef USER_PRINT -// Remove normal print defines -# undef print -# undef println -# undef xprintf -# define print(s) -# define println(s) -# define xprintf(fmt, ...) -#endif - -#define print_dec(i) xprintf("%u", i) -#define print_decs(i) xprintf("%d", i) -/* hex */ -#define print_hex4(i) xprintf("%X", i) -#define print_hex8(i) xprintf("%02X", i) -#define print_hex16(i) xprintf("%04X", i) -#define print_hex32(i) xprintf("%08lX", i) -/* binary */ -#define print_bin4(i) IGNORE_FORMAT_WARNING(xprintf("%04b", i)) -#define print_bin8(i) IGNORE_FORMAT_WARNING(xprintf("%08b", i)) -#define print_bin16(i) IGNORE_FORMAT_WARNING(xprintf("%016b", i)) -#define print_bin32(i) IGNORE_FORMAT_WARNING(xprintf("%032lb", i)) -#define print_bin_reverse8(i) IGNORE_FORMAT_WARNING(xprintf("%08b", bitrev(i))) -#define print_bin_reverse16(i) IGNORE_FORMAT_WARNING(xprintf("%016b", bitrev16(i))) -#define print_bin_reverse32(i) IGNORE_FORMAT_WARNING(xprintf("%032lb", bitrev32(i))) -/* print value utility */ -#define print_val_dec(v) xprintf(#v ": %u\n", v) -#define print_val_decs(v) xprintf(#v ": %d\n", v) -#define print_val_hex8(v) xprintf(#v ": %X\n", v) -#define print_val_hex16(v) xprintf(#v ": %02X\n", v) -#define print_val_hex32(v) xprintf(#v ": %04lX\n", v) -#define print_val_bin8(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %08b\n", v)) -#define print_val_bin16(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %016b\n", v)) -#define print_val_bin32(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %032lb\n", v)) -#define print_val_bin_reverse8(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %08b\n", bitrev(v))) -#define print_val_bin_reverse16(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %016b\n", bitrev16(v))) -#define print_val_bin_reverse32(v) IGNORE_FORMAT_WARNING(xprintf(#v ": %032lb\n", bitrev32(v))) - -// User print disables the normal print messages in the body of QMK/TMK code and -// is meant as a lightweight alternative to NOPRINT. Use it when you only want to do -// a spot of debugging but lack flash resources for allowing all of the codebase to -// print (and store their wasteful strings). -// -// !!! DO NOT USE USER PRINT CALLS IN THE BODY OF QMK/TMK !!! - -/* decimal */ -#define uprint_dec(i) uprintf("%u", i) -#define uprint_decs(i) uprintf("%d", i) -/* hex */ -#define uprint_hex4(i) uprintf("%X", i) -#define uprint_hex8(i) uprintf("%02X", i) -#define uprint_hex16(i) uprintf("%04X", i) -#define uprint_hex32(i) uprintf("%08lX", i) -/* binary */ -#define uprint_bin4(i) IGNORE_FORMAT_WARNING(uprintf("%04b", i)) -#define uprint_bin8(i) IGNORE_FORMAT_WARNING(uprintf("%08b", i)) -#define uprint_bin16(i) IGNORE_FORMAT_WARNING(uprintf("%016b", i)) -#define uprint_bin32(i) IGNORE_FORMAT_WARNING(uprintf("%032lb", i)) -#define uprint_bin_reverse8(i) IGNORE_FORMAT_WARNING(uprintf("%08b", bitrev(i))) -#define uprint_bin_reverse16(i) IGNORE_FORMAT_WARNING(uprintf("%016b", bitrev16(i))) -#define uprint_bin_reverse32(i) IGNORE_FORMAT_WARNING(uprintf("%032lb", bitrev32(i))) -/* print value utility */ -#define uprint_val_dec(v) uprintf(#v ": %u\n", v) -#define uprint_val_decs(v) uprintf(#v ": %d\n", v) -#define uprint_val_hex8(v) uprintf(#v ": %X\n", v) -#define uprint_val_hex16(v) uprintf(#v ": %02X\n", v) -#define uprint_val_hex32(v) uprintf(#v ": %04lX\n", v) -#define uprint_val_bin8(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %08b\n", v)) -#define uprint_val_bin16(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %016b\n", v)) -#define uprint_val_bin32(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %032lb\n", v)) -#define uprint_val_bin_reverse8(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %08b\n", bitrev(v))) -#define uprint_val_bin_reverse16(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %016b\n", bitrev16(v))) -#define uprint_val_bin_reverse32(v) IGNORE_FORMAT_WARNING(uprintf(#v ": %032lb\n", bitrev32(v))) diff --git a/quantum/logging/print.mk b/quantum/logging/print.mk deleted file mode 100644 index 658c533dadfc..000000000000 --- a/quantum/logging/print.mk +++ /dev/null @@ -1,12 +0,0 @@ -PRINTF_PATH = $(LIB_PATH)/printf/src - -VPATH += $(PRINTF_PATH) $(PRINTF_PATH)/printf -SRC += printf.c -QUANTUM_SRC +=$(QUANTUM_DIR)/logging/print.c - -OPT_DEFS += -DPRINTF_SUPPORT_DECIMAL_SPECIFIERS=0 -OPT_DEFS += -DPRINTF_SUPPORT_EXPONENTIAL_SPECIFIERS=0 -OPT_DEFS += -DPRINTF_SUPPORT_LONG_LONG=0 -OPT_DEFS += -DPRINTF_SUPPORT_WRITEBACK_SPECIFIER=0 -OPT_DEFS += -DSUPPORT_MSVC_STYLE_INTEGER_SPECIFIERS=0 -OPT_DEFS += -DPRINTF_ALIAS_STANDARD_FUNCTION_NAMES=1 diff --git a/quantum/logging/sendchar.c b/quantum/logging/sendchar.c deleted file mode 100644 index 5bc744b7433c..000000000000 --- a/quantum/logging/sendchar.c +++ /dev/null @@ -1,22 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ -#include "sendchar.h" - -/* default noop "null" implementation */ -__attribute__((weak)) int8_t sendchar(uint8_t c) { - return 0; -} diff --git a/quantum/main.c b/quantum/main.c deleted file mode 100644 index 3b101c522c37..000000000000 --- a/quantum/main.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ - -#include "keyboard.h" - -void platform_setup(void); - -void protocol_setup(void); -void protocol_pre_init(void); -void protocol_post_init(void); -void protocol_pre_task(void); -void protocol_post_task(void); - -// Bodge as refactoring this area sucks.... -void protocol_init(void) __attribute__((weak)); -void protocol_init(void) { - protocol_pre_init(); - - keyboard_init(); - - protocol_post_init(); -} - -void protocol_task(void) __attribute__((weak)); -void protocol_task(void) { - protocol_pre_task(); - - keyboard_task(); - - protocol_post_task(); -} - -/** \brief Main - * - * FIXME: Needs doc - */ -int main(void) __attribute__((weak)); -int main(void) { - platform_setup(); - protocol_setup(); - keyboard_setup(); - - protocol_init(); - - /* Main loop */ - while (true) { - protocol_task(); - -#ifdef QUANTUM_PAINTER_ENABLE - // Run Quantum Painter task - void qp_internal_task(void); - qp_internal_task(); -#endif - -#ifdef DEFERRED_EXEC_ENABLE - // Run deferred executions - void deferred_exec_task(void); - deferred_exec_task(); -#endif // DEFERRED_EXEC_ENABLE - - housekeeping_task(); - } -} diff --git a/quantum/matrix.c b/quantum/matrix.c deleted file mode 100644 index 97d41caedded..000000000000 --- a/quantum/matrix.c +++ /dev/null @@ -1,348 +0,0 @@ -/* -Copyright 2012-2018 Jun Wako, Jack Humbert, Yiancar - -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 . -*/ -#include -#include -#include -#include "util.h" -#include "matrix.h" -#include "debounce.h" -#include "quantum.h" -#ifdef SPLIT_KEYBOARD -# include "split_common/split_util.h" -# include "split_common/transactions.h" - -# define ROWS_PER_HAND (MATRIX_ROWS / 2) -#else -# define ROWS_PER_HAND (MATRIX_ROWS) -#endif - -#ifdef DIRECT_PINS_RIGHT -# define SPLIT_MUTABLE -#else -# define SPLIT_MUTABLE const -#endif -#ifdef MATRIX_ROW_PINS_RIGHT -# define SPLIT_MUTABLE_ROW -#else -# define SPLIT_MUTABLE_ROW const -#endif -#ifdef MATRIX_COL_PINS_RIGHT -# define SPLIT_MUTABLE_COL -#else -# define SPLIT_MUTABLE_COL const -#endif - -#ifndef MATRIX_INPUT_PRESSED_STATE -# define MATRIX_INPUT_PRESSED_STATE 0 -#endif - -#ifdef DIRECT_PINS -static SPLIT_MUTABLE pin_t direct_pins[ROWS_PER_HAND][MATRIX_COLS] = DIRECT_PINS; -#elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) -# ifdef MATRIX_ROW_PINS -static SPLIT_MUTABLE_ROW pin_t row_pins[ROWS_PER_HAND] = MATRIX_ROW_PINS; -# endif // MATRIX_ROW_PINS -# ifdef MATRIX_COL_PINS -static SPLIT_MUTABLE_COL pin_t col_pins[MATRIX_COLS] = MATRIX_COL_PINS; -# endif // MATRIX_COL_PINS -#endif - -/* matrix state(1:on, 0:off) */ -extern matrix_row_t raw_matrix[MATRIX_ROWS]; // raw values -extern matrix_row_t matrix[MATRIX_ROWS]; // debounced values - -#ifdef SPLIT_KEYBOARD -// row offsets for each hand -extern uint8_t thisHand, thatHand; -#endif - -// user-defined overridable functions -__attribute__((weak)) void matrix_init_pins(void); -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row); -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter); - -static inline void setPinOutput_writeLow(pin_t pin) { - ATOMIC_BLOCK_FORCEON { - setPinOutput(pin); - writePinLow(pin); - } -} - -static inline void setPinOutput_writeHigh(pin_t pin) { - ATOMIC_BLOCK_FORCEON { - setPinOutput(pin); - writePinHigh(pin); - } -} - -static inline void setPinInputHigh_atomic(pin_t pin) { - ATOMIC_BLOCK_FORCEON { - setPinInputHigh(pin); - } -} - -static inline uint8_t readMatrixPin(pin_t pin) { - if (pin != NO_PIN) { - return (readPin(pin) == MATRIX_INPUT_PRESSED_STATE) ? 0 : 1; - } else { - return 1; - } -} - -// matrix code - -#ifdef DIRECT_PINS - -__attribute__((weak)) void matrix_init_pins(void) { - for (int row = 0; row < ROWS_PER_HAND; row++) { - for (int col = 0; col < MATRIX_COLS; col++) { - pin_t pin = direct_pins[row][col]; - if (pin != NO_PIN) { - setPinInputHigh(pin); - } - } - } -} - -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { - // Start with a clear matrix row - matrix_row_t current_row_value = 0; - - matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) { - pin_t pin = direct_pins[current_row][col_index]; - current_row_value |= readMatrixPin(pin) ? 0 : row_shifter; - } - - // Update the matrix - current_matrix[current_row] = current_row_value; -} - -#elif defined(DIODE_DIRECTION) -# if defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) -# if (DIODE_DIRECTION == COL2ROW) - -static bool select_row(uint8_t row) { - pin_t pin = row_pins[row]; - if (pin != NO_PIN) { - setPinOutput_writeLow(pin); - return true; - } - return false; -} - -static void unselect_row(uint8_t row) { - pin_t pin = row_pins[row]; - if (pin != NO_PIN) { -# ifdef MATRIX_UNSELECT_DRIVE_HIGH - setPinOutput_writeHigh(pin); -# else - setPinInputHigh_atomic(pin); -# endif - } -} - -static void unselect_rows(void) { - for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - unselect_row(x); - } -} - -__attribute__((weak)) void matrix_init_pins(void) { - unselect_rows(); - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - if (col_pins[x] != NO_PIN) { - setPinInputHigh_atomic(col_pins[x]); - } - } -} - -__attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[], uint8_t current_row) { - // Start with a clear matrix row - matrix_row_t current_row_value = 0; - - if (!select_row(current_row)) { // Select row - return; // skip NO_PIN row - } - matrix_output_select_delay(); - - // For each col... - matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; - for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) { - uint8_t pin_state = readMatrixPin(col_pins[col_index]); - - // Populate the matrix row with the state of the col pin - current_row_value |= pin_state ? 0 : row_shifter; - } - - // Unselect row - unselect_row(current_row); - matrix_output_unselect_delay(current_row, current_row_value != 0); // wait for all Col signals to go HIGH - - // Update the matrix - current_matrix[current_row] = current_row_value; -} - -# elif (DIODE_DIRECTION == ROW2COL) - -static bool select_col(uint8_t col) { - pin_t pin = col_pins[col]; - if (pin != NO_PIN) { - setPinOutput_writeLow(pin); - return true; - } - return false; -} - -static void unselect_col(uint8_t col) { - pin_t pin = col_pins[col]; - if (pin != NO_PIN) { -# ifdef MATRIX_UNSELECT_DRIVE_HIGH - setPinOutput_writeHigh(pin); -# else - setPinInputHigh_atomic(pin); -# endif - } -} - -static void unselect_cols(void) { - for (uint8_t x = 0; x < MATRIX_COLS; x++) { - unselect_col(x); - } -} - -__attribute__((weak)) void matrix_init_pins(void) { - unselect_cols(); - for (uint8_t x = 0; x < ROWS_PER_HAND; x++) { - if (row_pins[x] != NO_PIN) { - setPinInputHigh_atomic(row_pins[x]); - } - } -} - -__attribute__((weak)) void matrix_read_rows_on_col(matrix_row_t current_matrix[], uint8_t current_col, matrix_row_t row_shifter) { - bool key_pressed = false; - - // Select col - if (!select_col(current_col)) { // select col - return; // skip NO_PIN col - } - matrix_output_select_delay(); - - // For each row... - for (uint8_t row_index = 0; row_index < ROWS_PER_HAND; row_index++) { - // Check row pin state - if (readMatrixPin(row_pins[row_index]) == 0) { - // Pin LO, set col bit - current_matrix[row_index] |= row_shifter; - key_pressed = true; - } else { - // Pin HI, clear col bit - current_matrix[row_index] &= ~row_shifter; - } - } - - // Unselect col - unselect_col(current_col); - matrix_output_unselect_delay(current_col, key_pressed); // wait for all Row signals to go HIGH -} - -# else -# error DIODE_DIRECTION must be one of COL2ROW or ROW2COL! -# endif -# endif // defined(MATRIX_ROW_PINS) && defined(MATRIX_COL_PINS) -#else -# error DIODE_DIRECTION is not defined! -#endif - -void matrix_init(void) { -#ifdef SPLIT_KEYBOARD - // Set pinout for right half if pinout for that half is defined - if (!isLeftHand) { -# ifdef DIRECT_PINS_RIGHT - const pin_t direct_pins_right[ROWS_PER_HAND][MATRIX_COLS] = DIRECT_PINS_RIGHT; - for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { - for (uint8_t j = 0; j < MATRIX_COLS; j++) { - direct_pins[i][j] = direct_pins_right[i][j]; - } - } -# endif -# ifdef MATRIX_ROW_PINS_RIGHT - const pin_t row_pins_right[ROWS_PER_HAND] = MATRIX_ROW_PINS_RIGHT; - for (uint8_t i = 0; i < ROWS_PER_HAND; i++) { - row_pins[i] = row_pins_right[i]; - } -# endif -# ifdef MATRIX_COL_PINS_RIGHT - const pin_t col_pins_right[MATRIX_COLS] = MATRIX_COL_PINS_RIGHT; - for (uint8_t i = 0; i < MATRIX_COLS; i++) { - col_pins[i] = col_pins_right[i]; - } -# endif - } - - thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); - thatHand = ROWS_PER_HAND - thisHand; -#endif - - // initialize key pins - matrix_init_pins(); - - // initialize matrix state: all keys off - memset(matrix, 0, sizeof(matrix)); - memset(raw_matrix, 0, sizeof(raw_matrix)); - - debounce_init(ROWS_PER_HAND); - - matrix_init_kb(); -} - -#ifdef SPLIT_KEYBOARD -// Fallback implementation for keyboards not using the standard split_util.c -__attribute__((weak)) bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - transport_master(master_matrix, slave_matrix); - return true; // Treat the transport as always connected -} -#endif - -uint8_t matrix_scan(void) { - matrix_row_t curr_matrix[MATRIX_ROWS] = {0}; - -#if defined(DIRECT_PINS) || (DIODE_DIRECTION == COL2ROW) - // Set row, read cols - for (uint8_t current_row = 0; current_row < ROWS_PER_HAND; current_row++) { - matrix_read_cols_on_row(curr_matrix, current_row); - } -#elif (DIODE_DIRECTION == ROW2COL) - // Set col, read rows - matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; - for (uint8_t current_col = 0; current_col < MATRIX_COLS; current_col++, row_shifter <<= 1) { - matrix_read_rows_on_col(curr_matrix, current_col, row_shifter); - } -#endif - - bool changed = memcmp(raw_matrix, curr_matrix, sizeof(curr_matrix)) != 0; - if (changed) memcpy(raw_matrix, curr_matrix, sizeof(curr_matrix)); - -#ifdef SPLIT_KEYBOARD - changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan(); -#else - changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); - matrix_scan_kb(); -#endif - return (uint8_t)changed; -} diff --git a/quantum/matrix.h b/quantum/matrix.h deleted file mode 100644 index a5b628fc59c9..000000000000 --- a/quantum/matrix.h +++ /dev/null @@ -1,86 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include -#include "gpio.h" - -/* diode directions */ -#define COL2ROW 0 -#define ROW2COL 1 - -#if (MATRIX_COLS <= 8) -typedef uint8_t matrix_row_t; -#elif (MATRIX_COLS <= 16) -typedef uint16_t matrix_row_t; -#elif (MATRIX_COLS <= 32) -typedef uint32_t matrix_row_t; -#else -# error "MATRIX_COLS: invalid value" -#endif - -#define MATRIX_ROW_SHIFTER ((matrix_row_t)1) - -#ifdef __cplusplus -extern "C" { -#endif - -/* number of matrix rows */ -uint8_t matrix_rows(void); -/* number of matrix columns */ -uint8_t matrix_cols(void); -/* should be called at early stage of startup before matrix_init.(optional) */ -void matrix_setup(void); -/* intialize matrix for scaning. */ -void matrix_init(void); -/* scan all key states on matrix */ -uint8_t matrix_scan(void); -/* whether matrix scanning operations should be executed */ -bool matrix_can_read(void); -/* whether a switch is on */ -bool matrix_is_on(uint8_t row, uint8_t col); -/* matrix state on row */ -matrix_row_t matrix_get_row(uint8_t row); -/* print matrix for debug */ -void matrix_print(void); -/* delay between changing matrix pin state and reading values */ -void matrix_output_select_delay(void); -void matrix_output_unselect_delay(uint8_t line, bool key_pressed); -/* only for backwards compatibility. delay between changing matrix pin state and reading values */ -void matrix_io_delay(void); - -/* power control */ -void matrix_power_up(void); -void matrix_power_down(void); - -void matrix_init_kb(void); -void matrix_scan_kb(void); - -void matrix_init_user(void); -void matrix_scan_user(void); - -#ifdef SPLIT_KEYBOARD -bool matrix_post_scan(void); -void matrix_slave_scan_kb(void); -void matrix_slave_scan_user(void); -#endif - -#ifdef __cplusplus -} -#endif diff --git a/quantum/matrix_common.c b/quantum/matrix_common.c deleted file mode 100644 index 3173351888dd..000000000000 --- a/quantum/matrix_common.c +++ /dev/null @@ -1,183 +0,0 @@ -#include "quantum.h" -#include "matrix.h" -#include "debounce.h" -#include "wait.h" -#include "print.h" -#include "debug.h" -#ifdef SPLIT_KEYBOARD -# include "split_common/split_util.h" -# include "split_common/transactions.h" -# include - -# define ROWS_PER_HAND (MATRIX_ROWS / 2) -#else -# define ROWS_PER_HAND (MATRIX_ROWS) -#endif - -#ifndef MATRIX_IO_DELAY -# define MATRIX_IO_DELAY 30 -#endif - -/* matrix state(1:on, 0:off) */ -matrix_row_t raw_matrix[MATRIX_ROWS]; -matrix_row_t matrix[MATRIX_ROWS]; - -#ifdef SPLIT_KEYBOARD -// row offsets for each hand -uint8_t thisHand, thatHand; -#endif - -#ifdef MATRIX_MASKED -extern const matrix_row_t matrix_mask[]; -#endif - -// user-defined overridable functions - -__attribute__((weak)) void matrix_init_kb(void) { - matrix_init_user(); -} - -__attribute__((weak)) void matrix_scan_kb(void) { - matrix_scan_user(); -} - -__attribute__((weak)) void matrix_init_user(void) {} - -__attribute__((weak)) void matrix_scan_user(void) {} - -// helper functions - -inline uint8_t matrix_rows(void) { - return MATRIX_ROWS; -} - -inline uint8_t matrix_cols(void) { - return MATRIX_COLS; -} - -inline bool matrix_is_on(uint8_t row, uint8_t col) { - return (matrix[row] & ((matrix_row_t)1 << col)); -} - -inline matrix_row_t matrix_get_row(uint8_t row) { - // Matrix mask lets you disable switches in the returned matrix data. For example, if you have a - // switch blocker installed and the switch is always pressed. -#ifdef MATRIX_MASKED - return matrix[row] & matrix_mask[row]; -#else - return matrix[row]; -#endif -} - -#if (MATRIX_COLS <= 8) -# define print_matrix_header() print("\nr/c 01234567\n") -# define print_matrix_row(row) print_bin_reverse8(matrix_get_row(row)) -#elif (MATRIX_COLS <= 16) -# define print_matrix_header() print("\nr/c 0123456789ABCDEF\n") -# define print_matrix_row(row) print_bin_reverse16(matrix_get_row(row)) -#elif (MATRIX_COLS <= 32) -# define print_matrix_header() print("\nr/c 0123456789ABCDEF0123456789ABCDEF\n") -# define print_matrix_row(row) print_bin_reverse32(matrix_get_row(row)) -#endif - -void matrix_print(void) { - print_matrix_header(); - - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - print_hex8(row); - print(": "); - print_matrix_row(row); - print("\n"); - } -} - -#ifdef SPLIT_KEYBOARD -bool matrix_post_scan(void) { - bool changed = false; - if (is_keyboard_master()) { - static bool last_connected = false; - matrix_row_t slave_matrix[ROWS_PER_HAND] = {0}; - if (transport_master_if_connected(matrix + thisHand, slave_matrix)) { - changed = memcmp(matrix + thatHand, slave_matrix, sizeof(slave_matrix)) != 0; - - last_connected = true; - } else if (last_connected) { - // reset other half when disconnected - memset(slave_matrix, 0, sizeof(slave_matrix)); - changed = true; - - last_connected = false; - } - - if (changed) memcpy(matrix + thatHand, slave_matrix, sizeof(slave_matrix)); - - matrix_scan_kb(); - } else { - transport_slave(matrix + thatHand, matrix + thisHand); - - matrix_slave_scan_kb(); - } - - return changed; -} -#endif - -/* `matrix_io_delay ()` exists for backwards compatibility. From now on, use matrix_output_unselect_delay(). */ -__attribute__((weak)) void matrix_io_delay(void) { - wait_us(MATRIX_IO_DELAY); -} -__attribute__((weak)) void matrix_output_select_delay(void) { - waitInputPinDelay(); -} -__attribute__((weak)) void matrix_output_unselect_delay(uint8_t line, bool key_pressed) { - matrix_io_delay(); -} - -// CUSTOM MATRIX 'LITE' -__attribute__((weak)) void matrix_init_custom(void) {} -__attribute__((weak)) bool matrix_scan_custom(matrix_row_t current_matrix[]) { - return true; -} - -#ifdef SPLIT_KEYBOARD -__attribute__((weak)) void matrix_slave_scan_kb(void) { - matrix_slave_scan_user(); -} -__attribute__((weak)) void matrix_slave_scan_user(void) {} -#endif - -__attribute__((weak)) void matrix_init(void) { -#ifdef SPLIT_KEYBOARD - thisHand = isLeftHand ? 0 : (ROWS_PER_HAND); - thatHand = ROWS_PER_HAND - thisHand; -#endif - - matrix_init_custom(); - - // initialize matrix state: all keys off - for (uint8_t i = 0; i < MATRIX_ROWS; i++) { - raw_matrix[i] = 0; - matrix[i] = 0; - } - - debounce_init(ROWS_PER_HAND); - - matrix_init_kb(); -} - -__attribute__((weak)) uint8_t matrix_scan(void) { - bool changed = matrix_scan_custom(raw_matrix); - -#ifdef SPLIT_KEYBOARD - changed = debounce(raw_matrix, matrix + thisHand, ROWS_PER_HAND, changed) | matrix_post_scan(); -#else - changed = debounce(raw_matrix, matrix, ROWS_PER_HAND, changed); - matrix_scan_kb(); -#endif - - return changed; -} - -__attribute__((weak)) bool peek_matrix(uint8_t row_index, uint8_t col_index, bool raw) { - return 0 != ((raw ? raw_matrix[row_index] : matrix[row_index]) & (MATRIX_ROW_SHIFTER << col_index)); -} diff --git a/quantum/midi/Config/LUFAConfig.h b/quantum/midi/Config/LUFAConfig.h deleted file mode 100644 index dead96de78d1..000000000000 --- a/quantum/midi/Config/LUFAConfig.h +++ /dev/null @@ -1,91 +0,0 @@ -/* - LUFA Library - Copyright (C) Dean Camera, 2012. - - dean [at] fourwalledcubicle [dot] com - www.lufa-lib.org -*/ - -/* - Copyright 2012 Dean Camera (dean [at] fourwalledcubicle [dot] com) - - Permission to use, copy, modify, distribute, and sell this - software and its documentation for any purpose is hereby granted - without fee, provided that the above copyright notice appear in - all copies and that both that the copyright notice and this - permission notice and warranty disclaimer appear in supporting - documentation, and that the name of the author not be used in - advertising or publicity pertaining to distribution of the - software without specific, written prior permission. - - The author disclaim all warranties with regard to this - software, including all implied warranties of merchantability - and fitness. In no event shall the author be liable for any - special, indirect or consequential damages or any damages - whatsoever resulting from loss of use, data or profits, whether - in an action of contract, negligence or other tortious action, - arising out of or in connection with the use or performance of - this software. -*/ - -/** \file - * \brief LUFA Library Configuration Header File - * - * This header file is used to configure LUFA's compile time options, - * as an alternative to the compile time constants supplied through - * a makefile. - * - * For information on what each token does, refer to the LUFA - * manual section "Summary of Compile Tokens". - */ - -#pragma once - -#if (ARCH == ARCH_AVR8) - -/* Non-USB Related Configuration Tokens: */ -// #define DISABLE_TERMINAL_CODES - -/* USB Class Driver Related Tokens: */ -// #define HID_HOST_BOOT_PROTOCOL_ONLY -// #define HID_STATETABLE_STACK_DEPTH {Insert Value Here} -// #define HID_USAGE_STACK_DEPTH {Insert Value Here} -// #define HID_MAX_COLLECTIONS {Insert Value Here} -// #define HID_MAX_REPORTITEMS {Insert Value Here} -// #define HID_MAX_REPORT_IDS {Insert Value Here} -// #define NO_CLASS_DRIVER_AUTOFLUSH - -/* General USB Driver Related Tokens: */ -// #define ORDERED_EP_CONFIG -# define USE_STATIC_OPTIONS (USB_DEVICE_OPT_FULLSPEED | USB_OPT_REG_ENABLED | USB_OPT_AUTO_PLL) -# define USB_DEVICE_ONLY -// #define USB_HOST_ONLY -// #define USB_STREAM_TIMEOUT_MS {Insert Value Here} -// #define NO_LIMITED_CONTROLLER_CONNECT -// #define NO_SOF_EVENTS - -/* USB Device Mode Driver Related Tokens: */ -// #define USE_RAM_DESCRIPTORS -# define USE_FLASH_DESCRIPTORS -// #define USE_EEPROM_DESCRIPTORS -// #define NO_INTERNAL_SERIAL -# define FIXED_CONTROL_ENDPOINT_SIZE 8 -// #define DEVICE_STATE_AS_GPIOR {Insert Value Here} -# define FIXED_NUM_CONFIGURATIONS 1 -// #define CONTROL_ONLY_DEVICE -// #define INTERRUPT_CONTROL_ENDPOINT -// #define NO_DEVICE_REMOTE_WAKEUP -// #define NO_DEVICE_SELF_POWER - -/* USB Host Mode Driver Related Tokens: */ -// #define HOST_STATE_AS_GPIOR {Insert Value Here} -// #define USB_HOST_TIMEOUT_MS {Insert Value Here} -// #define HOST_DEVICE_SETTLE_DELAY_MS {Insert Value Here} -// #define NO_AUTO_VBUS_MANAGEMENT -// #define INVERTED_VBUS_ENABLE_LINE - -#else - -# error Unsupported architecture for this LUFA configuration file. - -#endif diff --git a/quantum/midi/bytequeue/COPYING b/quantum/midi/bytequeue/COPYING deleted file mode 100755 index 94a9ed024d38..000000000000 --- a/quantum/midi/bytequeue/COPYING +++ /dev/null @@ -1,674 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - 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 3 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 . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. diff --git a/quantum/midi/bytequeue/bytequeue.c b/quantum/midi/bytequeue/bytequeue.c deleted file mode 100644 index 0dd18680f0cb..000000000000 --- a/quantum/midi/bytequeue/bytequeue.c +++ /dev/null @@ -1,64 +0,0 @@ -// this is a single reader [maybe multiple writer?] byte queue -// Copyright 2008 Alex Norman -// writen by Alex Norman -// -// This file is part of avr-bytequeue. -// -// avr-bytequeue 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 3 of the License, or -//(at your option) any later version. -// -// avr-bytequeue 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 avr-bytequeue. If not, see . - -#include "bytequeue.h" -#include "interrupt_setting.h" - -void bytequeue_init(byteQueue_t* queue, uint8_t* dataArray, byteQueueIndex_t arrayLen) { - queue->length = arrayLen; - queue->data = dataArray; - queue->start = queue->end = 0; -} - -bool bytequeue_enqueue(byteQueue_t* queue, uint8_t item) { - interrupt_setting_t setting = store_and_clear_interrupt(); - // full - if (((queue->end + 1) % queue->length) == queue->start) { - restore_interrupt_setting(setting); - return false; - } else { - queue->data[queue->end] = item; - queue->end = (queue->end + 1) % queue->length; - restore_interrupt_setting(setting); - return true; - } -} - -byteQueueIndex_t bytequeue_length(byteQueue_t* queue) { - byteQueueIndex_t len; - interrupt_setting_t setting = store_and_clear_interrupt(); - if (queue->end >= queue->start) - len = queue->end - queue->start; - else - len = (queue->length - queue->start) + queue->end; - restore_interrupt_setting(setting); - return len; -} - -// we don't need to avoid interrupts if there is only one reader -uint8_t bytequeue_get(byteQueue_t* queue, byteQueueIndex_t index) { - return queue->data[(queue->start + index) % queue->length]; -} - -// we just update the start index to remove elements -void bytequeue_remove(byteQueue_t* queue, byteQueueIndex_t numToRemove) { - interrupt_setting_t setting = store_and_clear_interrupt(); - queue->start = (queue->start + numToRemove) % queue->length; - restore_interrupt_setting(setting); -} diff --git a/quantum/midi/bytequeue/bytequeue.h b/quantum/midi/bytequeue/bytequeue.h deleted file mode 100644 index 29d15abbd38a..000000000000 --- a/quantum/midi/bytequeue/bytequeue.h +++ /dev/null @@ -1,55 +0,0 @@ -// this is a single reader [maybe multiple writer?] byte queue -// Copyright 2008 Alex Norman -// writen by Alex Norman -// -// This file is part of avr-bytequeue. -// -// avr-bytequeue 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 3 of the License, or -//(at your option) any later version. -// -// avr-bytequeue 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 avr-bytequeue. If not, see . - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -typedef uint8_t byteQueueIndex_t; - -typedef struct { - byteQueueIndex_t start; - byteQueueIndex_t end; - byteQueueIndex_t length; - uint8_t* data; -} byteQueue_t; - -// you must have a queue, an array of data which the queue will use, and the length of that array -void bytequeue_init(byteQueue_t* queue, uint8_t* dataArray, byteQueueIndex_t arrayLen); - -// add an item to the queue, returns false if the queue is full -bool bytequeue_enqueue(byteQueue_t* queue, uint8_t item); - -// get the length of the queue -byteQueueIndex_t bytequeue_length(byteQueue_t* queue); - -// this grabs data at the index given [starting at queue->start] -uint8_t bytequeue_get(byteQueue_t* queue, byteQueueIndex_t index); - -// update the index in the queue to reflect data that has been dealt with -void bytequeue_remove(byteQueue_t* queue, byteQueueIndex_t numToRemove); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/midi/bytequeue/interrupt_setting.c b/quantum/midi/bytequeue/interrupt_setting.c deleted file mode 100644 index d9c003594663..000000000000 --- a/quantum/midi/bytequeue/interrupt_setting.c +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 20010 Alex Norman -// writen by Alex Norman -// -// This file is part of avr-bytequeue. -// -// avr-bytequeue 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 3 of the License, or -//(at your option) any later version. -// -// avr-bytequeue 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 avr-bytequeue. If not, see . - -// AVR specific code -// should be able to port to other systems by simply providing chip specific -// implementations of the typedef and these functions - -#include "interrupt_setting.h" -#if defined(__AVR__) -# include - -interrupt_setting_t store_and_clear_interrupt(void) { - uint8_t sreg = SREG; - cli(); - return sreg; -} - -void restore_interrupt_setting(interrupt_setting_t setting) { - SREG = setting; -} -#elif defined(__arm__) -# include - -interrupt_setting_t store_and_clear_interrupt(void) { - chSysLock(); - return 0; -} - -void restore_interrupt_setting(interrupt_setting_t setting) { - chSysUnlock(); -} -#endif diff --git a/quantum/midi/bytequeue/interrupt_setting.h b/quantum/midi/bytequeue/interrupt_setting.h deleted file mode 100644 index 78294f07657e..000000000000 --- a/quantum/midi/bytequeue/interrupt_setting.h +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 20010 Alex Norman -// writen by Alex Norman -// -// This file is part of avr-bytequeue. -// -// avr-bytequeue 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 3 of the License, or -//(at your option) any later version. -// -// avr-bytequeue 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 avr-bytequeue. If not, see . - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -// AVR specific typedef -typedef uint8_t interrupt_setting_t; - -interrupt_setting_t store_and_clear_interrupt(void); -void restore_interrupt_setting(interrupt_setting_t setting); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/midi/midi.c b/quantum/midi/midi.c deleted file mode 100644 index 1c481f2f0b38..000000000000 --- a/quantum/midi/midi.c +++ /dev/null @@ -1,244 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -#include "midi.h" -#include //for memcpy -#include "util.h" - -#ifndef NULL -# define NULL 0 -#endif - -bool midi_is_statusbyte(uint8_t theByte) { - return (bool)(theByte & MIDI_STATUSMASK); -} - -bool midi_is_realtime(uint8_t theByte) { - return (theByte >= MIDI_CLOCK); -} - -midi_packet_length_t midi_packet_length(uint8_t status) { - switch (status & 0xF0) { - case MIDI_CC: - case MIDI_NOTEON: - case MIDI_NOTEOFF: - case MIDI_AFTERTOUCH: - case MIDI_PITCHBEND: - return THREE; - case MIDI_PROGCHANGE: - case MIDI_CHANPRESSURE: - case MIDI_SONGSELECT: - return TWO; - case 0xF0: - switch (status) { - case MIDI_CLOCK: - case MIDI_TICK: - case MIDI_START: - case MIDI_CONTINUE: - case MIDI_STOP: - case MIDI_ACTIVESENSE: - case MIDI_RESET: - case MIDI_TUNEREQUEST: - return ONE; - case MIDI_SONGPOSITION: - return THREE; - case MIDI_TC_QUARTERFRAME: - case MIDI_SONGSELECT: - return TWO; - case SYSEX_END: - case SYSEX_BEGIN: - default: - return UNDEFINED; - } - default: - return UNDEFINED; - } -} - -void midi_send_cc(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t val) { - // CC Status: 0xB0 to 0xBF where the low nibble is the MIDI channel. - // CC Data: Controller Num, Controller Val - device->send_func(device, 3, MIDI_CC | (chan & MIDI_CHANMASK), num & 0x7F, val & 0x7F); -} - -void midi_send_noteon(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t vel) { - // Note Data: Note Num, Note Velocity - device->send_func(device, 3, MIDI_NOTEON | (chan & MIDI_CHANMASK), num & 0x7F, vel & 0x7F); -} - -void midi_send_noteoff(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t vel) { - // Note Data: Note Num, Note Velocity - device->send_func(device, 3, MIDI_NOTEOFF | (chan & MIDI_CHANMASK), num & 0x7F, vel & 0x7F); -} - -void midi_send_aftertouch(MidiDevice* device, uint8_t chan, uint8_t note_num, uint8_t amt) { - device->send_func(device, 3, MIDI_AFTERTOUCH | (chan & MIDI_CHANMASK), note_num & 0x7F, amt & 0x7F); -} - -// XXX does this work right? -// amt in range -0x2000, 0x1fff -// uAmt should be in range.. -// 0x0000 to 0x3FFF -void midi_send_pitchbend(MidiDevice* device, uint8_t chan, int16_t amt) { - uint16_t uAmt; - // check range - if (amt > 0x1fff) { - uAmt = 0x3FFF; - } else if (amt < -0x2000) { - uAmt = 0; - } else { - uAmt = amt + 0x2000; - } - device->send_func(device, 3, MIDI_PITCHBEND | (chan & MIDI_CHANMASK), uAmt & 0x7F, (uAmt >> 7) & 0x7F); -} - -void midi_send_programchange(MidiDevice* device, uint8_t chan, uint8_t num) { - device->send_func(device, 2, MIDI_PROGCHANGE | (chan & MIDI_CHANMASK), num & 0x7F, 0); -} - -void midi_send_channelpressure(MidiDevice* device, uint8_t chan, uint8_t amt) { - device->send_func(device, 2, MIDI_CHANPRESSURE | (chan & MIDI_CHANMASK), amt & 0x7F, 0); -} - -void midi_send_clock(MidiDevice* device) { - device->send_func(device, 1, MIDI_CLOCK, 0, 0); -} - -void midi_send_tick(MidiDevice* device) { - device->send_func(device, 1, MIDI_TICK, 0, 0); -} - -void midi_send_start(MidiDevice* device) { - device->send_func(device, 1, MIDI_START, 0, 0); -} - -void midi_send_continue(MidiDevice* device) { - device->send_func(device, 1, MIDI_CONTINUE, 0, 0); -} - -void midi_send_stop(MidiDevice* device) { - device->send_func(device, 1, MIDI_STOP, 0, 0); -} - -void midi_send_activesense(MidiDevice* device) { - device->send_func(device, 1, MIDI_ACTIVESENSE, 0, 0); -} - -void midi_send_reset(MidiDevice* device) { - device->send_func(device, 1, MIDI_RESET, 0, 0); -} - -void midi_send_tcquarterframe(MidiDevice* device, uint8_t time) { - device->send_func(device, 2, MIDI_TC_QUARTERFRAME, time & 0x7F, 0); -} - -// XXX is this right? -void midi_send_songposition(MidiDevice* device, uint16_t pos) { - device->send_func(device, 3, MIDI_SONGPOSITION, pos & 0x7F, (pos >> 7) & 0x7F); -} - -void midi_send_songselect(MidiDevice* device, uint8_t song) { - device->send_func(device, 2, MIDI_SONGSELECT, song & 0x7F, 0); -} - -void midi_send_tunerequest(MidiDevice* device) { - device->send_func(device, 1, MIDI_TUNEREQUEST, 0, 0); -} - -void midi_send_byte(MidiDevice* device, uint8_t b) { - device->send_func(device, 1, b, 0, 0); -} - -void midi_send_data(MidiDevice* device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2) { - // ensure that the count passed along is always 3 or lower - if (count > 3) { - // TODO how to do this correctly? - } - device->send_func(device, count, byte0, byte1, byte2); -} - -void midi_send_array(MidiDevice* device, uint16_t count, uint8_t* array) { - uint16_t i; - for (i = 0; i < count; i += 3) { - uint8_t b[3] = {0, 0, 0}; - uint16_t to_send = count - i; - to_send = (to_send > 3) ? 3 : to_send; - memcpy(b, array + i, to_send); - midi_send_data(device, to_send, b[0], b[1], b[2]); - } -} - -void midi_register_cc_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_cc_callback = func; -} - -void midi_register_noteon_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_noteon_callback = func; -} - -void midi_register_noteoff_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_noteoff_callback = func; -} - -void midi_register_aftertouch_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_aftertouch_callback = func; -} - -void midi_register_pitchbend_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_pitchbend_callback = func; -} - -void midi_register_songposition_callback(MidiDevice* device, midi_three_byte_func_t func) { - device->input_songposition_callback = func; -} - -void midi_register_progchange_callback(MidiDevice* device, midi_two_byte_func_t func) { - device->input_progchange_callback = func; -} - -void midi_register_chanpressure_callback(MidiDevice* device, midi_two_byte_func_t func) { - device->input_chanpressure_callback = func; -} - -void midi_register_songselect_callback(MidiDevice* device, midi_two_byte_func_t func) { - device->input_songselect_callback = func; -} - -void midi_register_tc_quarterframe_callback(MidiDevice* device, midi_two_byte_func_t func) { - device->input_tc_quarterframe_callback = func; -} - -void midi_register_realtime_callback(MidiDevice* device, midi_one_byte_func_t func) { - device->input_realtime_callback = func; -} - -void midi_register_tunerequest_callback(MidiDevice* device, midi_one_byte_func_t func) { - device->input_tunerequest_callback = func; -} - -void midi_register_sysex_callback(MidiDevice* device, midi_sysex_func_t func) { - device->input_sysex_callback = func; -} - -void midi_register_fallthrough_callback(MidiDevice* device, midi_var_byte_func_t func) { - device->input_fallthrough_callback = func; -} - -void midi_register_catchall_callback(MidiDevice* device, midi_var_byte_func_t func) { - device->input_catchall_callback = func; -} diff --git a/quantum/midi/midi.h b/quantum/midi/midi.h deleted file mode 100644 index 34547077e49e..000000000000 --- a/quantum/midi/midi.h +++ /dev/null @@ -1,487 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -/** - * @file - * @brief The main midi functions - * - * This file includes all of the functions you need to set up and process a - * midi device, send midi, and register midi callbacks. - * - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include "midi_device.h" -#include "midi_function_types.h" - -/** - * @defgroup midi_device_setup_process Device initialization and processing - * @brief These are method that you must use to initialize and run a device - * - * @{ - */ - -/** - * @brief Initialize a device - * - * You must call this before using the device in question. - * - * @param device the device to initialize - */ -void midi_device_init(MidiDevice* device); // [implementation in midi_device.c] - -/** - * @brief Process input data - * - * This method drives the input processing, you must call this method frequently - * if you expect to have your input callbacks called. - * - * @param device the device to process - */ -void midi_device_process(MidiDevice* device); // [implementation in midi_device.c] - -/**@}*/ - -/** - * @defgroup send_functions Midi send functions - * @brief These are the functions you use to send midi data through a device. - * @{ - */ - -/** - * @brief Send a control change message (cc) via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param num the cc num - * @param val the value of that cc num - */ -void midi_send_cc(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t val); - -/** - * @brief Send a note on message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param num the note number - * @param vel the note velocity - */ -void midi_send_noteon(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t vel); - -/** - * @brief Send a note off message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param num the note number - * @param vel the note velocity - */ -void midi_send_noteoff(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t vel); - -/** - * @brief Send an after touch message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param note_num the note number - * @param amt the after touch amount - */ -void midi_send_aftertouch(MidiDevice* device, uint8_t chan, uint8_t note_num, uint8_t amt); - -/** - * @brief Send a pitch bend message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param amt the bend amount range: -8192..8191, 0 means no bend - */ -void midi_send_pitchbend(MidiDevice* device, uint8_t chan, int16_t amt); // range -8192, 8191 - -/** - * @brief Send a program change message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param num the program to change to - */ -void midi_send_programchange(MidiDevice* device, uint8_t chan, uint8_t num); - -/** - * @brief Send a channel pressure message via the given device. - * - * @param device the device to use for sending - * @param chan the channel to send on, 0-15 - * @param amt the amount of channel pressure - */ -void midi_send_channelpressure(MidiDevice* device, uint8_t chan, uint8_t amt); - -/** - * @brief Send a clock message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_clock(MidiDevice* device); - -/** - * @brief Send a tick message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_tick(MidiDevice* device); - -/** - * @brief Send a start message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_start(MidiDevice* device); - -/** - * @brief Send a continue message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_continue(MidiDevice* device); - -/** - * @brief Send a stop message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_stop(MidiDevice* device); - -/** - * @brief Send an active sense message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_activesense(MidiDevice* device); - -/** - * @brief Send a reset message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_reset(MidiDevice* device); - -/** - * @brief Send a tc quarter frame message via the given device. - * - * @param device the device to use for sending - * @param time the time of this quarter frame, range 0..16383 - */ -void midi_send_tcquarterframe(MidiDevice* device, uint8_t time); - -/** - * @brief Send a song position message via the given device. - * - * @param device the device to use for sending - * @param pos the song position - */ -void midi_send_songposition(MidiDevice* device, uint16_t pos); - -/** - * @brief Send a song select message via the given device. - * - * @param device the device to use for sending - * @param song the song to select - */ -void midi_send_songselect(MidiDevice* device, uint8_t song); - -/** - * @brief Send a tune request message via the given device. - * - * @param device the device to use for sending - */ -void midi_send_tunerequest(MidiDevice* device); - -/** - * @brief Send a byte via the given device. - * - * This is a generic method for sending data via the given midi device. - * This would be useful for sending sysex data or messages that are not - * implemented in this API, if there are any. Please contact the author - * if you find some so we can add them. - * - * @param device the device to use for sending - * @param b the byte to send - */ -void midi_send_byte(MidiDevice* device, uint8_t b); - -/** - * @brief Send up to 3 bytes of data - * - * % 4 is applied to count so that you can use this to pass sysex through - * - * @param device the device to use for sending - * @param count the count of bytes to send, %4 is applied - * @param byte0 the first byte - * @param byte1 the second byte, ignored if cnt % 4 != 2 - * @param byte2 the third byte, ignored if cnt % 4 != 3 - */ -void midi_send_data(MidiDevice* device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2); - -/** - * @brief Send an array of formatted midi data. - * - * Can be used for sysex. - * - * @param device the device to use for sending - * @param count the count of bytes to send - * @param array the array of bytes - */ -void midi_send_array(MidiDevice* device, uint16_t count, uint8_t* array); - -/**@}*/ - -/** - * @defgroup input_callback_reg Input callback registration functions - * - * @brief These are the functions you use to register your input callbacks. - * - * The functions are called when the appropriate midi message is matched on the - * associated device's input. - * - * @{ - */ - -// three byte funcs - -/** - * @brief Register a control change message (cc) callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_cc_callback(MidiDevice* device, midi_three_byte_func_t func); - -/** - * @brief Register a note on callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_noteon_callback(MidiDevice* device, midi_three_byte_func_t func); - -/** - * @brief Register a note off callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_noteoff_callback(MidiDevice* device, midi_three_byte_func_t func); - -/** - * @brief Register an after touch callback. - * - * @param device the device associate with - * @param func the callback function to register - */ - -void midi_register_aftertouch_callback(MidiDevice* device, midi_three_byte_func_t func); - -/** - * @brief Register a pitch bend callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_pitchbend_callback(MidiDevice* device, midi_three_byte_func_t func); - -/** - * @brief Register a song position callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_songposition_callback(MidiDevice* device, midi_three_byte_func_t func); - -// two byte funcs - -/** - * @brief Register a program change callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_progchange_callback(MidiDevice* device, midi_two_byte_func_t func); - -/** - * @brief Register a channel pressure callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_chanpressure_callback(MidiDevice* device, midi_two_byte_func_t func); - -/** - * @brief Register a song select callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_songselect_callback(MidiDevice* device, midi_two_byte_func_t func); - -/** - * @brief Register a tc quarter frame callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_tc_quarterframe_callback(MidiDevice* device, midi_two_byte_func_t func); - -// one byte funcs - -/** - * @brief Register a realtime callback. - * - * The callback will be called for all of the real time message types. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_realtime_callback(MidiDevice* device, midi_one_byte_func_t func); - -/** - * @brief Register a tune request callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_tunerequest_callback(MidiDevice* device, midi_one_byte_func_t func); - -/** - * @brief Register a sysex callback. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_sysex_callback(MidiDevice* device, midi_sysex_func_t func); - -/** - * @brief Register fall through callback. - * - * This is only called if a more specific callback is not matched and called. - * For instance, if you don't register a note on callback but you get a note on message - * the fall through callback will be called, if it is registered. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_fallthrough_callback(MidiDevice* device, midi_var_byte_func_t func); - -/** - * @brief Register a catch all callback. - * - * If registered, the catch all callback is called for every message that is - * matched, even if a more specific or the fallthrough callback is registered. - * - * @param device the device associate with - * @param func the callback function to register - */ -void midi_register_catchall_callback(MidiDevice* device, midi_var_byte_func_t func); - -/**@}*/ - -/** - * @defgroup midi_util Device independent utility functions. - * @{ - */ - -/** - * \enum midi_packet_length_t - * - * An enumeration of the possible packet length values. - */ -typedef enum { UNDEFINED = 0, ONE = 1, TWO = 2, THREE = 3 } midi_packet_length_t; - -/** - * @brief Test to see if the byte given is a status byte - * @param theByte the byte to test - * @return true if the byte given is a midi status byte - */ -bool midi_is_statusbyte(uint8_t theByte); - -/** - * @brief Test to see if the byte given is a realtime message - * @param theByte the byte to test - * @return true if it is a realtime message, false otherwise - */ -bool midi_is_realtime(uint8_t theByte); - -/** - * @brief Find the length of the packet associated with the status byte given - * @param status the status byte - * @return the length of the packet, will return UNDEFINED if the byte is not - * a status byte or if it is a sysex status byte - */ -midi_packet_length_t midi_packet_length(uint8_t status); - -/**@}*/ - -/** - * @defgroup defines Midi status and miscellaneous utility #defines - * - * @{ - */ - -#define SYSEX_BEGIN 0xF0 -#define SYSEX_END 0xF7 - -// if you and this with a byte and you get anything non-zero -// it is a status message -#define MIDI_STATUSMASK 0x80 -// if you and this with a status message that contains channel info, -// you'll get the channel -#define MIDI_CHANMASK 0x0F - -#define MIDI_CC 0xB0 -#define MIDI_NOTEON 0x90 -#define MIDI_NOTEOFF 0x80 -#define MIDI_AFTERTOUCH 0xA0 -#define MIDI_PITCHBEND 0xE0 -#define MIDI_PROGCHANGE 0xC0 -#define MIDI_CHANPRESSURE 0xD0 - -// midi realtime -#define MIDI_CLOCK 0xF8 -#define MIDI_TICK 0xF9 -#define MIDI_START 0xFA -#define MIDI_CONTINUE 0xFB -#define MIDI_STOP 0xFC -#define MIDI_ACTIVESENSE 0xFE -#define MIDI_RESET 0xFF - -#define MIDI_TC_QUARTERFRAME 0xF1 -#define MIDI_SONGPOSITION 0xF2 -#define MIDI_SONGSELECT 0xF3 -#define MIDI_TUNEREQUEST 0xF6 - -// This ID is for educational or development use only -#define SYSEX_EDUMANUFID 0x7D - -/**@}*/ - -#ifdef __cplusplus -} -#endif diff --git a/quantum/midi/midi_device.c b/quantum/midi/midi_device.c deleted file mode 100644 index 77c010b15623..000000000000 --- a/quantum/midi/midi_device.c +++ /dev/null @@ -1,277 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -#include "midi_device.h" -#include "midi.h" - -#ifndef NULL -# define NULL 0 -#endif - -// forward declarations, internally used to call the callbacks -void midi_input_callbacks(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2); -void midi_process_byte(MidiDevice* device, uint8_t input); - -void midi_device_init(MidiDevice* device) { - device->input_state = IDLE; - device->input_count = 0; - bytequeue_init(&device->input_queue, device->input_queue_data, MIDI_INPUT_QUEUE_LENGTH); - - // three byte funcs - device->input_cc_callback = NULL; - device->input_noteon_callback = NULL; - device->input_noteoff_callback = NULL; - device->input_aftertouch_callback = NULL; - device->input_pitchbend_callback = NULL; - device->input_songposition_callback = NULL; - - // two byte funcs - device->input_progchange_callback = NULL; - device->input_chanpressure_callback = NULL; - device->input_songselect_callback = NULL; - device->input_tc_quarterframe_callback = NULL; - - // one byte funcs - device->input_realtime_callback = NULL; - device->input_tunerequest_callback = NULL; - - // var byte functions - device->input_sysex_callback = NULL; - device->input_fallthrough_callback = NULL; - device->input_catchall_callback = NULL; - - device->pre_input_process_callback = NULL; -} - -void midi_device_input(MidiDevice* device, uint8_t cnt, uint8_t* input) { - uint8_t i; - for (i = 0; i < cnt; i++) - bytequeue_enqueue(&device->input_queue, input[i]); -} - -void midi_device_set_send_func(MidiDevice* device, midi_var_byte_func_t send_func) { - device->send_func = send_func; -} - -void midi_device_set_pre_input_process_func(MidiDevice* device, midi_no_byte_func_t pre_process_func) { - device->pre_input_process_callback = pre_process_func; -} - -void midi_device_process(MidiDevice* device) { - // call the pre_input_process_callback if there is one - if (device->pre_input_process_callback) device->pre_input_process_callback(device); - - // pull stuff off the queue and process - byteQueueIndex_t len = bytequeue_length(&device->input_queue); - uint16_t i; - // TODO limit number of bytes processed? - for (i = 0; i < len; i++) { - uint8_t val = bytequeue_get(&device->input_queue, 0); - midi_process_byte(device, val); - bytequeue_remove(&device->input_queue, 1); - } -} - -void midi_process_byte(MidiDevice* device, uint8_t input) { - if (midi_is_realtime(input)) { - // call callback, store and restore state - input_state_t state = device->input_state; - device->input_state = ONE_BYTE_MESSAGE; - midi_input_callbacks(device, 1, input, 0, 0); - device->input_state = state; - } else if (midi_is_statusbyte(input)) { - // store the byte - if (device->input_state != SYSEX_MESSAGE) { - device->input_buffer[0] = input; - device->input_count = 1; - } - switch (midi_packet_length(input)) { - case ONE: - device->input_state = ONE_BYTE_MESSAGE; - ; - midi_input_callbacks(device, 1, input, 0, 0); - device->input_state = IDLE; - break; - case TWO: - device->input_state = TWO_BYTE_MESSAGE; - break; - case THREE: - device->input_state = THREE_BYTE_MESSAGE; - break; - case UNDEFINED: - switch (input) { - case SYSEX_BEGIN: - device->input_state = SYSEX_MESSAGE; - device->input_buffer[0] = input; - device->input_count = 1; - break; - case SYSEX_END: - // send what is left in the input buffer, set idle - device->input_buffer[device->input_count % 3] = input; - device->input_count += 1; - // call the callback - midi_input_callbacks(device, device->input_count, device->input_buffer[0], device->input_buffer[1], device->input_buffer[2]); - device->input_state = IDLE; - break; - default: - device->input_state = IDLE; - device->input_count = 0; - } - - break; - default: - device->input_state = IDLE; - device->input_count = 0; - break; - } - } else { - if (device->input_state != IDLE) { - // store the byte - device->input_buffer[device->input_count % 3] = input; - // increment count - uint16_t prev = device->input_count; - device->input_count += 1; - - switch (prev % 3) { - case 2: - // call callback - midi_input_callbacks(device, device->input_count, device->input_buffer[0], device->input_buffer[1], device->input_buffer[2]); - if (device->input_state != SYSEX_MESSAGE) { - // set to 1, keeping status byte, allowing for running status - device->input_count = 1; - } - break; - case 1: - if (device->input_state == TWO_BYTE_MESSAGE) { - // call callback - midi_input_callbacks(device, device->input_count, device->input_buffer[0], device->input_buffer[1], 0); - if (device->input_state != SYSEX_MESSAGE) { - // set to 1, keeping status byte, allowing for running status - device->input_count = 1; - } - } - break; - case 0: - default: - // one byte messages are dealt with directly - break; - } - } - } -} - -void midi_input_callbacks(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { - // did we end up calling a callback? - bool called = false; - if (device->input_state == SYSEX_MESSAGE) { - if (device->input_sysex_callback) { - const uint16_t start = ((cnt - 1) / 3) * 3; - const uint8_t length = (cnt - start); - uint8_t data[3]; - data[0] = byte0; - data[1] = byte1; - data[2] = byte2; - device->input_sysex_callback(device, start, length, data); - called = true; - } - } else { - switch (cnt) { - case 3: { - midi_three_byte_func_t func = NULL; - switch (byte0 & 0xF0) { - case MIDI_CC: - func = device->input_cc_callback; - break; - case MIDI_NOTEON: - func = device->input_noteon_callback; - break; - case MIDI_NOTEOFF: - func = device->input_noteoff_callback; - break; - case MIDI_AFTERTOUCH: - func = device->input_aftertouch_callback; - break; - case MIDI_PITCHBEND: - func = device->input_pitchbend_callback; - break; - case 0xF0: - if (byte0 == MIDI_SONGPOSITION) func = device->input_songposition_callback; - break; - default: - break; - } - if (func) { - // mask off the channel for non song position functions - if (byte0 == MIDI_SONGPOSITION) - func(device, byte0, byte1, byte2); - else - func(device, byte0 & 0x0F, byte1, byte2); - called = true; - } - } break; - case 2: { - midi_two_byte_func_t func = NULL; - switch (byte0 & 0xF0) { - case MIDI_PROGCHANGE: - func = device->input_progchange_callback; - break; - case MIDI_CHANPRESSURE: - func = device->input_chanpressure_callback; - break; - case 0xF0: - if (byte0 == MIDI_SONGSELECT) - func = device->input_songselect_callback; - else if (byte0 == MIDI_TC_QUARTERFRAME) - func = device->input_tc_quarterframe_callback; - break; - default: - break; - } - if (func) { - // mask off the channel - if (byte0 == MIDI_SONGSELECT || byte0 == MIDI_TC_QUARTERFRAME) - func(device, byte0, byte1); - else - func(device, byte0 & 0x0F, byte1); - called = true; - } - } break; - case 1: { - midi_one_byte_func_t func = NULL; - if (midi_is_realtime(byte0)) - func = device->input_realtime_callback; - else if (byte0 == MIDI_TUNEREQUEST) - func = device->input_tunerequest_callback; - if (func) { - func(device, byte0); - called = true; - } - } break; - default: - // just in case - if (cnt > 3) cnt = 0; - break; - } - } - - // if there is fallthrough default callback and we haven't called a more specific one, - // call the fallthrough - if (!called && device->input_fallthrough_callback) device->input_fallthrough_callback(device, cnt, byte0, byte1, byte2); - // always call the catch all if it exists - if (device->input_catchall_callback) device->input_catchall_callback(device, cnt, byte0, byte1, byte2); -} diff --git a/quantum/midi/midi_device.h b/quantum/midi/midi_device.h deleted file mode 100644 index 79e8f7a9369b..000000000000 --- a/quantum/midi/midi_device.h +++ /dev/null @@ -1,148 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -/** - * @file - * @brief Device implementation functions - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup midi_device Functions used when implementing your own midi device. - * - * You use the functions when you are implementing your own midi device. - * - * You set a send function to actually send bytes via your device, this method - * is called when you call a send function with this device, for instance - * midi_send_cc - * - * You use the midi_device_input to process input data from the device and pass - * it through the device's associated callbacks. - * - * You use the midi_device_set_pre_input_process_func if you want to have a - * function called at the beginning of the device's process function, generally - * to poll for input and pass that into midi_device_input - * - * @{ - */ - -#include "midi_function_types.h" -#include "bytequeue/bytequeue.h" -#define MIDI_INPUT_QUEUE_LENGTH 192 - -typedef enum { IDLE, ONE_BYTE_MESSAGE = 1, TWO_BYTE_MESSAGE = 2, THREE_BYTE_MESSAGE = 3, SYSEX_MESSAGE } input_state_t; - -typedef void (*midi_no_byte_func_t)(MidiDevice* device); - -/** - * \struct _midi_device - * - * @brief This structure represents the input and output functions and - * processing data for a midi device. - * - * A device can represent an actual physical device [serial port, usb port] or - * something virtual. - * You should not need to modify this structure directly. - */ -struct _midi_device { - // output send function - midi_var_byte_func_t send_func; - - //********input callbacks - // three byte funcs - midi_three_byte_func_t input_cc_callback; - midi_three_byte_func_t input_noteon_callback; - midi_three_byte_func_t input_noteoff_callback; - midi_three_byte_func_t input_aftertouch_callback; - midi_three_byte_func_t input_pitchbend_callback; - midi_three_byte_func_t input_songposition_callback; - // two byte funcs - midi_two_byte_func_t input_progchange_callback; - midi_two_byte_func_t input_chanpressure_callback; - midi_two_byte_func_t input_songselect_callback; - midi_two_byte_func_t input_tc_quarterframe_callback; - // one byte funcs - midi_one_byte_func_t input_realtime_callback; - midi_one_byte_func_t input_tunerequest_callback; - - // sysex - midi_sysex_func_t input_sysex_callback; - - // only called if more specific callback is not matched - midi_var_byte_func_t input_fallthrough_callback; - // called if registered, independent of other callbacks - midi_var_byte_func_t input_catchall_callback; - - // pre input processing function - midi_no_byte_func_t pre_input_process_callback; - - // for internal input processing - uint8_t input_buffer[3]; - input_state_t input_state; - uint16_t input_count; - - // for queueing data between the input and the processing functions - uint8_t input_queue_data[MIDI_INPUT_QUEUE_LENGTH]; - byteQueue_t input_queue; -}; - -/** - * @brief Process input bytes. This function parses bytes and calls the - * appropriate callbacks associated with the given device. You use this - * function if you are creating a custom device and you want to have midi - * input. - * - * @param device the midi device to associate the input with - * @param cnt the number of bytes you are processing - * @param input the bytes to process - */ -void midi_device_input(MidiDevice* device, uint8_t cnt, uint8_t* input); - -/** - * @brief Set the callback function that will be used for sending output - * data bytes. This is only used if you're creating a custom device. - * You'll most likely want the callback function to disable interrupts so - * that you can call the various midi send functions without worrying about - * locking. - * - * \param device the midi device to associate this callback with - * \param send_func the callback function that will do the sending - */ -void midi_device_set_send_func(MidiDevice* device, midi_var_byte_func_t send_func); - -/** - * @brief Set a callback which is called at the beginning of the - * midi_device_process call. This can be used to poll for input - * data and send the data through the midi_device_input function. - * You'll probably only use this if you're creating a custom device. - * - * \param device the midi device to associate this callback with - * \param midi_no_byte_func_t the actual callback function - */ -void midi_device_set_pre_input_process_func(MidiDevice* device, midi_no_byte_func_t pre_process_func); - -/**@}*/ - -#ifdef __cplusplus -} -#endif diff --git a/quantum/midi/midi_function_types.h b/quantum/midi/midi_function_types.h deleted file mode 100644 index 6f98a729811b..000000000000 --- a/quantum/midi/midi_function_types.h +++ /dev/null @@ -1,47 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -/** - * @file - * @brief Function signature definitions - */ - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -// forward declaration -typedef struct _midi_device MidiDevice; - -typedef void (*midi_one_byte_func_t)(MidiDevice *device, uint8_t byte); -typedef void (*midi_two_byte_func_t)(MidiDevice *device, uint8_t byte0, uint8_t byte1); -typedef void (*midi_three_byte_func_t)(MidiDevice *device, uint8_t byte0, uint8_t byte1, uint8_t byte2); -// all bytes after count bytes should be ignored -typedef void (*midi_var_byte_func_t)(MidiDevice *device, uint16_t count, uint8_t byte0, uint8_t byte1, uint8_t byte2); - -// the start byte tells you how far into the sysex message you are, the data_length tells you how many bytes data is -typedef void (*midi_sysex_func_t)(MidiDevice *device, uint16_t start_byte, uint8_t data_length, uint8_t *data); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/midi/qmk_midi.c b/quantum/midi/qmk_midi.c deleted file mode 100644 index f6a5d9228124..000000000000 --- a/quantum/midi/qmk_midi.c +++ /dev/null @@ -1,135 +0,0 @@ -#include -#include "qmk_midi.h" -#include "sysex_tools.h" -#include "midi.h" -#include "usb_descriptor.h" -#include "process_midi.h" - -/******************************************************************************* - * MIDI - ******************************************************************************/ - -MidiDevice midi_device; - -#define SYSEX_START_OR_CONT 0x40 -#define SYSEX_ENDS_IN_1 0x50 -#define SYSEX_ENDS_IN_2 0x60 -#define SYSEX_ENDS_IN_3 0x70 - -#define SYS_COMMON_1 0x50 -#define SYS_COMMON_2 0x20 -#define SYS_COMMON_3 0x30 - -static void usb_send_func(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { - MIDI_EventPacket_t event; - event.Data1 = byte0; - event.Data2 = byte1; - event.Data3 = byte2; - - uint8_t cable = 0; - - // if the length is undefined we assume it is a SYSEX message - if (midi_packet_length(byte0) == UNDEFINED) { - switch (cnt) { - case 3: - if (byte2 == SYSEX_END) - event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_3); - else - event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); - break; - case 2: - if (byte1 == SYSEX_END) - event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_2); - else - event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); - break; - case 1: - if (byte0 == SYSEX_END) - event.Event = MIDI_EVENT(cable, SYSEX_ENDS_IN_1); - else - event.Event = MIDI_EVENT(cable, SYSEX_START_OR_CONT); - break; - default: - return; // invalid cnt - } - } else { - // deal with 'system common' messages - // TODO are there any more? - switch (byte0 & 0xF0) { - case MIDI_SONGPOSITION: - event.Event = MIDI_EVENT(cable, SYS_COMMON_3); - break; - case MIDI_SONGSELECT: - case MIDI_TC_QUARTERFRAME: - event.Event = MIDI_EVENT(cable, SYS_COMMON_2); - break; - default: - event.Event = MIDI_EVENT(cable, byte0); - break; - } - } - - send_midi_packet(&event); -} - -static void usb_get_midi(MidiDevice* device) { - MIDI_EventPacket_t event; - while (recv_midi_packet(&event)) { - midi_packet_length_t length = midi_packet_length(event.Data1); - uint8_t input[3]; - input[0] = event.Data1; - input[1] = event.Data2; - input[2] = event.Data3; - if (length == UNDEFINED) { - // sysex - if (event.Event == MIDI_EVENT(0, SYSEX_START_OR_CONT) || event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_3)) { - length = 3; - } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_2)) { - length = 2; - } else if (event.Event == MIDI_EVENT(0, SYSEX_ENDS_IN_1)) { - length = 1; - } else { - // XXX what to do? - } - } - - // pass the data to the device input function - if (length != UNDEFINED) midi_device_input(device, length, input); - } -} - -static void fallthrough_callback(MidiDevice* device, uint16_t cnt, uint8_t byte0, uint8_t byte1, uint8_t byte2) { -#ifdef AUDIO_ENABLE - if (cnt == 3) { - switch (byte0 & 0xF0) { - case MIDI_NOTEON: - play_note(((double)261.6) * pow(2.0, -4.0) * pow(2.0, (byte1 & 0x7F) / 12.0), (byte2 & 0x7F) / 8); - break; - case MIDI_NOTEOFF: - stop_note(((double)261.6) * pow(2.0, -4.0) * pow(2.0, (byte1 & 0x7F) / 12.0)); - break; - } - } - if (byte0 == MIDI_STOP) { - stop_all_notes(); - } -#endif -} - -static void cc_callback(MidiDevice* device, uint8_t chan, uint8_t num, uint8_t val) { - // sending it back on the next channel - // midi_send_cc(device, (chan + 1) % 16, num, val); -} - -void midi_init(void); - -void setup_midi(void) { -#ifdef MIDI_ADVANCED - midi_init(); -#endif - midi_device_init(&midi_device); - midi_device_set_send_func(&midi_device, usb_send_func); - midi_device_set_pre_input_process_func(&midi_device, usb_get_midi); - midi_register_fallthrough_callback(&midi_device, fallthrough_callback); - midi_register_cc_callback(&midi_device, cc_callback); -} diff --git a/quantum/midi/qmk_midi.h b/quantum/midi/qmk_midi.h deleted file mode 100644 index 819087a405fe..000000000000 --- a/quantum/midi/qmk_midi.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#ifdef MIDI_ENABLE -# include "midi.h" -# include -extern MidiDevice midi_device; -void setup_midi(void); -void send_midi_packet(MIDI_EventPacket_t* event); -bool recv_midi_packet(MIDI_EventPacket_t* const event); -#endif diff --git a/quantum/midi/sysex_tools.c b/quantum/midi/sysex_tools.c deleted file mode 100644 index c9a9d0328502..000000000000 --- a/quantum/midi/sysex_tools.c +++ /dev/null @@ -1,97 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -#include "sysex_tools.h" - -uint16_t sysex_encoded_length(uint16_t decoded_length) { - uint8_t remainder = decoded_length % 7; - if (remainder) - return (decoded_length / 7) * 8 + remainder + 1; - else - return (decoded_length / 7) * 8; -} - -uint16_t sysex_decoded_length(uint16_t encoded_length) { - uint8_t remainder = encoded_length % 8; - if (remainder) - return (encoded_length / 8) * 7 + remainder - 1; - else - return (encoded_length / 8) * 7; -} - -uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, const uint16_t length) { - uint16_t encoded_full = length / 7; // number of full 8 byte sections from 7 bytes of input - uint16_t i, j; - - // fill out the fully encoded sections - for (i = 0; i < encoded_full; i++) { - uint16_t encoded_msb_idx = i * 8; - uint16_t input_start_idx = i * 7; - encoded[encoded_msb_idx] = 0; - for (j = 0; j < 7; j++) { - uint8_t current = source[input_start_idx + j]; - encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j); - encoded[encoded_msb_idx + 1 + j] = 0x7F & current; - } - } - - // fill out the rest if there is any more - uint8_t remainder = length % 7; - if (remainder) { - uint16_t encoded_msb_idx = encoded_full * 8; - uint16_t input_start_idx = encoded_full * 7; - encoded[encoded_msb_idx] = 0; - for (j = 0; j < remainder; j++) { - uint8_t current = source[input_start_idx + j]; - encoded[encoded_msb_idx] |= (0x80 & current) >> (1 + j); - encoded[encoded_msb_idx + 1 + j] = 0x7F & current; - } - return encoded_msb_idx + remainder + 1; - } else { - return encoded_full * 8; - } -} - -uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, const uint16_t length) { - uint16_t decoded_full = length / 8; - uint16_t i, j; - - if (length < 2) return 0; - - // fill out the fully encoded sections - for (i = 0; i < decoded_full; i++) { - uint16_t encoded_msb_idx = i * 8; - uint16_t output_start_index = i * 7; - for (j = 0; j < 7; j++) { - decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1]; - decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j))); - } - } - uint8_t remainder = length % 8; - if (remainder) { - uint16_t encoded_msb_idx = decoded_full * 8; - uint16_t output_start_index = decoded_full * 7; - for (j = 0; j < (remainder - 1); j++) { - decoded[output_start_index + j] = 0x7F & source[encoded_msb_idx + j + 1]; - decoded[output_start_index + j] |= (0x80 & (source[encoded_msb_idx] << (1 + j))); - } - return decoded_full * 7 + remainder - 1; - } else { - return decoded_full * 7; - } -} diff --git a/quantum/midi/sysex_tools.h b/quantum/midi/sysex_tools.h deleted file mode 100644 index 7d7f10d24e80..000000000000 --- a/quantum/midi/sysex_tools.h +++ /dev/null @@ -1,92 +0,0 @@ -// midi for embedded chips, -// Copyright 2010 Alex Norman -// -// This file is part of avr-midi. -// -// avr-midi 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 3 of the License, or -//(at your option) any later version. -// -// avr-midi 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 avr-midi. If not, see . - -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -#include - -/** - * @file - * @brief Sysex utility functions - * - * These functions are for converting data to and from a "midi-safe" format, - * which can be use to send data with sysex messages. Sysex messages may only - * contain data where the to bit is not set. - * - * An "encoded" midi message is one that contains all of the data from its - * original state, but does not have any of the top bits set. - * - * Every 7 bytes of decoded data is converted into 8 bytes of encoded data and - * visa-versa. If you'd like to operate on small segments, make sure that you - * encode in 7 byte increments and decode in 8 byte increments. - * - */ - -/** @defgroup sysex_tools Sysex utility functions - * @{ - */ - -/** - * @brief Compute the length of a message after it is encoded. - * - * @param decoded_length The length, in bytes, of the message to encode. - * - * @return The length, in bytes, of the message after encodeing. - */ -uint16_t sysex_encoded_length(uint16_t decoded_length); - -/** - * @brief Compute the length of a message after it is decoded. - * - * @param encoded_length The length, in bytes, of the encoded message. - * - * @return The length, in bytes, of the message after it is decoded. - */ -uint16_t sysex_decoded_length(uint16_t encoded_length); - -/** - * @brief Encode data so that it can be transmitted safely in a sysex message. - * - * @param encoded The output data buffer, must be at least sysex_encoded_length(length) bytes long. - * @param source The input buffer of data to be encoded. - * @param length The number of bytes from the input buffer to encode. - * - * @return number of bytes encoded. - */ -uint16_t sysex_encode(uint8_t *encoded, const uint8_t *source, uint16_t length); - -/** - * @brief Decode encoded data. - * - * @param decoded The output data buffer, must be at least sysex_decoded_length(length) bytes long. - * @param source The input buffer of data to be decoded. - * @param length The number of bytes from the input buffer to decode. - * - * @return number of bytes decoded. - */ -uint16_t sysex_decode(uint8_t *decoded, const uint8_t *source, uint16_t length); - -/**@}*/ - -#ifdef __cplusplus -} -#endif diff --git a/quantum/modifiers.h b/quantum/modifiers.h deleted file mode 100644 index 45bcd6508d8c..000000000000 --- a/quantum/modifiers.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -/** \brief 5-bit packed modifiers - * - * Mod bits: 43210 - * bit 0 ||||+- Control - * bit 1 |||+-- Shift - * bit 2 ||+--- Alt - * bit 3 |+---- Gui - * bit 4 +----- LR flag(Left:0, Right:1) - */ -enum mods_5bit { - MOD_LCTL = 0x01, - MOD_LSFT = 0x02, - MOD_LALT = 0x04, - MOD_LGUI = 0x08, - MOD_RCTL = 0x11, - MOD_RSFT = 0x12, - MOD_RALT = 0x14, - MOD_RGUI = 0x18, -}; -#define MOD_HYPR (MOD_LCTL | MOD_LSFT | MOD_LALT | MOD_LGUI) -#define MOD_MEH (MOD_LCTL | MOD_LSFT | MOD_LALT) - -/** \brief 8-bit packed modifiers - */ -enum mods_8bit { - MOD_BIT_LCTRL = 0b00000001, - MOD_BIT_LSHIFT = 0b00000010, - MOD_BIT_LALT = 0b00000100, - MOD_BIT_LGUI = 0b00001000, - MOD_BIT_RCTRL = 0b00010000, - MOD_BIT_RSHIFT = 0b00100000, - MOD_BIT_RALT = 0b01000000, - MOD_BIT_RGUI = 0b10000000, -}; -#define MOD_MASK_CTRL (MOD_BIT_LCTRL | MOD_BIT_RCTRL) -#define MOD_MASK_SHIFT (MOD_BIT_LSHIFT | MOD_BIT_RSHIFT) -#define MOD_MASK_ALT (MOD_BIT_LALT | MOD_BIT_RALT) -#define MOD_MASK_GUI (MOD_BIT_LGUI | MOD_BIT_RGUI) -#define MOD_MASK_CS (MOD_MASK_CTRL | MOD_MASK_SHIFT) -#define MOD_MASK_CA (MOD_MASK_CTRL | MOD_MASK_ALT) -#define MOD_MASK_CG (MOD_MASK_CTRL | MOD_MASK_GUI) -#define MOD_MASK_SA (MOD_MASK_SHIFT | MOD_MASK_ALT) -#define MOD_MASK_SG (MOD_MASK_SHIFT | MOD_MASK_GUI) -#define MOD_MASK_AG (MOD_MASK_ALT | MOD_MASK_GUI) -#define MOD_MASK_CSA (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT) -#define MOD_MASK_CSG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_GUI) -#define MOD_MASK_CAG (MOD_MASK_CTRL | MOD_MASK_ALT | MOD_MASK_GUI) -#define MOD_MASK_SAG (MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) -#define MOD_MASK_CSAG (MOD_MASK_CTRL | MOD_MASK_SHIFT | MOD_MASK_ALT | MOD_MASK_GUI) diff --git a/quantum/mousekey.c b/quantum/mousekey.c deleted file mode 100644 index df8aa613bea4..000000000000 --- a/quantum/mousekey.c +++ /dev/null @@ -1,653 +0,0 @@ -/* - * Copyright 2011 Jun Wako - * - * 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 . - */ - -#include -#include -#include "keycode.h" -#include "host.h" -#include "timer.h" -#include "print.h" -#include "debug.h" -#include "mousekey.h" - -static inline int8_t times_inv_sqrt2(int8_t x) { - // 181/256 is pretty close to 1/sqrt(2) - // 0.70703125 0.707106781 - // 1 too small for x=99 and x=198 - // This ends up being a mult and discard lower 8 bits - return (x * 181) >> 8; -} - -static report_mouse_t mouse_report = {0}; -static void mousekey_debug(void); -static uint8_t mousekey_accel = 0; -static uint8_t mousekey_repeat = 0; -static uint8_t mousekey_wheel_repeat = 0; -#ifdef MOUSEKEY_INERTIA -static uint8_t mousekey_frame = 0; // track whether gesture is inactive, first frame, or repeating -static int8_t mousekey_x_dir = 0; // -1 / 0 / 1 = left / neutral / right -static int8_t mousekey_y_dir = 0; // -1 / 0 / 0 = up / neutral / down -static int8_t mousekey_x_inertia = 0; // current velocity, limit +/- MOUSEKEY_TIME_TO_MAX -static int8_t mousekey_y_inertia = 0; // ... -#endif -#ifdef MK_KINETIC_SPEED -static uint16_t mouse_timer = 0; -#endif - -#ifndef MK_3_SPEED - -static uint16_t last_timer_c = 0; -static uint16_t last_timer_w = 0; - -/* - * Mouse keys acceleration algorithm - * http://en.wikipedia.org/wiki/Mouse_keys - * - * speed = delta * max_speed * (repeat / time_to_max)**((1000+curve)/1000) - */ -/* milliseconds between the initial key press and first repeated motion event (0-2550) */ -uint8_t mk_delay = MOUSEKEY_DELAY / 10; -/* milliseconds between repeated motion events (0-255) */ -uint8_t mk_interval = MOUSEKEY_INTERVAL; -/* steady speed (in action_delta units) applied each event (0-255) */ -uint8_t mk_max_speed = MOUSEKEY_MAX_SPEED; -/* number of events (count) accelerating to steady speed (0-255) */ -uint8_t mk_time_to_max = MOUSEKEY_TIME_TO_MAX; -/* ramp used to reach maximum pointer speed (NOT SUPPORTED) */ -// int8_t mk_curve = 0; -/* wheel params */ -/* milliseconds between the initial key press and first repeated motion event (0-2550) */ -uint8_t mk_wheel_delay = MOUSEKEY_WHEEL_DELAY / 10; -/* milliseconds between repeated motion events (0-255) */ -# ifdef MK_KINETIC_SPEED -float mk_wheel_interval = 1000.0f / MOUSEKEY_WHEEL_INITIAL_MOVEMENTS; -# else -uint8_t mk_wheel_interval = MOUSEKEY_WHEEL_INTERVAL; -# endif -uint8_t mk_wheel_max_speed = MOUSEKEY_WHEEL_MAX_SPEED; -uint8_t mk_wheel_time_to_max = MOUSEKEY_WHEEL_TIME_TO_MAX; - -# ifndef MK_COMBINED -# ifndef MK_KINETIC_SPEED -# ifndef MOUSEKEY_INERTIA - -/* Default accelerated mode */ - -static uint8_t move_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 4; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed); - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_MOVE_DELTA; - } else if (mousekey_repeat >= mk_time_to_max) { - unit = MOUSEKEY_MOVE_DELTA * mk_max_speed; - } else { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max; - } - return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit)); -} - -# else // MOUSEKEY_INERTIA mode - -static int8_t move_unit(uint8_t axis) { - int16_t unit; - - // handle X or Y axis - int8_t inertia, dir; - if (axis) { - inertia = mousekey_y_inertia; - dir = mousekey_y_dir; - } else { - inertia = mousekey_x_inertia; - dir = mousekey_x_dir; - } - - if (mousekey_frame < 2) { // first frame(s): initial keypress moves one pixel - mousekey_frame = 1; - unit = dir * MOUSEKEY_MOVE_DELTA; - } else { // acceleration - // linear acceleration (is here for reference, but doesn't feel as good during use) - // unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * inertia) / mk_time_to_max; - - // x**2 acceleration (quadratic, more precise for short movements) - int16_t percent = (inertia << 8) / mk_time_to_max; - percent = ((int32_t)percent * percent) >> 8; - if (inertia < 0) percent = -percent; - - // unit = sign(inertia) + (percent of max speed) - if (inertia > 0) - unit = 1; - else if (inertia < 0) - unit = -1; - else - unit = 0; - - unit = unit + ((mk_max_speed * percent) >> 8); - } - - if (unit > MOUSEKEY_MOVE_MAX) - unit = MOUSEKEY_MOVE_MAX; - else if (unit < -MOUSEKEY_MOVE_MAX) - unit = -MOUSEKEY_MOVE_MAX; - return unit; -} - -# endif // end MOUSEKEY_INERTIA mode - -static uint8_t wheel_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 4; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed); - } else if (mousekey_wheel_repeat == 0) { - unit = MOUSEKEY_WHEEL_DELTA; - } else if (mousekey_wheel_repeat >= mk_wheel_time_to_max) { - unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed; - } else { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_wheel_repeat) / mk_wheel_time_to_max; - } - return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); -} - -# else /* #ifndef MK_KINETIC_SPEED */ - -/* - * Kinetic movement acceleration algorithm - * - * current speed = I + A * T/50 + A * 0.5 * T^2 | maximum B - * - * T: time since the mouse movement started - * E: mouse events per second (set through MOUSEKEY_INTERVAL, UHK sends 250, the - * pro micro on my Signum 3.0 sends only 125!) - * I: initial speed at time 0 - * A: acceleration - * B: base mouse travel speed - */ -const uint16_t mk_accelerated_speed = MOUSEKEY_ACCELERATED_SPEED; -const uint16_t mk_base_speed = MOUSEKEY_BASE_SPEED; -const uint16_t mk_decelerated_speed = MOUSEKEY_DECELERATED_SPEED; -const uint16_t mk_initial_speed = MOUSEKEY_INITIAL_SPEED; - -static uint8_t move_unit(void) { - float speed = mk_initial_speed; - - if (mousekey_accel & ((1 << 0) | (1 << 2))) { - speed = mousekey_accel & (1 << 2) ? mk_accelerated_speed : mk_decelerated_speed; - } else if (mousekey_repeat && mouse_timer) { - const float time_elapsed = timer_elapsed(mouse_timer) / 50; - speed = mk_initial_speed + MOUSEKEY_MOVE_DELTA * time_elapsed + MOUSEKEY_MOVE_DELTA * 0.5 * time_elapsed * time_elapsed; - - speed = speed > mk_base_speed ? mk_base_speed : speed; - } - - /* convert speed to USB mouse speed 1 to 127 */ - speed = (uint8_t)(speed / (1000.0f / mk_interval)); - speed = speed < 1 ? 1 : speed; - - return speed > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : speed; -} - -static uint8_t wheel_unit(void) { - float speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS; - - if (mousekey_accel & ((1 << 0) | (1 << 2))) { - speed = mousekey_accel & (1 << 2) ? MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS : MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS; - } else if (mousekey_wheel_repeat && mouse_timer) { - if (mk_wheel_interval != MOUSEKEY_WHEEL_BASE_MOVEMENTS) { - const float time_elapsed = timer_elapsed(mouse_timer) / 50; - speed = MOUSEKEY_WHEEL_INITIAL_MOVEMENTS + 1 * time_elapsed + 1 * 0.5 * time_elapsed * time_elapsed; - } - speed = speed > MOUSEKEY_WHEEL_BASE_MOVEMENTS ? MOUSEKEY_WHEEL_BASE_MOVEMENTS : speed; - } - mk_wheel_interval = 1000.0f / speed; - - return (uint8_t)speed > MOUSEKEY_WHEEL_INITIAL_MOVEMENTS ? 2 : 1; -} - -# endif /* #ifndef MK_KINETIC_SPEED */ -# else /* #ifndef MK_COMBINED */ - -/* Combined mode */ - -static uint8_t move_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = 1; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = MOUSEKEY_MOVE_MAX; - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_MOVE_DELTA; - } else if (mousekey_repeat >= mk_time_to_max) { - unit = MOUSEKEY_MOVE_DELTA * mk_max_speed; - } else { - unit = (MOUSEKEY_MOVE_DELTA * mk_max_speed * mousekey_repeat) / mk_time_to_max; - } - return (unit > MOUSEKEY_MOVE_MAX ? MOUSEKEY_MOVE_MAX : (unit == 0 ? 1 : unit)); -} - -static uint8_t wheel_unit(void) { - uint16_t unit; - if (mousekey_accel & (1 << 0)) { - unit = 1; - } else if (mousekey_accel & (1 << 1)) { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed) / 2; - } else if (mousekey_accel & (1 << 2)) { - unit = MOUSEKEY_WHEEL_MAX; - } else if (mousekey_repeat == 0) { - unit = MOUSEKEY_WHEEL_DELTA; - } else if (mousekey_repeat >= mk_wheel_time_to_max) { - unit = MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed; - } else { - unit = (MOUSEKEY_WHEEL_DELTA * mk_wheel_max_speed * mousekey_repeat) / mk_wheel_time_to_max; - } - return (unit > MOUSEKEY_WHEEL_MAX ? MOUSEKEY_WHEEL_MAX : (unit == 0 ? 1 : unit)); -} - -# endif /* #ifndef MK_COMBINED */ - -# ifdef MOUSEKEY_INERTIA - -static int8_t calc_inertia(int8_t direction, int8_t velocity) { - // simulate acceleration and deceleration - - // deceleration - if ((direction > -1) && (velocity < 0)) - velocity = (velocity + 1) * (256 - MOUSEKEY_FRICTION) / 256; - else if ((direction < 1) && (velocity > 0)) - velocity = velocity * (256 - MOUSEKEY_FRICTION) / 256; - - // acceleration - if ((direction > 0) && (velocity < mk_time_to_max)) - velocity++; - else if ((direction < 0) && (velocity > -mk_time_to_max)) - velocity--; - - return velocity; -} - -# endif - -void mousekey_task(void) { - // report cursor and scroll movement independently - report_mouse_t tmpmr = mouse_report; - - mouse_report.x = 0; - mouse_report.y = 0; - mouse_report.v = 0; - mouse_report.h = 0; - -# ifdef MOUSEKEY_INERTIA - - // if an animation is in progress and it's time for the next frame - if ((mousekey_frame) && timer_elapsed(last_timer_c) > ((mousekey_frame > 1) ? mk_interval : mk_delay * 10)) { - mousekey_x_inertia = calc_inertia(mousekey_x_dir, mousekey_x_inertia); - mousekey_y_inertia = calc_inertia(mousekey_y_dir, mousekey_y_inertia); - - mouse_report.x = move_unit(0); - mouse_report.y = move_unit(1); - - // prevent sticky "drift" - if ((!mousekey_x_dir) && (!mousekey_x_inertia)) tmpmr.x = 0; - if ((!mousekey_y_dir) && (!mousekey_y_inertia)) tmpmr.y = 0; - - if (mousekey_frame < 2) mousekey_frame++; - } - - // reset if not moving and no movement keys are held - if ((!mousekey_x_dir) && (!mousekey_y_dir) && (!mousekey_x_inertia) && (!mousekey_y_inertia)) { - mousekey_frame = 0; - tmpmr.x = 0; - tmpmr.y = 0; - } - -# else // default acceleration - - if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > (mousekey_repeat ? mk_interval : mk_delay * 10)) { - if (mousekey_repeat != UINT8_MAX) mousekey_repeat++; - if (tmpmr.x != 0) mouse_report.x = move_unit() * ((tmpmr.x > 0) ? 1 : -1); - if (tmpmr.y != 0) mouse_report.y = move_unit() * ((tmpmr.y > 0) ? 1 : -1); - - /* diagonal move [1/sqrt(2)] */ - if (mouse_report.x && mouse_report.y) { - mouse_report.x = times_inv_sqrt2(mouse_report.x); - if (mouse_report.x == 0) { - mouse_report.x = 1; - } - mouse_report.y = times_inv_sqrt2(mouse_report.y); - if (mouse_report.y == 0) { - mouse_report.y = 1; - } - } - } - -# endif // MOUSEKEY_INERTIA or not - - if ((tmpmr.v || tmpmr.h) && timer_elapsed(last_timer_w) > (mousekey_wheel_repeat ? mk_wheel_interval : mk_wheel_delay * 10)) { - if (mousekey_wheel_repeat != UINT8_MAX) mousekey_wheel_repeat++; - if (tmpmr.v != 0) mouse_report.v = wheel_unit() * ((tmpmr.v > 0) ? 1 : -1); - if (tmpmr.h != 0) mouse_report.h = wheel_unit() * ((tmpmr.h > 0) ? 1 : -1); - - /* diagonal move [1/sqrt(2)] */ - if (mouse_report.v && mouse_report.h) { - mouse_report.v = times_inv_sqrt2(mouse_report.v); - if (mouse_report.v == 0) { - mouse_report.v = 1; - } - mouse_report.h = times_inv_sqrt2(mouse_report.h); - if (mouse_report.h == 0) { - mouse_report.h = 1; - } - } - } - - if (has_mouse_report_changed(&mouse_report, &tmpmr) || should_mousekey_report_send(&mouse_report)) { - mousekey_send(); - } - // save the state for later - memcpy(&mouse_report, &tmpmr, sizeof(tmpmr)); -} - -void mousekey_on(uint8_t code) { -# ifdef MK_KINETIC_SPEED - if (mouse_timer == 0) { - mouse_timer = timer_read(); - } -# endif /* #ifdef MK_KINETIC_SPEED */ - -# ifdef MOUSEKEY_INERTIA - - // initial keypress sets impulse and activates first frame of movement - if ((code == KC_MS_UP) || (code == KC_MS_DOWN)) { - mousekey_y_dir = (code == KC_MS_DOWN) ? 1 : -1; - if (mousekey_frame < 2) mouse_report.y = move_unit(1); - } else if ((code == KC_MS_LEFT) || (code == KC_MS_RIGHT)) { - mousekey_x_dir = (code == KC_MS_RIGHT) ? 1 : -1; - if (mousekey_frame < 2) mouse_report.x = move_unit(0); - } - -# else // no inertia - - if (code == KC_MS_UP) - mouse_report.y = move_unit() * -1; - else if (code == KC_MS_DOWN) - mouse_report.y = move_unit(); - else if (code == KC_MS_LEFT) - mouse_report.x = move_unit() * -1; - else if (code == KC_MS_RIGHT) - mouse_report.x = move_unit(); - -# endif // inertia or not - - else if (code == KC_MS_WH_UP) - mouse_report.v = wheel_unit(); - else if (code == KC_MS_WH_DOWN) - mouse_report.v = wheel_unit() * -1; - else if (code == KC_MS_WH_LEFT) - mouse_report.h = wheel_unit() * -1; - else if (code == KC_MS_WH_RIGHT) - mouse_report.h = wheel_unit(); - else if (IS_MOUSEKEY_BUTTON(code)) - mouse_report.buttons |= 1 << (code - KC_MS_BTN1); - else if (code == KC_MS_ACCEL0) - mousekey_accel |= (1 << 0); - else if (code == KC_MS_ACCEL1) - mousekey_accel |= (1 << 1); - else if (code == KC_MS_ACCEL2) - mousekey_accel |= (1 << 2); -} - -void mousekey_off(uint8_t code) { -# ifdef MOUSEKEY_INERTIA - - // key release clears impulse unless opposite direction is held - if ((code == KC_MS_UP) && (mousekey_y_dir < 1)) - mousekey_y_dir = 0; - else if ((code == KC_MS_DOWN) && (mousekey_y_dir > -1)) - mousekey_y_dir = 0; - else if ((code == KC_MS_LEFT) && (mousekey_x_dir < 1)) - mousekey_x_dir = 0; - else if ((code == KC_MS_RIGHT) && (mousekey_x_dir > -1)) - mousekey_x_dir = 0; - -# else // no inertia - - if (code == KC_MS_UP && mouse_report.y < 0) - mouse_report.y = 0; - else if (code == KC_MS_DOWN && mouse_report.y > 0) - mouse_report.y = 0; - else if (code == KC_MS_LEFT && mouse_report.x < 0) - mouse_report.x = 0; - else if (code == KC_MS_RIGHT && mouse_report.x > 0) - mouse_report.x = 0; - -# endif // inertia or not - - else if (code == KC_MS_WH_UP && mouse_report.v > 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) - mouse_report.h = 0; - else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) - mouse_report.h = 0; - else if (IS_MOUSEKEY_BUTTON(code)) - mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1)); - else if (code == KC_MS_ACCEL0) - mousekey_accel &= ~(1 << 0); - else if (code == KC_MS_ACCEL1) - mousekey_accel &= ~(1 << 1); - else if (code == KC_MS_ACCEL2) - mousekey_accel &= ~(1 << 2); - if (mouse_report.x == 0 && mouse_report.y == 0) { - mousekey_repeat = 0; -# ifdef MK_KINETIC_SPEED - mouse_timer = 0; -# endif /* #ifdef MK_KINETIC_SPEED */ - } - if (mouse_report.v == 0 && mouse_report.h == 0) mousekey_wheel_repeat = 0; -} - -#else /* #ifndef MK_3_SPEED */ - -enum { mkspd_unmod, mkspd_0, mkspd_1, mkspd_2, mkspd_COUNT }; -# ifndef MK_MOMENTARY_ACCEL -static uint8_t mk_speed = mkspd_1; -# else -static uint8_t mk_speed = mkspd_unmod; -static uint8_t mkspd_DEFAULT = mkspd_unmod; -# endif -static uint16_t last_timer_c = 0; -static uint16_t last_timer_w = 0; -uint16_t c_offsets[mkspd_COUNT] = {MK_C_OFFSET_UNMOD, MK_C_OFFSET_0, MK_C_OFFSET_1, MK_C_OFFSET_2}; -uint16_t c_intervals[mkspd_COUNT] = {MK_C_INTERVAL_UNMOD, MK_C_INTERVAL_0, MK_C_INTERVAL_1, MK_C_INTERVAL_2}; -uint16_t w_offsets[mkspd_COUNT] = {MK_W_OFFSET_UNMOD, MK_W_OFFSET_0, MK_W_OFFSET_1, MK_W_OFFSET_2}; -uint16_t w_intervals[mkspd_COUNT] = {MK_W_INTERVAL_UNMOD, MK_W_INTERVAL_0, MK_W_INTERVAL_1, MK_W_INTERVAL_2}; - -void mousekey_task(void) { - // report cursor and scroll movement independently - report_mouse_t tmpmr = mouse_report; - mouse_report.x = 0; - mouse_report.y = 0; - mouse_report.v = 0; - mouse_report.h = 0; - - if ((tmpmr.x || tmpmr.y) && timer_elapsed(last_timer_c) > c_intervals[mk_speed]) { - mouse_report.x = tmpmr.x; - mouse_report.y = tmpmr.y; - } - if ((tmpmr.h || tmpmr.v) && timer_elapsed(last_timer_w) > w_intervals[mk_speed]) { - mouse_report.v = tmpmr.v; - mouse_report.h = tmpmr.h; - } - - if (has_mouse_report_changed(&mouse_report, &tmpmr) || should_mousekey_report_send(&mouse_report)) { - mousekey_send(); - } - memcpy(&mouse_report, &tmpmr, sizeof(tmpmr)); -} - -void adjust_speed(void) { - uint16_t const c_offset = c_offsets[mk_speed]; - uint16_t const w_offset = w_offsets[mk_speed]; - if (mouse_report.x > 0) mouse_report.x = c_offset; - if (mouse_report.x < 0) mouse_report.x = c_offset * -1; - if (mouse_report.y > 0) mouse_report.y = c_offset; - if (mouse_report.y < 0) mouse_report.y = c_offset * -1; - if (mouse_report.h > 0) mouse_report.h = w_offset; - if (mouse_report.h < 0) mouse_report.h = w_offset * -1; - if (mouse_report.v > 0) mouse_report.v = w_offset; - if (mouse_report.v < 0) mouse_report.v = w_offset * -1; - // adjust for diagonals - if (mouse_report.x && mouse_report.y) { - mouse_report.x = times_inv_sqrt2(mouse_report.x); - if (mouse_report.x == 0) { - mouse_report.x = 1; - } - mouse_report.y = times_inv_sqrt2(mouse_report.y); - if (mouse_report.y == 0) { - mouse_report.y = 1; - } - } - if (mouse_report.h && mouse_report.v) { - mouse_report.h = times_inv_sqrt2(mouse_report.h); - mouse_report.v = times_inv_sqrt2(mouse_report.v); - } -} - -void mousekey_on(uint8_t code) { - uint16_t const c_offset = c_offsets[mk_speed]; - uint16_t const w_offset = w_offsets[mk_speed]; - uint8_t const old_speed = mk_speed; - if (code == KC_MS_UP) - mouse_report.y = c_offset * -1; - else if (code == KC_MS_DOWN) - mouse_report.y = c_offset; - else if (code == KC_MS_LEFT) - mouse_report.x = c_offset * -1; - else if (code == KC_MS_RIGHT) - mouse_report.x = c_offset; - else if (code == KC_MS_WH_UP) - mouse_report.v = w_offset; - else if (code == KC_MS_WH_DOWN) - mouse_report.v = w_offset * -1; - else if (code == KC_MS_WH_LEFT) - mouse_report.h = w_offset * -1; - else if (code == KC_MS_WH_RIGHT) - mouse_report.h = w_offset; - else if (IS_MOUSEKEY_BUTTON(code)) - mouse_report.buttons |= 1 << (code - KC_MS_BTN1); - else if (code == KC_MS_ACCEL0) - mk_speed = mkspd_0; - else if (code == KC_MS_ACCEL1) - mk_speed = mkspd_1; - else if (code == KC_MS_ACCEL2) - mk_speed = mkspd_2; - if (mk_speed != old_speed) adjust_speed(); -} - -void mousekey_off(uint8_t code) { -# ifdef MK_MOMENTARY_ACCEL - uint8_t const old_speed = mk_speed; -# endif - if (code == KC_MS_UP && mouse_report.y < 0) - mouse_report.y = 0; - else if (code == KC_MS_DOWN && mouse_report.y > 0) - mouse_report.y = 0; - else if (code == KC_MS_LEFT && mouse_report.x < 0) - mouse_report.x = 0; - else if (code == KC_MS_RIGHT && mouse_report.x > 0) - mouse_report.x = 0; - else if (code == KC_MS_WH_UP && mouse_report.v > 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_DOWN && mouse_report.v < 0) - mouse_report.v = 0; - else if (code == KC_MS_WH_LEFT && mouse_report.h < 0) - mouse_report.h = 0; - else if (code == KC_MS_WH_RIGHT && mouse_report.h > 0) - mouse_report.h = 0; - else if (IS_MOUSEKEY_BUTTON(code)) - mouse_report.buttons &= ~(1 << (code - KC_MS_BTN1)); -# ifdef MK_MOMENTARY_ACCEL - else if (code == KC_MS_ACCEL0) - mk_speed = mkspd_DEFAULT; - else if (code == KC_MS_ACCEL1) - mk_speed = mkspd_DEFAULT; - else if (code == KC_MS_ACCEL2) - mk_speed = mkspd_DEFAULT; - if (mk_speed != old_speed) adjust_speed(); -# endif -} - -#endif /* #ifndef MK_3_SPEED */ - -void mousekey_send(void) { - mousekey_debug(); - uint16_t time = timer_read(); - if (mouse_report.x || mouse_report.y) last_timer_c = time; - if (mouse_report.v || mouse_report.h) last_timer_w = time; - host_mouse_send(&mouse_report); -} - -void mousekey_clear(void) { - mouse_report = (report_mouse_t){}; - mousekey_repeat = 0; - mousekey_wheel_repeat = 0; - mousekey_accel = 0; -#ifdef MOUSEKEY_INERTIA - mousekey_frame = 0; - mousekey_x_inertia = 0; - mousekey_y_inertia = 0; - mousekey_x_dir = 0; - mousekey_y_dir = 0; -#endif -} - -static void mousekey_debug(void) { - if (!debug_mouse) return; - print("mousekey [btn|x y v h](rep/acl): ["); - print_hex8(mouse_report.buttons); - print("|"); - print_decs(mouse_report.x); - print(" "); - print_decs(mouse_report.y); - print(" "); - print_decs(mouse_report.v); - print(" "); - print_decs(mouse_report.h); - print("]("); - print_dec(mousekey_repeat); - print("/"); - print_dec(mousekey_accel); - print(")\n"); -} - -report_mouse_t mousekey_get_report(void) { - return mouse_report; -} - -bool should_mousekey_report_send(report_mouse_t *mouse_report) { - return mouse_report->x || mouse_report->y || mouse_report->v || mouse_report->h; -} diff --git a/quantum/mousekey.h b/quantum/mousekey.h deleted file mode 100644 index e968e000c027..000000000000 --- a/quantum/mousekey.h +++ /dev/null @@ -1,198 +0,0 @@ -/* -Copyright 2011 Jun Wako - -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 . -*/ - -#pragma once - -#include -#include "host.h" - -#ifndef MK_3_SPEED - -/* max value on report descriptor */ -# ifndef MOUSEKEY_MOVE_MAX -# define MOUSEKEY_MOVE_MAX 127 -# elif MOUSEKEY_MOVE_MAX > 127 -# error MOUSEKEY_MOVE_MAX needs to be smaller than 127 -# endif - -# ifndef MOUSEKEY_WHEEL_MAX -# define MOUSEKEY_WHEEL_MAX 127 -# elif MOUSEKEY_WHEEL_MAX > 127 -# error MOUSEKEY_WHEEL_MAX needs to be smaller than 127 -# endif - -# ifndef MOUSEKEY_MOVE_DELTA -# if defined(MK_KINETIC_SPEED) -# define MOUSEKEY_MOVE_DELTA 16 -# elif defined(MOUSEKEY_INERTIA) -# define MOUSEKEY_MOVE_DELTA 1 -# else -# define MOUSEKEY_MOVE_DELTA 8 -# endif -# endif -# ifndef MOUSEKEY_WHEEL_DELTA -# define MOUSEKEY_WHEEL_DELTA 1 -# endif -# ifndef MOUSEKEY_DELAY -# if defined(MK_KINETIC_SPEED) -# define MOUSEKEY_DELAY 5 -# elif defined(MOUSEKEY_INERTIA) -# define MOUSEKEY_DELAY 150 // allow single-pixel movements before repeat activates -# else -# define MOUSEKEY_DELAY 10 -# endif -# endif -# ifndef MOUSEKEY_INTERVAL -# if defined(MK_KINETIC_SPEED) -# define MOUSEKEY_INTERVAL 10 -# elif defined(MOUSEKEY_INERTIA) -# define MOUSEKEY_INTERVAL 16 // 60 fps -# else -# define MOUSEKEY_INTERVAL 20 -# endif -# endif -# ifndef MOUSEKEY_MAX_SPEED -# if defined(MOUSEKEY_INERTIA) -# define MOUSEKEY_MAX_SPEED 32 -# else -# define MOUSEKEY_MAX_SPEED 10 -# endif -# endif -# ifndef MOUSEKEY_TIME_TO_MAX -# if defined(MOUSEKEY_INERTIA) -# define MOUSEKEY_TIME_TO_MAX 32 -# else -# define MOUSEKEY_TIME_TO_MAX 30 -# endif -# endif -# ifndef MOUSEKEY_WHEEL_DELAY -# define MOUSEKEY_WHEEL_DELAY 10 -# endif -# ifndef MOUSEKEY_WHEEL_INTERVAL -# define MOUSEKEY_WHEEL_INTERVAL 80 -# endif -# ifndef MOUSEKEY_WHEEL_MAX_SPEED -# define MOUSEKEY_WHEEL_MAX_SPEED 8 -# endif -# ifndef MOUSEKEY_WHEEL_TIME_TO_MAX -# define MOUSEKEY_WHEEL_TIME_TO_MAX 40 -# endif - -# ifndef MOUSEKEY_FRICTION -# define MOUSEKEY_FRICTION 24 // 0 to 255 -# endif -# ifndef MOUSEKEY_INITIAL_SPEED -# define MOUSEKEY_INITIAL_SPEED 100 -# endif -# ifndef MOUSEKEY_BASE_SPEED -# define MOUSEKEY_BASE_SPEED 5000 -# endif -# ifndef MOUSEKEY_DECELERATED_SPEED -# define MOUSEKEY_DECELERATED_SPEED 400 -# endif -# ifndef MOUSEKEY_ACCELERATED_SPEED -# define MOUSEKEY_ACCELERATED_SPEED 3000 -# endif -# ifndef MOUSEKEY_WHEEL_INITIAL_MOVEMENTS -# define MOUSEKEY_WHEEL_INITIAL_MOVEMENTS 16 -# endif -# ifndef MOUSEKEY_WHEEL_BASE_MOVEMENTS -# define MOUSEKEY_WHEEL_BASE_MOVEMENTS 32 -# endif -# ifndef MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS -# define MOUSEKEY_WHEEL_ACCELERATED_MOVEMENTS 48 -# endif -# ifndef MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS -# define MOUSEKEY_WHEEL_DECELERATED_MOVEMENTS 8 -# endif - -#else /* #ifndef MK_3_SPEED */ - -# ifndef MK_C_OFFSET_UNMOD -# define MK_C_OFFSET_UNMOD 16 -# endif -# ifndef MK_C_INTERVAL_UNMOD -# define MK_C_INTERVAL_UNMOD 16 -# endif -# ifndef MK_C_OFFSET_0 -# define MK_C_OFFSET_0 1 -# endif -# ifndef MK_C_INTERVAL_0 -# define MK_C_INTERVAL_0 32 -# endif -# ifndef MK_C_OFFSET_1 -# define MK_C_OFFSET_1 4 -# endif -# ifndef MK_C_INTERVAL_1 -# define MK_C_INTERVAL_1 16 -# endif -# ifndef MK_C_OFFSET_2 -# define MK_C_OFFSET_2 32 -# endif -# ifndef MK_C_INTERVAL_2 -# define MK_C_INTERVAL_2 16 -# endif - -# ifndef MK_W_OFFSET_UNMOD -# define MK_W_OFFSET_UNMOD 1 -# endif -# ifndef MK_W_INTERVAL_UNMOD -# define MK_W_INTERVAL_UNMOD 40 -# endif -# ifndef MK_W_OFFSET_0 -# define MK_W_OFFSET_0 1 -# endif -# ifndef MK_W_INTERVAL_0 -# define MK_W_INTERVAL_0 360 -# endif -# ifndef MK_W_OFFSET_1 -# define MK_W_OFFSET_1 1 -# endif -# ifndef MK_W_INTERVAL_1 -# define MK_W_INTERVAL_1 120 -# endif -# ifndef MK_W_OFFSET_2 -# define MK_W_OFFSET_2 1 -# endif -# ifndef MK_W_INTERVAL_2 -# define MK_W_INTERVAL_2 20 -# endif - -#endif /* #ifndef MK_3_SPEED */ - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint8_t mk_delay; -extern uint8_t mk_interval; -extern uint8_t mk_max_speed; -extern uint8_t mk_time_to_max; -extern uint8_t mk_wheel_max_speed; -extern uint8_t mk_wheel_time_to_max; - -void mousekey_task(void); -void mousekey_on(uint8_t code); -void mousekey_off(uint8_t code); -void mousekey_clear(void); -void mousekey_send(void); -report_mouse_t mousekey_get_report(void); -bool should_mousekey_report_send(report_mouse_t *mouse_report); - -#ifdef __cplusplus -} -#endif diff --git a/quantum/os_detection.c b/quantum/os_detection.c deleted file mode 100644 index e606227136af..000000000000 --- a/quantum/os_detection.c +++ /dev/null @@ -1,136 +0,0 @@ -/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) - * - * 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 . - */ - -#include "os_detection.h" - -#include - -#ifdef OS_DETECTION_DEBUG_ENABLE -# include "eeconfig.h" -# include "eeprom.h" -# include "print.h" - -# define STORED_USB_SETUPS 50 -# define EEPROM_USER_OFFSET (uint8_t*)EECONFIG_SIZE - -uint16_t usb_setups[STORED_USB_SETUPS]; -#endif - -#ifdef OS_DETECTION_ENABLE -struct setups_data_t { - uint8_t count; - uint8_t cnt_02; - uint8_t cnt_04; - uint8_t cnt_ff; - uint16_t last_wlength; -}; - -struct setups_data_t setups_data = { - .count = 0, - .cnt_02 = 0, - .cnt_04 = 0, - .cnt_ff = 0, -}; - -os_variant_t detected_os = OS_UNSURE; - -// Some collected sequences of wLength can be found in tests. -void make_guess(void) { - if (setups_data.count < 3) { - return; - } - if (setups_data.cnt_ff >= 2 && setups_data.cnt_04 >= 1) { - detected_os = OS_WINDOWS; - return; - } - if (setups_data.count == setups_data.cnt_ff) { - // Linux has 3 packets with 0xFF. - detected_os = OS_LINUX; - return; - } - if (setups_data.count == 5 && setups_data.last_wlength == 0xFF && setups_data.cnt_ff == 1 && setups_data.cnt_02 == 2) { - detected_os = OS_MACOS; - return; - } - if (setups_data.count == 4 && setups_data.cnt_ff == 0 && setups_data.cnt_02 == 2) { - // iOS and iPadOS don't have the last 0xFF packet. - detected_os = OS_IOS; - return; - } - if (setups_data.cnt_ff == 0 && setups_data.cnt_02 == 3 && setups_data.cnt_04 == 1) { - // This is actually PS5. - detected_os = OS_LINUX; - return; - } - if (setups_data.cnt_ff >= 1 && setups_data.cnt_02 == 0 && setups_data.cnt_04 == 0) { - // This is actually Quest 2 or Nintendo Switch. - detected_os = OS_LINUX; - return; - } -} - -void process_wlength(const uint16_t w_length) { -# ifdef OS_DETECTION_DEBUG_ENABLE - usb_setups[setups_data.count] = w_length; -# endif - setups_data.count++; - setups_data.last_wlength = w_length; - if (w_length == 0x2) { - setups_data.cnt_02++; - } else if (w_length == 0x4) { - setups_data.cnt_04++; - } else if (w_length == 0xFF) { - setups_data.cnt_ff++; - } - make_guess(); -} - -os_variant_t detected_host_os(void) { - return detected_os; -} - -void erase_wlength_data(void) { - memset(&setups_data, 0, sizeof(setups_data)); - detected_os = OS_UNSURE; -} - -# if defined(SPLIT_KEYBOARD) && defined(SPLIT_DETECTED_OS_ENABLE) -void slave_update_detected_host_os(os_variant_t os) { - detected_os = os; -} -# endif // defined(SPLIT_KEYBOARD) && defined(SPLIT_DETECTED_OS_ENABLE) -#endif // OS_DETECTION_ENABLE - -#ifdef OS_DETECTION_DEBUG_ENABLE -void print_stored_setups(void) { -# ifdef CONSOLE_ENABLE - uint8_t cnt = eeprom_read_byte(EEPROM_USER_OFFSET); - for (uint16_t i = 0; i < cnt; ++i) { - uint16_t* addr = (uint16_t*)EEPROM_USER_OFFSET + i * sizeof(uint16_t) + sizeof(uint8_t); - xprintf("i: %d, wLength: 0x%02X\n", i, eeprom_read_word(addr)); - } -# endif -} - -void store_setups_in_eeprom(void) { - eeprom_update_byte(EEPROM_USER_OFFSET, setups_data.count); - for (uint16_t i = 0; i < setups_data.count; ++i) { - uint16_t* addr = (uint16_t*)EEPROM_USER_OFFSET + i * sizeof(uint16_t) + sizeof(uint8_t); - eeprom_update_word(addr, usb_setups[i]); - } -} - -#endif // OS_DETECTION_DEBUG_ENABLE diff --git a/quantum/os_detection.h b/quantum/os_detection.h deleted file mode 100644 index 3496ea0ed219..000000000000 --- a/quantum/os_detection.h +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) - * - * 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 . - */ - -#pragma once - -#include - -#ifdef OS_DETECTION_ENABLE -typedef enum { - OS_UNSURE, - OS_LINUX, - OS_WINDOWS, - OS_MACOS, - OS_IOS, -} os_variant_t; - -void process_wlength(const uint16_t w_length); -os_variant_t detected_host_os(void); -void erase_wlength_data(void); - -# if defined(SPLIT_KEYBOARD) && defined(SPLIT_DETECTED_OS_ENABLE) -void slave_update_detected_host_os(os_variant_t os); -# endif // defined(SPLIT_KEYBOARD) && defined(SPLIT_DETECTED_OS_ENABLE) -#endif - -#ifdef OS_DETECTION_DEBUG_ENABLE -void print_stored_setups(void); -void store_setups_in_eeprom(void); -#endif diff --git a/quantum/os_detection/tests/os_detection.cpp b/quantum/os_detection/tests/os_detection.cpp deleted file mode 100644 index 102349852e0c..000000000000 --- a/quantum/os_detection/tests/os_detection.cpp +++ /dev/null @@ -1,164 +0,0 @@ -/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) - * - * 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 . - */ - -#include "gtest/gtest.h" - -extern "C" { -#include "os_detection.h" -} - -class OsDetectionTest : public ::testing::Test { - protected: - void SetUp() override { - erase_wlength_data(); - } -}; - -os_variant_t check_sequence(const std::vector &w_lengths) { - for (auto &w_length : w_lengths) { - process_wlength(w_length); - } - return detected_host_os(); -} - -/* Some collected data. - -ChibiOS: -Windows 10: [FF, FF, 4, 24, 4, 24, 4, FF, 24, FF, 4, FF, 24, 4, 24, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A] -Windows 10 (another host): [FF, FF, 4, 24, 4, 24, 4, 24, 4, 24, 4, 24] -macOS 12.5: [2, 24, 2, 28, FF] -iOS/iPadOS 15.6: [2, 24, 2, 28] -Linux (including Android, Raspberry Pi and WebOS TV): [FF, FF, FF] -PS5: [2, 4, 2, 28, 2, 24] -Nintendo Switch: [82, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40] -Quest 2: [FF, FF, FF, FE, FF, FE, FF, FE, FF, FE, FF] - -LUFA: -Windows 10 (first connect): [12, FF, FF, 4, 10, FF, FF, FF, 4, 10, 20A, 20A, 20A, 20A, 20A, 20A] -Windows 10 (subsequent connect): [FF, FF, 4, 10, FF, 4, FF, 10, FF, 20A, 20A, 20A, 20A, 20A, 20A] -Windows 10 (another host): [FF, FF, 4, 10, 4, 10] -macOS: [2, 10, 2, E, FF] -iOS/iPadOS: [2, 10, 2, E] -Linux: [FF, FF, FF] -PS5: [2, 4, 2, E, 2, 10] -Nintendo Switch: [82, FF, 40, 40, FF, 40, 40] - -V-USB: -Windows 10: [FF, FF, 4, E, FF] -Windows 10 (another host): [FF, FF, 4, E, 4] -macOS: [2, E, 2, E, FF] -iOS/iPadOS: [2, E, 2, E] -Linux: [FF, FF, FF] -PS5: [2, 4, 2, E, 2] -Nintendo Switch: [82, FF, 40, 40] -Quest 2: [FF, FF, FF, FE] - -Common parts: -Windows: [..., FF, FF, 4, ...] -macOS: [2, _, 2, _, FF] -iOS/iPadOS: [2, _, 2, _] -Linux: [FF, FF, FF] -PS5: [2, 4, 2, _, 2, ...] -Nintendo Switch: [82, FF, 40, 40, ...] -Quest 2: [FF, FF, FF, FE, ...] -*/ -TEST_F(OsDetectionTest, TestLinux) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestChibiosMacos) { - EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28, 0xFF}), OS_MACOS); -} - -TEST_F(OsDetectionTest, TestLufaMacos) { - EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE, 0xFF}), OS_MACOS); -} - -TEST_F(OsDetectionTest, TestVusbMacos) { - EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE, 0xFF}), OS_MACOS); -} - -TEST_F(OsDetectionTest, TestChibiosIos) { - EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28}), OS_IOS); -} - -TEST_F(OsDetectionTest, TestLufaIos) { - EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE}), OS_IOS); -} - -TEST_F(OsDetectionTest, TestVusbIos) { - EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE}), OS_IOS); -} - -TEST_F(OsDetectionTest, TestChibiosWindows10) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0xFF, 0x24, 0xFF, 0x4, 0xFF, 0x24, 0x4, 0x24, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestChibiosWindows10_2) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestLufaWindows10) { - EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestLufaWindows10_2) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0xFF, 0x4, 0xFF, 0x10, 0xFF, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestLufaWindows10_3) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0x4, 0x10}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestVusbWindows10) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0xFF}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestVusbWindows10_2) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0x4}), OS_WINDOWS); -} - -TEST_F(OsDetectionTest, TestChibiosPs5) { - EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0x28, 0x2, 0x24}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestLufaPs5) { - EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2, 0x10}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestVusbPs5) { - EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestChibiosNintendoSwitch) { - EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestLufaNintendoSwitch) { - EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestVusbNintendoSwitch) { - EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestChibiosQuest2) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF}), OS_LINUX); -} - -TEST_F(OsDetectionTest, TestVusbQuest2) { - EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); -} diff --git a/quantum/os_detection/tests/rules.mk b/quantum/os_detection/tests/rules.mk deleted file mode 100644 index 9bfe373f46ef..000000000000 --- a/quantum/os_detection/tests/rules.mk +++ /dev/null @@ -1,5 +0,0 @@ -os_detection_DEFS := -DOS_DETECTION_ENABLE - -os_detection_SRC := \ - $(QUANTUM_PATH)/os_detection/tests/os_detection.cpp \ - $(QUANTUM_PATH)/os_detection.c diff --git a/quantum/os_detection/tests/testlist.mk b/quantum/os_detection/tests/testlist.mk deleted file mode 100644 index 405a7b82d55b..000000000000 --- a/quantum/os_detection/tests/testlist.mk +++ /dev/null @@ -1 +0,0 @@ -TEST_LIST += os_detection diff --git a/quantum/painter/lvgl/qp_lvgl.c b/quantum/painter/lvgl/qp_lvgl.c deleted file mode 100644 index 660ffb610083..000000000000 --- a/quantum/painter/lvgl/qp_lvgl.c +++ /dev/null @@ -1,150 +0,0 @@ -// Copyright 2022 Jose Pablo Ramirez (@jpe230) -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_lvgl.h" -#include "timer.h" -#include "deferred_exec.h" -#include "lvgl.h" - -typedef struct lvgl_state_t { - uint8_t fnc_id; // Ideally this should be the pointer of the function to run - uint16_t delay_ms; - deferred_token defer_token; -} lvgl_state_t; - -static deferred_executor_t lvgl_executors[2] = {0}; // For lv_tick_inc and lv_task_handler -static lvgl_state_t lvgl_states[2] = {0}; // For lv_tick_inc and lv_task_handler - -painter_device_t selected_display = NULL; -void * color_buffer = NULL; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter LVGL Integration Internal: qp_lvgl_flush - -void qp_lvgl_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { - if (selected_display) { - uint32_t number_pixels = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); - qp_viewport(selected_display, area->x1, area->y1, area->x2, area->y2); - qp_pixdata(selected_display, (void *)color_p, number_pixels); - qp_flush(selected_display); - lv_disp_flush_ready(disp); - } -} - -static uint32_t tick_task_callback(uint32_t trigger_time, void *cb_arg) { - lvgl_state_t * state = (lvgl_state_t *)cb_arg; - static uint32_t last_tick = 0; - switch (state->fnc_id) { - case 0: { - uint32_t now = timer_read32(); - lv_tick_inc(TIMER_DIFF_32(now, last_tick)); - last_tick = now; - } break; - case 1: - lv_task_handler(); - break; - - default: - break; - } - - // The tasks should run indefinitely - return state->delay_ms; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter LVGL Integration API: qp_lvgl_attach - -bool qp_lvgl_attach(painter_device_t device) { - qp_dprintf("qp_lvgl_start: entry\n"); - qp_lvgl_detach(); - - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_lvgl_attach: fail (validation_ok == false)\n"); - qp_lvgl_detach(); - return false; - } - - // Setting up the tasks - lvgl_state_t *lv_tick_inc_state = &lvgl_states[0]; - lv_tick_inc_state->fnc_id = 0; - lv_tick_inc_state->delay_ms = 1; - lv_tick_inc_state->defer_token = defer_exec_advanced(lvgl_executors, 2, 1, tick_task_callback, lv_tick_inc_state); - - if (lv_tick_inc_state->defer_token == INVALID_DEFERRED_TOKEN) { - qp_dprintf("qp_lvgl_attach: fail (could not set up qp_lvgl executor)\n"); - qp_lvgl_detach(); - return false; - } - - lvgl_state_t *lv_task_handler_state = &lvgl_states[1]; - lv_task_handler_state->fnc_id = 1; - lv_task_handler_state->delay_ms = 5; - lv_task_handler_state->defer_token = defer_exec_advanced(lvgl_executors, 2, 5, tick_task_callback, lv_task_handler_state); - - if (lv_task_handler_state->defer_token == INVALID_DEFERRED_TOKEN) { - qp_dprintf("qp_lvgl_attach: fail (could not set up qp_lvgl executor)\n"); - qp_lvgl_detach(); - return false; - } - - // Init LVGL - lv_init(); - - // Set up lvgl display buffer - static lv_disp_draw_buf_t draw_buf; - // Allocate a buffer for 1/10 screen size - const size_t count_required = driver->panel_width * driver->panel_height / 10; - color_buffer = color_buffer ? realloc(color_buffer, sizeof(lv_color_t) * count_required) : malloc(sizeof(lv_color_t) * count_required); - if (!color_buffer) { - qp_dprintf("qp_lvgl_attach: fail (could not set up memory buffer)\n"); - qp_lvgl_detach(); - return false; - } - memset(color_buffer, 0, sizeof(lv_color_t) * count_required); - // Initialize the display buffer. - lv_disp_draw_buf_init(&draw_buf, color_buffer, NULL, count_required); - - selected_display = device; - - uint16_t panel_width, panel_height, offset_x, offset_y; - qp_get_geometry(selected_display, &panel_width, &panel_height, NULL, &offset_x, &offset_y); - - panel_width -= offset_x; - panel_height -= offset_y; - - // Setting up display driver - static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ - lv_disp_drv_init(&disp_drv); /*Basic initialization*/ - disp_drv.flush_cb = qp_lvgl_flush; /*Set your driver function*/ - disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/ - disp_drv.hor_res = panel_width; /*Set the horizontal resolution of the display*/ - disp_drv.ver_res = panel_height; /*Set the vertical resolution of the display*/ - lv_disp_drv_register(&disp_drv); /*Finally register the driver*/ - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter LVGL Integration API: qp_lvgl_detach - -void qp_lvgl_detach(void) { - for (int i = 0; i < 2; ++i) { - cancel_deferred_exec_advanced(lvgl_executors, 2, lvgl_states[i].defer_token); - } - if (color_buffer) { - free(color_buffer); - color_buffer = NULL; - } - selected_display = NULL; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter LVGL Integration Internal: qp_lvgl_internal_tick - -void qp_lvgl_internal_tick(void) { - static uint32_t last_lvgl_exec = 0; - deferred_exec_advanced_task(lvgl_executors, 2, &last_lvgl_exec); -} diff --git a/quantum/painter/lvgl/qp_lvgl.h b/quantum/painter/lvgl/qp_lvgl.h deleted file mode 100644 index d9ad5e8df1ef..000000000000 --- a/quantum/painter/lvgl/qp_lvgl.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2022 Jose Pablo Ramirez (@jpe230) -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "qp.h" -#include "lvgl.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter - LVGL External API - -/** - * Sets up LVGL with the supplied display. - * - * @param device[in] the handle of the device to control - * @return true if init. of LVGL succeeded - * @return false if init. of LVGL failed - */ -bool qp_lvgl_attach(painter_device_t device); - -/** - * Disconnects LVGL from any attached display - */ -void qp_lvgl_detach(void); diff --git a/quantum/painter/lvgl/rules.mk b/quantum/painter/lvgl/rules.mk deleted file mode 100644 index 50226941b35a..000000000000 --- a/quantum/painter/lvgl/rules.mk +++ /dev/null @@ -1,24 +0,0 @@ -# LVGL Integration - -OPT_DEFS += -DQUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE -DLV_CONF_INCLUDE_SIMPLE -DEFERRED_EXEC_ENABLE := yes - -LVGL_DIR_NAME = lvgl -LVGL_DIR = $(LIB_DIR) -LVGL_PATH = $(LVGL_DIR)/$(LVGL_DIR_NAME) - -COMMON_VPATH += $(PLATFORM_PATH) \ - $(QUANTUM_DIR)/painter/$(LVGL_DIR_NAME) \ - $(LVGL_PATH) - -include $(LVGL_PATH)/src/extra/extra.mk -include $(LVGL_PATH)/src/core/lv_core.mk -include $(LVGL_PATH)/src/draw/lv_draw.mk -include $(LVGL_PATH)/src/draw/sw/lv_draw_sw.mk -include $(LVGL_PATH)/src/font/lv_font.mk -include $(LVGL_PATH)/src/hal/lv_hal.mk -include $(LVGL_PATH)/src/misc/lv_misc.mk -include $(LVGL_PATH)/src/widgets/lv_widgets.mk - -SRC += qp_lvgl.c \ - $(CSRCS) diff --git a/quantum/painter/qff.c b/quantum/painter/qff.c deleted file mode 100644 index cd6af788f9ef..000000000000 --- a/quantum/painter/qff.c +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -// Quantum Font File "QFF" File Format. -// See https://docs.qmk.fm/#/quantum_painter_qff for more information. - -#include "qff.h" -#include "qp_draw.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QFF API - -bool qff_read_font_descriptor(qp_stream_t *stream, uint8_t *line_height, bool *has_ascii_table, uint16_t *num_unicode_glyphs, uint8_t *bpp, bool *has_palette, painter_compression_t *compression_scheme, uint32_t *total_bytes) { - // Seek to the start - qp_stream_setpos(stream, 0); - - // Read and validate the font descriptor - qff_font_descriptor_v1_t font_descriptor; - if (qp_stream_read(&font_descriptor, sizeof(qff_font_descriptor_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read font_descriptor, expected length was not %d\n", (int)sizeof(qff_font_descriptor_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&font_descriptor.header, QFF_FONT_DESCRIPTOR_TYPEID, (sizeof(qff_font_descriptor_v1_t) - sizeof(qgf_block_header_v1_t)))) { - return false; - } - - // Make sure the magic and version are correct - if (font_descriptor.magic != QFF_MAGIC || font_descriptor.qff_version != 0x01) { - qp_dprintf("Failed to validate font_descriptor, expected magic 0x%06X was 0x%06X, expected version = 0x%02X was 0x%02X\n", (int)QFF_MAGIC, (int)font_descriptor.magic, (int)0x01, (int)font_descriptor.qff_version); - return false; - } - - // Make sure the file length is valid - if (font_descriptor.neg_total_file_size != ~font_descriptor.total_file_size) { - qp_dprintf("Failed to validate font_descriptor, expected negated length 0x%08X was 0x%08X\n", (int)(~font_descriptor.total_file_size), (int)font_descriptor.neg_total_file_size); - return false; - } - - // Copy out the required info - if (line_height) { - *line_height = font_descriptor.line_height; - } - if (has_ascii_table) { - *has_ascii_table = font_descriptor.has_ascii_table; - } - if (num_unicode_glyphs) { - *num_unicode_glyphs = font_descriptor.num_unicode_glyphs; - } - if (bpp || has_palette) { - if (!qgf_parse_format(font_descriptor.format, bpp, has_palette)) { - return false; - } - } - if (compression_scheme) { - *compression_scheme = font_descriptor.compression_scheme; - } - if (total_bytes) { - *total_bytes = font_descriptor.total_file_size; - } - - return true; -} - -static bool qff_validate_ascii_descriptor(qp_stream_t *stream) { - // Read the raw descriptor - qff_ascii_glyph_table_v1_t ascii_descriptor; - if (qp_stream_read(&ascii_descriptor, sizeof(qff_ascii_glyph_table_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read ascii_descriptor, expected length was not %d\n", (int)sizeof(qff_ascii_glyph_table_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&ascii_descriptor.header, QFF_ASCII_GLYPH_DESCRIPTOR_TYPEID, (sizeof(qff_ascii_glyph_table_v1_t) - sizeof(qgf_block_header_v1_t)))) { - return false; - } - - return true; -} - -static bool qff_validate_unicode_descriptor(qp_stream_t *stream, uint16_t num_unicode_glyphs) { - // Read the raw descriptor - qff_unicode_glyph_table_v1_t unicode_descriptor; - if (qp_stream_read(&unicode_descriptor, sizeof(qff_unicode_glyph_table_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read unicode_descriptor, expected length was not %d\n", (int)sizeof(qff_unicode_glyph_table_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&unicode_descriptor.header, QFF_UNICODE_GLYPH_DESCRIPTOR_TYPEID, num_unicode_glyphs * 6)) { - return false; - } - - // Skip the necessary amount of data to get to the next block - qp_stream_seek(stream, num_unicode_glyphs * sizeof(qff_unicode_glyph_v1_t), SEEK_CUR); - - return true; -} - -bool qff_validate_stream(qp_stream_t *stream) { - bool has_ascii_table; - uint16_t num_unicode_glyphs; - - if (!qff_read_font_descriptor(stream, NULL, &has_ascii_table, &num_unicode_glyphs, NULL, NULL, NULL, NULL)) { - return false; - } - - if (has_ascii_table) { - if (!qff_validate_ascii_descriptor(stream)) { - return false; - } - } - - if (num_unicode_glyphs > 0) { - if (!qff_validate_unicode_descriptor(stream, num_unicode_glyphs)) { - return false; - } - } - - return true; -} - -uint32_t qff_get_total_size(qp_stream_t *stream) { - // Get the original location - uint32_t oldpos = qp_stream_tell(stream); - - // Read the font descriptor, grabbing the size - uint32_t total_size; - if (!qff_read_font_descriptor(stream, NULL, NULL, NULL, NULL, NULL, NULL, &total_size)) { - return false; - } - - // Restore the original location - qp_stream_setpos(stream, oldpos); - return total_size; -} diff --git a/quantum/painter/qff.h b/quantum/painter/qff.h deleted file mode 100644 index d1d629582f57..000000000000 --- a/quantum/painter/qff.h +++ /dev/null @@ -1,88 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -// Quantum Font File "QFF" File Format. -// See https://docs.qmk.fm/#/quantum_painter_qff for more information. - -#include -#include - -#include "qp_stream.h" -#include "qp_internal.h" -#include "qgf.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QFF structures - -///////////////////////////////////////// -// Font descriptor - -#define QFF_FONT_DESCRIPTOR_TYPEID 0x00 - -typedef struct QP_PACKED qff_font_descriptor_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x00, .neg_type_id = (~0x00), .length = 20 } - uint32_t magic : 24; // constant, equal to 0x464651 ("QFF") - uint8_t qff_version; // constant, equal to 0x01 - uint32_t total_file_size; // total size of the entire file, starting at offset zero - uint32_t neg_total_file_size; // negated value of total_file_size, used for detecting parsing errors - uint8_t line_height; // glyph height in pixels - bool has_ascii_table; // whether the font has an ascii table of glyphs (0x20...0x7E) - uint16_t num_unicode_glyphs; // the number of glyphs in the unicode table -- no table specified if zero - qp_image_format_t format : 8; // Frame format, see qp.h. - uint8_t flags; // frame flags, see below. - uint8_t compression_scheme; // compression scheme, see below. - uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) -} qff_font_descriptor_v1_t; - -_Static_assert(sizeof(qff_font_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 20), "qff_font_descriptor_v1_t must be 25 bytes in v1 of QFF"); - -#define QFF_MAGIC 0x464651 - -///////////////////////////////////////// -// ASCII glyph table descriptor - -#define QFF_ASCII_GLYPH_DESCRIPTOR_TYPEID 0x01 - -#define QFF_GLYPH_WIDTH_BITS 6 -#define QFF_GLYPH_WIDTH_MASK ((1 << QFF_GLYPH_WIDTH_BITS) - 1) -#define QFF_GLYPH_OFFSET_BITS 18 -#define QFF_GLYPH_OFFSET_MASK (((1 << QFF_GLYPH_OFFSET_BITS) - 1) << QFF_GLYPH_WIDTH_BITS) - -typedef struct QP_PACKED qff_ascii_glyph_v1_t { - uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined -} qff_ascii_glyph_v1_t; - -_Static_assert(sizeof(qff_ascii_glyph_v1_t) == 3, "qff_ascii_glyph_v1_t must be 3 bytes in v1 of QFF"); - -typedef struct QP_PACKED qff_ascii_glyph_table_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = 285 } - qff_ascii_glyph_v1_t glyph[95]; // 95 glyphs, 0x20..0x7E -} qff_ascii_glyph_table_v1_t; - -_Static_assert(sizeof(qff_ascii_glyph_table_v1_t) == (sizeof(qgf_block_header_v1_t) + (95 * sizeof(qff_ascii_glyph_v1_t))), "qff_ascii_glyph_table_v1_t must be 290 bytes in v1 of QFF"); - -///////////////////////////////////////// -// Unicode glyph table descriptor - -#define QFF_UNICODE_GLYPH_DESCRIPTOR_TYPEID 0x02 - -typedef struct QP_PACKED qff_unicode_glyph_v1_t { - uint32_t code_point : 24; - uint32_t value : 24; // Uses QFF_GLYPH_*_(BITS|MASK) as bitfield ordering is compiler-defined -} qff_unicode_glyph_v1_t; - -_Static_assert(sizeof(qff_unicode_glyph_v1_t) == 6, "qff_unicode_glyph_v1_t must be 6 bytes in v1 of QFF"); - -typedef struct QP_PACKED qff_unicode_glyph_table_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = (N * 6) } - qff_unicode_glyph_v1_t glyph[0]; // Extent of '0' signifies that this struct is immediately followed by the glyph data -} qff_unicode_glyph_table_v1_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QFF API - -bool qff_validate_stream(qp_stream_t *stream); -uint32_t qff_get_total_size(qp_stream_t *stream); -bool qff_read_font_descriptor(qp_stream_t *stream, uint8_t *line_height, bool *has_ascii_table, uint16_t *num_unicode_glyphs, uint8_t *bpp, bool *has_palette, painter_compression_t *compression_scheme, uint32_t *total_bytes); diff --git a/quantum/painter/qgf.c b/quantum/painter/qgf.c deleted file mode 100644 index 6a4af07001ec..000000000000 --- a/quantum/painter/qgf.c +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -// Quantum Graphics File "QGF" File Format. -// See https://docs.qmk.fm/#/quantum_painter_qgf for more information. - -#include "qgf.h" -#include "qp_draw.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QGF API - -bool qgf_validate_block_header(qgf_block_header_v1_t *desc, uint8_t expected_typeid, int32_t expected_length) { - if (desc->type_id != expected_typeid || desc->neg_type_id != ((~expected_typeid) & 0xFF)) { - qp_dprintf("Failed to validate header, expected typeid 0x%02X, was 0x%02X, expected negated typeid 0x%02X, was 0x%02X\n", (int)expected_typeid, (int)desc->type_id, (int)((~desc->type_id) & 0xFF), (int)desc->neg_type_id); - return false; - } - - if (expected_length >= 0 && desc->length != expected_length) { - qp_dprintf("Failed to validate header (typeid 0x%02X), expected length %d, was %d\n", (int)desc->type_id, (int)expected_length, (int)desc->length); - return false; - } - - return true; -} - -bool qgf_parse_format(qp_image_format_t format, uint8_t *bpp, bool *has_palette) { - // clang-format off - static const struct QP_PACKED { - uint8_t bpp; - bool has_palette; - } formats[] = { - [GRAYSCALE_1BPP] = {.bpp = 1, .has_palette = false}, - [GRAYSCALE_2BPP] = {.bpp = 2, .has_palette = false}, - [GRAYSCALE_4BPP] = {.bpp = 4, .has_palette = false}, - [GRAYSCALE_8BPP] = {.bpp = 8, .has_palette = false}, - [PALETTE_1BPP] = {.bpp = 1, .has_palette = true}, - [PALETTE_2BPP] = {.bpp = 2, .has_palette = true}, - [PALETTE_4BPP] = {.bpp = 4, .has_palette = true}, - [PALETTE_8BPP] = {.bpp = 8, .has_palette = true}, - [RGB565_16BPP] = {.bpp = 16, .has_palette = false}, - [RGB888_24BPP] = {.bpp = 24, .has_palette = false}, - }; - // clang-format on - - // Copy out the required info - if (format > RGB888_24BPP) { - qp_dprintf("Failed to parse frame_descriptor, invalid format 0x%02X\n", (int)format); - return false; - } - - // Copy out the required info - if (bpp) { - *bpp = formats[format].bpp; - } - if (has_palette) { - *has_palette = formats[format].has_palette; - } - - return true; -} - -bool qgf_parse_frame_descriptor(qgf_frame_v1_t *frame_descriptor, uint8_t *bpp, bool *has_palette, bool *is_delta, painter_compression_t *compression_scheme, uint16_t *delay) { - // Decode the format - qgf_parse_format(frame_descriptor->format, bpp, has_palette); - - // Copy out the required info - if (is_delta) { - *is_delta = (frame_descriptor->flags & QGF_FRAME_FLAG_DELTA) == QGF_FRAME_FLAG_DELTA; - } - if (compression_scheme) { - *compression_scheme = frame_descriptor->compression_scheme; - } - if (delay) { - *delay = frame_descriptor->delay; - } - - return true; -} - -bool qgf_read_graphics_descriptor(qp_stream_t *stream, uint16_t *image_width, uint16_t *image_height, uint16_t *frame_count, uint32_t *total_bytes) { - // Seek to the start - qp_stream_setpos(stream, 0); - - // Read and validate the graphics descriptor - qgf_graphics_descriptor_v1_t graphics_descriptor; - if (qp_stream_read(&graphics_descriptor, sizeof(qgf_graphics_descriptor_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read graphics_descriptor, expected length was not %d\n", (int)sizeof(qgf_graphics_descriptor_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&graphics_descriptor.header, QGF_GRAPHICS_DESCRIPTOR_TYPEID, (sizeof(qgf_graphics_descriptor_v1_t) - sizeof(qgf_block_header_v1_t)))) { - return false; - } - - // Make sure the magic and version are correct - if (graphics_descriptor.magic != QGF_MAGIC || graphics_descriptor.qgf_version != 0x01) { - qp_dprintf("Failed to validate graphics_descriptor, expected magic 0x%06X was 0x%06X, expected version = 0x%02X was 0x%02X\n", (int)QGF_MAGIC, (int)graphics_descriptor.magic, (int)0x01, (int)graphics_descriptor.qgf_version); - return false; - } - - // Make sure the file length is valid - if (graphics_descriptor.neg_total_file_size != ~graphics_descriptor.total_file_size) { - qp_dprintf("Failed to validate graphics_descriptor, expected negated length 0x%08X was 0x%08X\n", (int)(~graphics_descriptor.total_file_size), (int)graphics_descriptor.neg_total_file_size); - return false; - } - - // Copy out the required info - if (image_width) { - *image_width = graphics_descriptor.image_width; - } - if (image_height) { - *image_height = graphics_descriptor.image_height; - } - if (frame_count) { - *frame_count = graphics_descriptor.frame_count; - } - if (total_bytes) { - *total_bytes = graphics_descriptor.total_file_size; - } - - return true; -} - -static bool qgf_read_frame_offset(qp_stream_t *stream, uint16_t frame_number, uint32_t *frame_offset) { - uint16_t frame_count; - if (!qgf_read_graphics_descriptor(stream, NULL, NULL, &frame_count, NULL)) { - return false; - } - - // Read the frame offsets descriptor - qgf_frame_offsets_v1_t frame_offsets; - if (qp_stream_read(&frame_offsets, sizeof(qgf_frame_offsets_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read frame_offsets, expected length was not %d\n", (int)sizeof(qgf_frame_offsets_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&frame_offsets.header, QGF_FRAME_OFFSET_DESCRIPTOR_TYPEID, (frame_count * sizeof(uint32_t)))) { - return false; - } - - if (frame_number >= frame_count) { - qp_dprintf("Invalid frame number, was %d but only %d frames in image\n", (int)frame_number, (int)frame_count); - return false; - } - - // Skip the necessary amount of data to get to the requested frame offset - qp_stream_seek(stream, frame_number * sizeof(uint32_t), SEEK_CUR); - - // Read the frame offset - uint32_t offset = 0; - if (qp_stream_read(&offset, sizeof(uint32_t), 1, stream) != 1) { - qp_dprintf("Failed to read frame offset, expected length was not %d\n", (int)sizeof(uint32_t)); - return false; - } - - // Copy out the required info - if (frame_offset) { - *frame_offset = offset; - } - - return true; -} - -void qgf_seek_to_frame_descriptor(qp_stream_t *stream, uint16_t frame_number) { - // Read the offset - uint32_t offset = 0; - qgf_read_frame_offset(stream, frame_number, &offset); - - // Move to the offset - qp_stream_setpos(stream, offset); -} - -bool qgf_validate_frame_descriptor(qp_stream_t *stream, uint16_t frame_number, uint8_t *bpp, bool *has_palette, bool *is_delta) { - // Seek to the correct location - qgf_seek_to_frame_descriptor(stream, frame_number); - - // Read the raw descriptor - qgf_frame_v1_t frame_descriptor; - if (qp_stream_read(&frame_descriptor, sizeof(qgf_frame_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read frame_descriptor, expected length was not %d\n", (int)sizeof(qgf_frame_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&frame_descriptor.header, QGF_FRAME_DESCRIPTOR_TYPEID, (sizeof(qgf_frame_v1_t) - sizeof(qgf_block_header_v1_t)))) { - return false; - } - - return qgf_parse_frame_descriptor(&frame_descriptor, bpp, has_palette, is_delta, NULL, NULL); -} - -bool qgf_validate_palette_descriptor(qp_stream_t *stream, uint16_t frame_number, uint8_t bpp) { - // Read the palette descriptor - qgf_palette_v1_t palette_descriptor; - if (qp_stream_read(&palette_descriptor, sizeof(qgf_palette_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read palette_descriptor, expected length was not %d\n", (int)sizeof(qgf_palette_v1_t)); - return false; - } - - // Make sure this block is valid - uint32_t expected_length = (1 << bpp) * 3 * sizeof(uint8_t); - if (!qgf_validate_block_header(&palette_descriptor.header, QGF_FRAME_PALETTE_DESCRIPTOR_TYPEID, expected_length)) { - return false; - } - - // Move forward in the stream to the next block - qp_stream_seek(stream, expected_length, SEEK_CUR); - return true; -} - -bool qgf_validate_delta_descriptor(qp_stream_t *stream, uint16_t frame_number) { - // Read the delta descriptor - qgf_delta_v1_t delta_descriptor; - if (qp_stream_read(&delta_descriptor, sizeof(qgf_delta_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read delta_descriptor, expected length was not %d\n", (int)sizeof(qgf_delta_v1_t)); - return false; - } - - // Make sure this block is valid - if (!qgf_validate_block_header(&delta_descriptor.header, QGF_FRAME_DELTA_DESCRIPTOR_TYPEID, (sizeof(qgf_delta_v1_t) - sizeof(qgf_block_header_v1_t)))) { - return false; - } - - return true; -} - -bool qgf_validate_frame_data_descriptor(qp_stream_t *stream, uint16_t frame_number) { - // Read and validate the data block - qgf_data_v1_t data_descriptor; - if (qp_stream_read(&data_descriptor, sizeof(qgf_data_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read data_descriptor, expected length was not %d\n", (int)sizeof(qgf_data_v1_t)); - return false; - } - - if (!qgf_validate_block_header(&data_descriptor.header, QGF_FRAME_DATA_DESCRIPTOR_TYPEID, -1)) { - return false; - } - - return true; -} - -bool qgf_validate_stream(qp_stream_t *stream) { - uint16_t frame_count; - if (!qgf_read_graphics_descriptor(stream, NULL, NULL, &frame_count, NULL)) { - return false; - } - - // Read and validate all the frames (automatically validates the frame offset descriptor in the process) - for (uint16_t i = 0; i < frame_count; ++i) { - // Validate the frame descriptor block - uint8_t bpp; - bool has_palette; - bool has_delta; - if (!qgf_validate_frame_descriptor(stream, i, &bpp, &has_palette, &has_delta)) { - return false; - } - - // If we've got a palette block, check it - if (has_palette && !qgf_validate_palette_descriptor(stream, i, bpp)) { - return false; - } - - // If we've got a delta block, check it - if (has_delta && !qgf_validate_delta_descriptor(stream, i)) { - return false; - } - - // Check the data block - if (!qgf_validate_frame_data_descriptor(stream, i)) { - return false; - } - } - - return true; -} - -// Work out the total size of an image definition, assuming we can read far enough into the file -uint32_t qgf_get_total_size(qp_stream_t *stream) { - // Get the original location - uint32_t oldpos = qp_stream_tell(stream); - - // Read the graphics descriptor, grabbing the size - uint32_t total_size; - if (!qgf_read_graphics_descriptor(stream, NULL, NULL, NULL, &total_size)) { - return false; - } - - // Restore the original location - qp_stream_setpos(stream, oldpos); - return total_size; -} diff --git a/quantum/painter/qgf.h b/quantum/painter/qgf.h deleted file mode 100644 index 54585edd0415..000000000000 --- a/quantum/painter/qgf.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -// Quantum Graphics File "QGF" File Format. -// See https://docs.qmk.fm/#/quantum_painter_qgf for more information. - -#include -#include - -#include "qp_stream.h" -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QGF structures - -///////////////////////////////////////// -// Common block header - -typedef struct QP_PACKED qgf_block_header_v1_t { - uint8_t type_id; // See each respective block type below. - uint8_t neg_type_id; // Negated type ID, used for detecting parsing errors. - uint32_t length : 24; // 24-bit blob length, allowing for block sizes of a maximum of 16MB. -} qgf_block_header_v1_t; - -_Static_assert(sizeof(qgf_block_header_v1_t) == 5, "qgf_block_header_v1_t must be 5 bytes in v1 of QGF"); - -///////////////////////////////////////// -// Graphics descriptor - -#define QGF_GRAPHICS_DESCRIPTOR_TYPEID 0x00 - -typedef struct QP_PACKED qgf_graphics_descriptor_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x00, .neg_type_id = (~0x00), .length = 18 } - uint32_t magic : 24; // constant, equal to 0x464751 ("QGF") - uint8_t qgf_version; // constant, equal to 0x01 - uint32_t total_file_size; // total size of the entire file, starting at offset zero - uint32_t neg_total_file_size; // negated value of total_file_size - uint16_t image_width; // in pixels - uint16_t image_height; // in pixels - uint16_t frame_count; // minimum of 1 -} qgf_graphics_descriptor_v1_t; - -_Static_assert(sizeof(qgf_graphics_descriptor_v1_t) == (sizeof(qgf_block_header_v1_t) + 18), "qgf_graphics_descriptor_v1_t must be 23 bytes in v1 of QGF"); - -#define QGF_MAGIC 0x464751 - -///////////////////////////////////////// -// Frame offset descriptor - -#define QGF_FRAME_OFFSET_DESCRIPTOR_TYPEID 0x01 - -typedef struct QP_PACKED qgf_frame_offsets_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x01, .neg_type_id = (~0x01), .length = (N * sizeof(uint32_t)) } - uint32_t offset[0]; // '0' signifies that this struct is immediately followed by the frame offsets -} qgf_frame_offsets_v1_t; - -_Static_assert(sizeof(qgf_frame_offsets_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_frame_offsets_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); - -///////////////////////////////////////// -// Frame descriptor - -#define QGF_FRAME_DESCRIPTOR_TYPEID 0x02 - -typedef struct QP_PACKED qgf_frame_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x02, .neg_type_id = (~0x02), .length = 6 } - qp_image_format_t format : 8; // Frame format, see qp.h. - uint8_t flags; // Frame flags, see below. - painter_compression_t compression_scheme : 8; // Compression scheme, see qp.h. - uint8_t transparency_index; // palette index used for transparent pixels (not yet implemented) - uint16_t delay; // frame delay time for animations (in units of milliseconds) -} qgf_frame_v1_t; - -_Static_assert(sizeof(qgf_frame_v1_t) == (sizeof(qgf_block_header_v1_t) + 6), "qgf_frame_v1_t must be 11 bytes in v1 of QGF"); - -#define QGF_FRAME_FLAG_DELTA 0x02 -#define QGF_FRAME_FLAG_TRANSPARENT 0x01 - -///////////////////////////////////////// -// Frame palette descriptor - -#define QGF_FRAME_PALETTE_DESCRIPTOR_TYPEID 0x03 - -typedef struct QP_PACKED qgf_palette_entry_v1_t { - uint8_t h; // hue component: `[0,360)` degrees is mapped to `[0,255]` uint8_t. - uint8_t s; // saturation component: `[0,1]` is mapped to `[0,255]` uint8_t. - uint8_t v; // value component: `[0,1]` is mapped to `[0,255]` uint8_t. -} qgf_palette_entry_v1_t; - -_Static_assert(sizeof(qgf_palette_entry_v1_t) == 3, "Palette entry is not 3 bytes in size"); - -typedef struct QP_PACKED qgf_palette_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x03, .neg_type_id = (~0x03), .length = (N * 3 * sizeof(uint8_t)) } - qgf_palette_entry_v1_t hsv[0]; // N * hsv, where N is the number of palette entries depending on the frame format in the descriptor -} qgf_palette_v1_t; - -_Static_assert(sizeof(qgf_palette_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_palette_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); - -///////////////////////////////////////// -// Frame delta descriptor - -#define QGF_FRAME_DELTA_DESCRIPTOR_TYPEID 0x04 - -typedef struct QP_PACKED qgf_delta_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x04, .neg_type_id = (~0x04), .length = 8 } - uint16_t left; // The left pixel location to draw the delta image - uint16_t top; // The top pixel location to draw the delta image - uint16_t right; // The right pixel location to to draw the delta image - uint16_t bottom; // The bottom pixel location to to draw the delta image -} qgf_delta_v1_t; - -_Static_assert(sizeof(qgf_delta_v1_t) == (sizeof(qgf_block_header_v1_t) + 8), "qgf_delta_v1_t must be 13 bytes in v1 of QGF"); - -///////////////////////////////////////// -// Frame data descriptor - -#define QGF_FRAME_DATA_DESCRIPTOR_TYPEID 0x05 - -typedef struct QP_PACKED qgf_data_v1_t { - qgf_block_header_v1_t header; // = { .type_id = 0x05, .neg_type_id = (~0x05), .length = N } - uint8_t data[0]; // 0 signifies that this struct is immediately followed by the length of data specified in the header -} qgf_data_v1_t; - -_Static_assert(sizeof(qgf_data_v1_t) == sizeof(qgf_block_header_v1_t), "qgf_data_v1_t must only contain qgf_block_header_v1_t in v1 of QGF"); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QGF API - -uint32_t qgf_get_total_size(qp_stream_t *stream); -bool qgf_validate_stream(qp_stream_t *stream); -bool qgf_validate_block_header(qgf_block_header_v1_t *desc, uint8_t expected_typeid, int32_t expected_length); -bool qgf_read_graphics_descriptor(qp_stream_t *stream, uint16_t *image_width, uint16_t *image_height, uint16_t *frame_count, uint32_t *total_bytes); -bool qgf_parse_format(qp_image_format_t format, uint8_t *bpp, bool *has_palette); -void qgf_seek_to_frame_descriptor(qp_stream_t *stream, uint16_t frame_number); -bool qgf_parse_frame_descriptor(qgf_frame_v1_t *frame_descriptor, uint8_t *bpp, bool *has_palette, bool *is_delta, painter_compression_t *compression_scheme, uint16_t *delay); diff --git a/quantum/painter/qp.c b/quantum/painter/qp.c deleted file mode 100644 index aea9381b602f..000000000000 --- a/quantum/painter/qp.c +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#include "qp_internal.h" -#include "qp_comms.h" -#include "qp_draw.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Internal driver validation - -static bool validate_driver_vtable(painter_driver_t *driver) { - return (driver->driver_vtable && driver->driver_vtable->init && driver->driver_vtable->power && driver->driver_vtable->clear && driver->driver_vtable->viewport && driver->driver_vtable->pixdata && driver->driver_vtable->palette_convert && driver->driver_vtable->append_pixels && driver->driver_vtable->append_pixdata) ? true : false; -} - -static bool validate_comms_vtable(painter_driver_t *driver) { - return (driver->comms_vtable && driver->comms_vtable->comms_init && driver->comms_vtable->comms_start && driver->comms_vtable->comms_stop && driver->comms_vtable->comms_send) ? true : false; -} - -static bool validate_driver_integrity(painter_driver_t *driver) { - return validate_driver_vtable(driver) && validate_comms_vtable(driver); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_init - -bool qp_init(painter_device_t device, painter_rotation_t rotation) { - qp_dprintf("qp_init: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - - driver->validate_ok = false; - if (!validate_driver_integrity(driver)) { - qp_dprintf("Failed to validate driver integrity in qp_init\n"); - return false; - } - - driver->validate_ok = true; - - if (!qp_comms_init(device)) { - driver->validate_ok = false; - qp_dprintf("qp_init: fail (could not init comms)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_init: fail (could not start comms)\n"); - return false; - } - - // Set the rotation before init - driver->rotation = rotation; - - // Invoke init - bool ret = driver->driver_vtable->init(device, rotation); - qp_comms_stop(device); - qp_dprintf("qp_init: %s\n", ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_power - -bool qp_power(painter_device_t device, bool power_on) { - qp_dprintf("qp_power: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_power: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_power: fail (could not start comms)\n"); - return false; - } - - bool ret = driver->driver_vtable->power(device, power_on); - qp_comms_stop(device); - qp_dprintf("qp_power: %s\n", ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_clear - -bool qp_clear(painter_device_t device) { - qp_dprintf("qp_clear: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_clear: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_clear: fail (could not start comms)\n"); - return false; - } - - bool ret = driver->driver_vtable->clear(device); - qp_comms_stop(device); - qp_dprintf("qp_clear: %s\n", ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_flush - -bool qp_flush(painter_device_t device) { - qp_dprintf("qp_flush: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_flush: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_flush: fail (could not start comms)\n"); - return false; - } - - bool ret = driver->driver_vtable->flush(device); - qp_comms_stop(device); - qp_dprintf("qp_flush: %s\n", ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_get_geometry - -void qp_get_geometry(painter_device_t device, uint16_t *width, uint16_t *height, painter_rotation_t *rotation, uint16_t *offset_x, uint16_t *offset_y) { - qp_dprintf("qp_geometry: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - - switch (driver->rotation) { - default: - case QP_ROTATION_0: - case QP_ROTATION_180: - if (width) { - *width = driver->panel_width; - } - if (height) { - *height = driver->panel_height; - } - break; - case QP_ROTATION_90: - case QP_ROTATION_270: - if (width) { - *width = driver->panel_height; - } - if (height) { - *height = driver->panel_width; - } - break; - } - - if (rotation) { - *rotation = driver->rotation; - } - - if (offset_x) { - *offset_x = driver->offset_x; - } - - if (offset_y) { - *offset_y = driver->offset_y; - } - - qp_dprintf("qp_geometry: ok\n"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_set_viewport_offsets - -void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y) { - qp_dprintf("qp_set_viewport_offsets: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - - driver->offset_x = offset_x; - driver->offset_y = offset_y; - - qp_dprintf("qp_set_viewport_offsets: ok\n"); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_viewport - -bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom) { - qp_dprintf("qp_viewport: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_viewport: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_viewport: fail (could not start comms)\n"); - return false; - } - - // Set the viewport - bool ret = driver->driver_vtable->viewport(device, left, top, right, bottom); - qp_dprintf("qp_viewport: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_pixdata - -bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count) { - qp_dprintf("qp_pixdata: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_pixdata: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_pixdata: fail (could not start comms)\n"); - return false; - } - - bool ret = driver->driver_vtable->pixdata(device, pixel_data, native_pixel_count); - qp_dprintf("qp_pixdata: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret; -} diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h deleted file mode 100644 index 7222d3b41373..000000000000 --- a/quantum/painter/qp.h +++ /dev/null @@ -1,512 +0,0 @@ -// Copyright 2021-2023 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "deferred_exec.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter global configurables (add to your keyboard's config.h) - -#ifndef QUANTUM_PAINTER_DISPLAY_TIMEOUT -/** - * @def This controls the amount of time (in milliseconds) that all displays will remain on after the last user input. - * If set to 0, the display will remain on indefinitely. - */ -# define QUANTUM_PAINTER_DISPLAY_TIMEOUT 30000 -#endif // QUANTUM_PAINTER_DISPLAY_TIMEOUT - -#ifndef QUANTUM_PAINTER_TASK_THROTTLE -/** - * @def This controls the amount of time (in milliseconds) that the Quantum Painter internal task will wait between - * each execution. - */ -# define QUANTUM_PAINTER_TASK_THROTTLE 1 -#endif // QUANTUM_PAINTER_TASK_THROTTLE - -#ifndef QUANTUM_PAINTER_NUM_IMAGES -/** - * @def This controls the maximum number of images that Quantum Painter can load at any one time. Images can be loaded - * using \ref qp_load_image_mem, and can be unloaded by calling \ref qp_close_image. Increasing this number in - * order to load more images increases the amount of RAM required. Image data is not held in RAM, just metadata. - */ -# define QUANTUM_PAINTER_NUM_IMAGES 8 -#endif // QUANTUM_PAINTER_NUM_IMAGES - -#ifndef QUANTUM_PAINTER_NUM_FONTS -/** - * @def This controls the maximum number of fonts that Quantum Painter can load. Fonts can be loaded using - * \ref qp_load_font_mem, and can be unloaded by calling \ref qp_close_font. Increasing this number in order to - * load more fonts increases the amount of RAM required. Font data is not held in RAM, unless - * \ref QUANTUM_PAINTER_LOAD_FONTS_TO_RAM is set to TRUE. - */ -# define QUANTUM_PAINTER_NUM_FONTS 4 -#endif // QUANTUM_PAINTER_NUM_FONTS - -#ifndef QUANTUM_PAINTER_LOAD_FONTS_TO_RAM -/** - * @def This controls whether or not fonts should be cached in RAM. Under normal circumstances, fonts can have quite - * random access patterns, and due to timing of flash memory or external storage, it may be a significant speedup - * moving the font into RAM before use. Defaults to "off", but if it's enabled it will fallback to reading from the - * original location if corresponding RAM could not be allocated (such as being too large). - */ -# define QUANTUM_PAINTER_LOAD_FONTS_TO_RAM FALSE -#endif - -#ifndef QUANTUM_PAINTER_CONCURRENT_ANIMATIONS -/** - * @def This controls the maximum number of animations that Quantum Painter can play simultaneously. Increasing this - * number in order to play more animations at the same time increases the amount of RAM required. - */ -# define QUANTUM_PAINTER_CONCURRENT_ANIMATIONS 4 -#endif // QUANTUM_PAINTER_CONCURRENT_ANIMATIONS - -#ifndef QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE -/** - * @def This controls the maximum size of the pixel data buffer used for single blocks of transmission. Larger buffers - * means more data is processed at one time, with less frequent transmissions, at the cost of RAM. - */ -# define QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE 1024 -#endif - -#ifndef QUANTUM_PAINTER_SUPPORTS_256_PALETTE -/** - * @def This controls whether 256-color palettes are supported. This has relatively hefty requirements on RAM -- at - * least 1kB extra is required just to store the palette information, with more required for other metadata. - */ -# define QUANTUM_PAINTER_SUPPORTS_256_PALETTE FALSE -#endif - -#ifndef QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS -/** - * @def This controls whether the native color range is supported. This avoids the use of palettes but each image - * requires more storage space. - */ -# define QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS FALSE -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter types - -/** - * @typedef A handle to a Quantum Painter device, such as an LCD or OLED. Most Quantum Painter APIs require this - * argument in order to perform operations on the display. - */ -typedef const void *painter_device_t; - -/** - * @typedef The desired rotation of a panel. Used as a parameter to \ref qp_init, and can be queried by - * \ref qp_get_geometry. - */ -typedef enum { QP_ROTATION_0, QP_ROTATION_90, QP_ROTATION_180, QP_ROTATION_270 } painter_rotation_t; - -/** - * @typedef A descriptor for a Quantum Painter image. - */ -typedef struct painter_image_desc_t { - uint16_t width; ///< Image width - uint16_t height; ///< Image height - uint16_t frame_count; ///< Number of frames in this image -} painter_image_desc_t; - -/** - * @typedef A handle to a Quantum Painter image. - */ -typedef const painter_image_desc_t *painter_image_handle_t; - -/** - * @typedef A descriptor for a Quantum Painter font. - */ -typedef struct painter_font_desc_t { - uint8_t line_height; ///< The number of pixels in height for each line -} painter_font_desc_t; - -/** - * @typedef A handle to a Quantum Painter font. - */ -typedef const painter_font_desc_t *painter_font_handle_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API - -/** - * Initialize a device and set its rotation. - * - * @param device[in] the handle of the device to initialize - * @param rotation[in] the rotation to use - * @return true if initialization succeeded - * @return false if initialization failed - */ -bool qp_init(painter_device_t device, painter_rotation_t rotation); - -/** - * Controls whether a display is on or off. - * - * @note If backlighting is used to control brightness (such as for an LCD), it will need to be handled external to - * Quantum Painter. - * - * @param device[in] the handle of the device to control - * @param power_on[in] whether or not the device should be on - * @return true if controlling the power state succeeded - * @return false if controlling the power state failed - */ -bool qp_power(painter_device_t device, bool power_on); - -/** - * Clears a device's screen. - * - * @param device[in] the handle of the device to control - * @return true if clearing the screen succeeded - * @return false if clearing the screen failed - */ -bool qp_clear(painter_device_t device); - -/** - * Transmits any outstanding data to the screen in order to persist all changes to the display. - * - * @note Drivers without internal framebuffers will likely ignore this API. - * - * @param device[in] the handle of the device to control - * @return true if flushing changes to the screen succeeded - * @return false if flushing changes to the screen failed - */ -bool qp_flush(painter_device_t device); - -/** - * Retrieves the size, rotation, and offsets for the display. - * - * @note Any arguments of NULL will be ignored. - * - * @param device[in] the handle of the device to control - * @param width[out] the device's width - * @param height[out] the device's height - * @param rotation[out] the device's rotation - * @param offset_x[out] the device's x-offset applied while drawing - * @param offset_y[out] the device's y-offset applied while drawing - */ -void qp_get_geometry(painter_device_t device, uint16_t *width, uint16_t *height, painter_rotation_t *rotation, uint16_t *offset_x, uint16_t *offset_y); - -/** - * Allows repositioning of the viewport if the panel geometry offsets are non-zero. - * - * @param device[in] the handle of the device to control - * @param offset_x[in] the device's x-offset applied while drawing - * @param offset_y[in] the device's y-offset applied while drawing - */ -void qp_set_viewport_offsets(painter_device_t device, uint16_t offset_x, uint16_t offset_y); - -/** - * Sets a pixel to the specified color. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position to draw onto the device - * @param y[in] the y-position to draw onto the device - * @param hue[in] the hue to use, with 0-360 mapped to 0-255 - * @param sat[in] the saturation to use, with 0-100% mapped to 0-255 - * @param val[in] the value to use, with 0-100% mapped to 0-255 - * @return true if setting the pixel succeeded - * @return false if setting the pixel failed - */ -bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val); - -/** - * Draws a line using the specified color. - * - * @param device[in] the handle of the device to control - * @param x0[in] the device's x-position to start - * @param y0[in] the device's y-position to start - * @param x1[in] the device's x-position to finish - * @param y1[in] the device's y-position to finish - * @param hue[in] the hue to use, with 0-360 mapped to 0-255 - * @param sat[in] the saturation to use, with 0-100% mapped to 0-255 - * @param val[in] the value to use, with 0-100% mapped to 0-255 - * @return true if drawing the line succeeded - * @return false if drawing the line failed - */ -bool qp_line(painter_device_t device, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t hue, uint8_t sat, uint8_t val); - -/** - * Draws a rectangle using the specified color, optionally filled. - * - * @param device[in] the handle of the device to control - * @param left[in] the device's x-position to start - * @param top[in] the device's y-position to start - * @param right[in] the device's x-position to finish - * @param bottom[in] the device's y-position to finish - * @param hue[in] the hue to use, with 0-360 mapped to 0-255 - * @param sat[in] the saturation to use, with 0-100% mapped to 0-255 - * @param val[in] the value to use, with 0-100% mapped to 0-255 - * @param filled[in] whether the rectangle should be filled - * @return true if drawing the rectangle succeeded - * @return false if drawing the rectangle failed - */ -bool qp_rect(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, uint8_t hue, uint8_t sat, uint8_t val, bool filled); - -/** - * Draws a circle using the specified color, optionally filled. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position of the centre of the circle to draw onto the device - * @param y[in] the y-position of the centre of the circle to draw onto the device - * @param radius[in] the radius of the circle to draw - * @param hue[in] the hue to use, with 0-360 mapped to 0-255 - * @param sat[in] the saturation to use, with 0-100% mapped to 0-255 - * @param val[in] the value to use, with 0-100% mapped to 0-255 - * @param filled[in] whether the circle should be filled - * @return true if drawing the circle succeeded - * @return false if drawing the circle failed - */ -bool qp_circle(painter_device_t device, uint16_t x, uint16_t y, uint16_t radius, uint8_t hue, uint8_t sat, uint8_t val, bool filled); - -/** - * Draws a ellipse using the specified color, optionally filled. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position of the centre of the ellipse to draw onto the device - * @param y[in] the y-position of the centre of the ellipse to draw onto the device - * @param sizex[in] the horizontal size of the ellipse - * @param sizey[in] the vertical size of the ellipse - * @param hue[in] the hue to use, with 0-360 mapped to 0-255 - * @param sat[in] the saturation to use, with 0-100% mapped to 0-255 - * @param val[in] the value to use, with 0-100% mapped to 0-255 - * @param filled[in] whether the ellipse should be filled - * @return true if drawing the ellipse succeeded - * @return false if drawing the ellipse failed - */ -bool qp_ellipse(painter_device_t device, uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, uint8_t hue, uint8_t sat, uint8_t val, bool filled); - -/** - * Sets up the location on the display to stream raw pixel data to the display, using \ref qp_pixdata. - * - * @note This is for advanced uses only, and should not be required for normal Quantum Painter functionality. - * - * @param device[in] the handle of the device to control - * @param left[in] the device's x-position to start - * @param top[in] the device's y-position to start - * @param right[in] the device's x-position to finish - * @param bottom[in] the device's y-position to finish - * @return true if setting the viewport succeeded - * @return false if setting the viewport failed - */ -bool qp_viewport(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom); - -/** - * Streams raw pixel data (in the native panel format) to the area previously set by \ref qp_viewport. - * - * @note This is for advanced uses only, and should not be required for normal Quantum Painter functionality. - * - * @param device[in] the handle of the device to control - * @param pixel_data[in] pointer to buffer data - * @param native_pixel_count[in] the number of pixels to transmit - * @return true if streaming of data succeeded - * @return false if streaming of data failed - */ -bool qp_pixdata(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count); - -/** - * Loads an image into memory. - * - * @note Images can be unloaded by calling \ref qp_close_image. - * - * @param buffer[in] the image data to load - * @return an image handle usable with \ref qp_drawimage, \ref qp_drawimage_recolor, \ref qp_animate, and - * \ref qp_animate_recolor. - * @return NULL if loading the image failed - */ -painter_image_handle_t qp_load_image_mem(const void *buffer); - -/** - * Closes an image handle when no longer in use. - * - * @param image[in] the handle of the image to unload - * @return true if unloading the image succeeded - * @return false if unloading the image failed - */ -bool qp_close_image(painter_image_handle_t image); - -/** - * Draws an image to the display. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the image should be drawn onto the device - * @param y[in] the y-position where the image should be drawn onto the device - * @param image[in] the handle of the image to draw - * @return true if drawing the image succeeded - * @return false if drawing the image failed - */ -bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); - -/** - * Draws an image to the display, recoloring monochrome images to the desired foreground/background. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the image should be drawn onto the device - * @param y[in] the y-position where the image should be drawn onto the device - * @param image[in] the handle of the image to draw - * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255 - * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255 - * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255 - * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255 - * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255 - * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255 - * @return true if drawing the image succeeded - * @return false if drawing the image failed - */ -bool qp_drawimage_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); - -/** - * Draws an animation to the display. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the image should be drawn onto the device - * @param y[in] the y-position where the image should be drawn onto the device - * @param image[in] the handle of the image to draw - * @return the \ref deferred_token to use with \ref qp_stop_animation in order to stop animating - * @return INVALID_DEFERRED_TOKEN if animating the image failed - */ -deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image); - -/** - * Draws an animation to the display, recoloring monochrome images to the desired foreground/background. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the image should be drawn onto the device - * @param y[in] the y-position where the image should be drawn onto the device - * @param image[in] the handle of the image to draw - * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255 - * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255 - * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255 - * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255 - * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255 - * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255 - * @return the \ref deferred_token to use with \ref qp_stop_animation in order to stop animating - * @return INVALID_DEFERRED_TOKEN if animating the image failed - */ -deferred_token qp_animate_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); - -/** - * Cancels a running animation. - * - * @param anim_token[in] the animation token returned by \ref qp_animate, or \ref qp_animate_recolor. - */ -void qp_stop_animation(deferred_token anim_token); - -/** - * Loads a font into memory. - * - * @note Fonts can be unloaded by calling \ref qp_close_font. - * - * @param buffer[in] the font data to load - * @return an image handle usable with \ref qp_textwidth, \ref qp_drawtext, and \ref qp_drawtext_recolor. - * @return NULL if loading the font failed - */ -painter_font_handle_t qp_load_font_mem(const void *buffer); - -/** - * Closes a font handle when no longer in use. - * - * @param font[in] the handle of the font to unload - * @return true if unloading the font succeeded - * @return false if unloading the font failed - */ -bool qp_close_font(painter_font_handle_t font); - -/** - * Measures the width (in pixels) of the supplied string, given the specified font. - * - * @param font[in] the handle of the font - * @param str[in] the string to measure - * @return the width (in pixels) needed to draw the specified string - */ -int16_t qp_textwidth(painter_font_handle_t font, const char *str); - -/** - * Draws text to the display. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the text should be drawn onto the device - * @param y[in] the y-position where the text should be drawn onto the device - * @param font[in] the handle of the font - * @param str[in] the string to draw - * @return the width (in pixels) used when drawing the specified string - */ -int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str); - -/** - * Draws text to the display, recoloring monochrome fonts to the desired foreground/background. - * - * @param device[in] the handle of the device to control - * @param x[in] the x-position where the text should be drawn onto the device - * @param y[in] the y-position where the text should be drawn onto the device - * @param font[in] the handle of the font - * @param str[in] the string to draw - * @param hue_fg[in] the foreground hue to use, with 0-360 mapped to 0-255 - * @param sat_fg[in] the foreground saturation to use, with 0-100% mapped to 0-255 - * @param val_fg[in] the foreground value to use, with 0-100% mapped to 0-255 - * @param hue_bg[in] the background hue to use, with 0-360 mapped to 0-255 - * @param sat_bg[in] the background saturation to use, with 0-100% mapped to 0-255 - * @param val_bg[in] the background value to use, with 0-100% mapped to 0-255 - * @return the width (in pixels) used when drawing the specified string - */ -int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Drivers - -#ifdef QUANTUM_PAINTER_RGB565_SURFACE_ENABLE -# include "qp_rgb565_surface.h" -#else // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE -# define RGB565_SURFACE_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_RGB565_SURFACE_ENABLE - -#ifdef QUANTUM_PAINTER_ILI9163_ENABLE -# include "qp_ili9163.h" -#else // QUANTUM_PAINTER_ILI9163_ENABLE -# define ILI9163_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_ILI9163_ENABLE - -#ifdef QUANTUM_PAINTER_ILI9341_ENABLE -# include "qp_ili9341.h" -#else // QUANTUM_PAINTER_ILI9341_ENABLE -# define ILI9341_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_ILI9341_ENABLE - -#ifdef QUANTUM_PAINTER_ILI9488_ENABLE -# include "qp_ili9488.h" -#else // QUANTUM_PAINTER_ILI9488_ENABLE -# define ILI9488_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_ILI9488_ENABLE - -#ifdef QUANTUM_PAINTER_ST7789_ENABLE -# include "qp_st7789.h" -#else // QUANTUM_PAINTER_ST7789_ENABLE -# define ST7789_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_ST7789_ENABLE - -#ifdef QUANTUM_PAINTER_ST7735_ENABLE -# include "qp_st7735.h" -#else // QUANTUM_PAINTER_ST7735_ENABLE -# define ST7735_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_ST7735_ENABLE - -#ifdef QUANTUM_PAINTER_GC9A01_ENABLE -# include "qp_gc9a01.h" -#else // QUANTUM_PAINTER_GC9A01_ENABLE -# define GC9A01_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_GC9A01_ENABLE - -#ifdef QUANTUM_PAINTER_SSD1351_ENABLE -# include "qp_ssd1351.h" -#else // QUANTUM_PAINTER_SSD1351_ENABLE -# define SSD1351_NUM_DEVICES 0 -#endif // QUANTUM_PAINTER_SSD1351_ENABLE - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Extras - -#ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE -# include "qp_lvgl.h" -#endif // QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE diff --git a/quantum/painter/qp_comms.c b/quantum/painter/qp_comms.c deleted file mode 100644 index bcc6de8f2ec7..000000000000 --- a/quantum/painter/qp_comms.c +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_comms.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Base comms APIs - -bool qp_comms_init(painter_device_t device) { - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_comms_init: fail (validation_ok == false)\n"); - return false; - } - - return driver->comms_vtable->comms_init(device); -} - -bool qp_comms_start(painter_device_t device) { - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_comms_start: fail (validation_ok == false)\n"); - return false; - } - - return driver->comms_vtable->comms_start(device); -} - -void qp_comms_stop(painter_device_t device) { - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_comms_stop: fail (validation_ok == false)\n"); - return; - } - - driver->comms_vtable->comms_stop(device); -} - -uint32_t qp_comms_send(painter_device_t device, const void *data, uint32_t byte_count) { - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_comms_send: fail (validation_ok == false)\n"); - return false; - } - - return driver->comms_vtable->comms_send(device, data, byte_count); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Comms APIs that use a D/C pin - -void qp_comms_command(painter_device_t device, uint8_t cmd) { - painter_driver_t * driver = (painter_driver_t *)device; - painter_comms_with_command_vtable_t *comms_vtable = (painter_comms_with_command_vtable_t *)driver->comms_vtable; - comms_vtable->send_command(device, cmd); -} - -void qp_comms_command_databyte(painter_device_t device, uint8_t cmd, uint8_t data) { - qp_comms_command(device, cmd); - qp_comms_send(device, &data, sizeof(data)); -} - -uint32_t qp_comms_command_databuf(painter_device_t device, uint8_t cmd, const void *data, uint32_t byte_count) { - qp_comms_command(device, cmd); - return qp_comms_send(device, data, byte_count); -} - -void qp_comms_bulk_command_sequence(painter_device_t device, const uint8_t *sequence, size_t sequence_len) { - painter_driver_t * driver = (painter_driver_t *)device; - painter_comms_with_command_vtable_t *comms_vtable = (painter_comms_with_command_vtable_t *)driver->comms_vtable; - comms_vtable->bulk_command_sequence(device, sequence, sequence_len); -} diff --git a/quantum/painter/qp_comms.h b/quantum/painter/qp_comms.h deleted file mode 100644 index 8fbf25c201cb..000000000000 --- a/quantum/painter/qp_comms.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include - -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Base comms APIs - -bool qp_comms_init(painter_device_t device); -bool qp_comms_start(painter_device_t device); -void qp_comms_stop(painter_device_t device); -uint32_t qp_comms_send(painter_device_t device, const void* data, uint32_t byte_count); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Comms APIs that use a D/C pin - -void qp_comms_command(painter_device_t device, uint8_t cmd); -void qp_comms_command_databyte(painter_device_t device, uint8_t cmd, uint8_t data); -uint32_t qp_comms_command_databuf(painter_device_t device, uint8_t cmd, const void* data, uint32_t byte_count); -void qp_comms_bulk_command_sequence(painter_device_t device, const uint8_t* sequence, size_t sequence_len); diff --git a/quantum/painter/qp_draw.h b/quantum/painter/qp_draw.h deleted file mode 100644 index 3d073efe8caf..000000000000 --- a/quantum/painter/qp_draw.h +++ /dev/null @@ -1,95 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "qp_internal.h" -#include "qp_stream.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter utility functions - -// Global variable used for native pixel data streaming. -extern uint8_t qp_internal_global_pixdata_buffer[QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE]; - -// Check if the supplied bpp is capable of being rendered -bool qp_internal_bpp_capable(uint8_t bits_per_pixel); - -// Returns the number of pixels that can fit in the pixdata buffer -uint32_t qp_internal_num_pixels_in_buffer(painter_device_t device); - -// Fills the supplied buffer with equivalent native pixels matching the supplied HSV -void qp_internal_fill_pixdata(painter_device_t device, uint32_t num_pixels, uint8_t hue, uint8_t sat, uint8_t val); - -// qp_setpixel internal implementation, but uses the global pixdata buffer with pre-converted native pixel. Only the first pixel is used. -bool qp_internal_setpixel_impl(painter_device_t device, uint16_t x, uint16_t y); - -// qp_rect internal implementation, but uses the global pixdata buffer with pre-converted native pixels. -bool qp_internal_fillrect_helper_impl(painter_device_t device, uint16_t l, uint16_t t, uint16_t r, uint16_t b); - -// Convert from input pixel data + palette to equivalent pixels -typedef int16_t (*qp_internal_byte_input_callback)(void* cb_arg); -typedef bool (*qp_internal_pixel_output_callback)(qp_pixel_t* palette, uint8_t index, void* cb_arg); -typedef bool (*qp_internal_byte_output_callback)(uint8_t byte, void* cb_arg); -bool qp_internal_decode_palette(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_pixel_t* palette, qp_internal_pixel_output_callback output_callback, void* output_arg); -bool qp_internal_decode_grayscale(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_internal_pixel_output_callback output_callback, void* output_arg); -bool qp_internal_decode_recolor(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, qp_internal_pixel_output_callback output_callback, void* output_arg); -bool qp_internal_send_bytes(painter_device_t device, uint32_t byte_count, qp_internal_byte_input_callback input_callback, void* input_arg, qp_internal_byte_output_callback output_callback, void* output_arg); - -// Global variable used for interpolated pixel lookup table. -#if QUANTUM_PAINTER_SUPPORTS_256_PALETTE -extern qp_pixel_t qp_internal_global_pixel_lookup_table[256]; -#else -extern qp_pixel_t qp_internal_global_pixel_lookup_table[16]; -#endif - -// Generates a color-interpolated lookup table based off the number of items, from foreground to background, for use with monochrome image rendering. -// Returns true if a palette was created, false if the palette is reused. -// As this uses a global, this may present a problem if using the same parameters but a different screen converts pixels -- use qp_internal_invalidate_palette() below to reset. -bool qp_internal_interpolate_palette(qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, int16_t steps); - -// Resets the global palette so that it can be regenerated. Only needed if the colors are identical, but a different display is used with a different internal pixel format. -void qp_internal_invalidate_palette(void); - -// Helper shared between image and font rendering -- sets up the global palette to match the palette block specified in the asset. Expects the stream to be positioned at the start of the block header. -bool qp_internal_load_qgf_palette(qp_stream_t* stream, uint8_t bpp); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter codec functions - -enum qp_internal_rle_mode_t { - MARKER_BYTE, - REPEATING_RUN, - NON_REPEATING_RUN, -}; - -typedef struct qp_internal_byte_input_state_t { - painter_device_t device; - qp_stream_t* src_stream; - int16_t curr; - union { - // RLE-specific - struct { - enum qp_internal_rle_mode_t mode; - uint8_t remain; // number of bytes remaining in the current mode - } rle; - }; -} qp_internal_byte_input_state_t; - -typedef struct qp_internal_pixel_output_state_t { - painter_device_t device; - uint32_t pixel_write_pos; - uint32_t max_pixels; -} qp_internal_pixel_output_state_t; - -bool qp_internal_pixel_appender(qp_pixel_t* palette, uint8_t index, void* cb_arg); - -typedef struct qp_internal_byte_output_state_t { - painter_device_t device; - uint32_t byte_write_pos; - uint32_t max_bytes; -} qp_internal_byte_output_state_t; - -bool qp_internal_byte_appender(uint8_t byteval, void* cb_arg); - -qp_internal_byte_input_callback qp_internal_prepare_input_state(qp_internal_byte_input_state_t* input_state, painter_compression_t compression); diff --git a/quantum/painter/qp_draw_circle.c b/quantum/painter/qp_draw_circle.c deleted file mode 100644 index 25517d91c599..000000000000 --- a/quantum/painter/qp_draw_circle.c +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright 2021 Paul Cotter (@gr1mr3aver) -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp.h" -#include "qp_internal.h" -#include "qp_comms.h" -#include "qp_draw.h" - -// Utilize 8-way symmetry to draw circles -static bool qp_circle_helper_impl(painter_device_t device, uint16_t centerx, uint16_t centery, uint16_t offsetx, uint16_t offsety, bool filled) { - /* - Circles have the property of 8-way symmetry, so eight pixels can be drawn - for each computed [offsetx,offsety] given the center coordinates - represented by [centerx,centery]. - - For filled circles, we can draw horizontal lines between each pair of - pixels with the same final value of y. - - Two special cases exist and have been optimized: - 1) offsetx == offsety (the final point), makes half the coordinates - equivalent, so we can omit them (and the corresponding fill lines) - 2) offsetx == 0 (the starting point) means that some horizontal lines - would be a single pixel in length, so we write individual pixels instead. - This also makes half the symmetrical points identical to their twins, - so we only need four points or two points and one line - */ - - int16_t xpx = ((int16_t)centerx) + ((int16_t)offsetx); - int16_t xmx = ((int16_t)centerx) - ((int16_t)offsetx); - int16_t xpy = ((int16_t)centerx) + ((int16_t)offsety); - int16_t xmy = ((int16_t)centerx) - ((int16_t)offsety); - int16_t ypx = ((int16_t)centery) + ((int16_t)offsetx); - int16_t ymx = ((int16_t)centery) - ((int16_t)offsetx); - int16_t ypy = ((int16_t)centery) + ((int16_t)offsety); - int16_t ymy = ((int16_t)centery) - ((int16_t)offsety); - - if (offsetx == 0) { - if (!qp_internal_setpixel_impl(device, centerx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, centerx, ymy)) { - return false; - } - if (filled) { - if (!qp_internal_fillrect_helper_impl(device, xpy, centery, xmy, centery)) { - return false; - } - } else { - if (!qp_internal_setpixel_impl(device, xpy, centery)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmy, centery)) { - return false; - } - } - } else if (offsetx == offsety) { - if (filled) { - if (!qp_internal_fillrect_helper_impl(device, xpy, ypy, xmy, ypy)) { - return false; - } - if (!qp_internal_fillrect_helper_impl(device, xpy, ymy, xmy, ymy)) { - return false; - } - } else { - if (!qp_internal_setpixel_impl(device, xpy, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmy, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpy, ymy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmy, ymy)) { - return false; - } - } - - } else { - if (filled) { - if (!qp_internal_fillrect_helper_impl(device, xpx, ypy, xmx, ypy)) { - return false; - } - if (!qp_internal_fillrect_helper_impl(device, xpx, ymy, xmx, ymy)) { - return false; - } - if (!qp_internal_fillrect_helper_impl(device, xpy, ypx, xmy, ypx)) { - return false; - } - if (!qp_internal_fillrect_helper_impl(device, xpy, ymx, xmy, ymx)) { - return false; - } - } else { - if (!qp_internal_setpixel_impl(device, xpx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpx, ymy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmx, ymy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpy, ypx)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmy, ypx)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpy, ymx)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmy, ymx)) { - return false; - } - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_circle - -bool qp_circle(painter_device_t device, uint16_t x, uint16_t y, uint16_t radius, uint8_t hue, uint8_t sat, uint8_t val, bool filled) { - qp_dprintf("qp_circle: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_circle: fail (validation_ok == false)\n"); - return false; - } - - // plot the initial set of points for x, y and r - int16_t xcalc = 0; - int16_t ycalc = (int16_t)radius; - int16_t err = ((5 - (radius >> 2)) >> 2); - - qp_internal_fill_pixdata(device, (radius * 2) + 1, hue, sat, val); - - if (!qp_comms_start(device)) { - qp_dprintf("qp_circle: fail (could not start comms)\n"); - return false; - } - - bool ret = true; - if (!qp_circle_helper_impl(device, x, y, xcalc, ycalc, filled)) { - ret = false; - } - - if (ret) { - while (xcalc < ycalc) { - xcalc++; - if (err < 0) { - err += (xcalc << 1) + 1; - } else { - ycalc--; - err += ((xcalc - ycalc) << 1) + 1; - } - if (!qp_circle_helper_impl(device, x, y, xcalc, ycalc, filled)) { - ret = false; - break; - } - } - } - - qp_dprintf("qp_circle: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret; -} diff --git a/quantum/painter/qp_draw_codec.c b/quantum/painter/qp_draw_codec.c deleted file mode 100644 index cee2e32e2810..000000000000 --- a/quantum/painter/qp_draw_codec.c +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_internal.h" -#include "qp_draw.h" -#include "qp_comms.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Palette / Monochrome-format decoder - -static const qp_pixel_t qp_pixel_white = {.hsv888 = {.h = 0, .s = 0, .v = 255}}; -static const qp_pixel_t qp_pixel_black = {.hsv888 = {.h = 0, .s = 0, .v = 0}}; - -bool qp_internal_bpp_capable(uint8_t bits_per_pixel) { -#if !(QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS) -# if !(QUANTUM_PAINTER_SUPPORTS_256_PALETTE) - if (bits_per_pixel > 4) { - qp_dprintf("qp_internal_decode_palette: image bpp greater than 4\n"); - return false; - } -# endif - - if (bits_per_pixel > 8) { - qp_dprintf("qp_internal_decode_palette: image bpp greater than 8\n"); - return false; - } -#endif - return true; -} - -bool qp_internal_decode_palette(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_pixel_t* palette, qp_internal_pixel_output_callback output_callback, void* output_arg) { - const uint8_t pixel_bitmask = (1 << bits_per_pixel) - 1; - const uint8_t pixels_per_byte = 8 / bits_per_pixel; - uint32_t remaining_pixels = pixel_count; // don't try to derive from byte_count, we may not use an entire byte - while (remaining_pixels > 0) { - int16_t byteval = input_callback(input_arg); - if (byteval < 0) { - return false; - } - uint8_t loop_pixels = remaining_pixels < pixels_per_byte ? remaining_pixels : pixels_per_byte; - for (uint8_t q = 0; q < loop_pixels; ++q) { - if (!output_callback(palette, byteval & pixel_bitmask, output_arg)) { - return false; - } - byteval >>= bits_per_pixel; - } - remaining_pixels -= loop_pixels; - } - return true; -} - -bool qp_internal_decode_grayscale(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_internal_pixel_output_callback output_callback, void* output_arg) { - return qp_internal_decode_recolor(device, pixel_count, bits_per_pixel, input_callback, input_arg, qp_pixel_white, qp_pixel_black, output_callback, output_arg); -} - -bool qp_internal_decode_recolor(painter_device_t device, uint32_t pixel_count, uint8_t bits_per_pixel, qp_internal_byte_input_callback input_callback, void* input_arg, qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, qp_internal_pixel_output_callback output_callback, void* output_arg) { - painter_driver_t* driver = (painter_driver_t*)device; - int16_t steps = 1 << bits_per_pixel; // number of items we need to interpolate - if (qp_internal_interpolate_palette(fg_hsv888, bg_hsv888, steps)) { - if (!driver->driver_vtable->palette_convert(device, steps, qp_internal_global_pixel_lookup_table)) { - return false; - } - } - - return qp_internal_decode_palette(device, pixel_count, bits_per_pixel, input_callback, input_arg, qp_internal_global_pixel_lookup_table, output_callback, output_arg); -} - -bool qp_internal_send_bytes(painter_device_t device, uint32_t byte_count, qp_internal_byte_input_callback input_callback, void* input_arg, qp_internal_byte_output_callback output_callback, void* output_arg) { - uint32_t remaining_bytes = byte_count; - while (remaining_bytes > 0) { - int16_t byteval = input_callback(input_arg); - if (byteval < 0) { - return false; - } - if (!output_callback(byteval, output_arg)) { - return false; - } - remaining_bytes -= 1; - } - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Progressive pull of bytes, push of pixels - -static inline int16_t qp_drawimage_byte_uncompressed_decoder(void* cb_arg) { - qp_internal_byte_input_state_t* state = (qp_internal_byte_input_state_t*)cb_arg; - state->curr = qp_stream_get(state->src_stream); - return state->curr; -} - -static inline int16_t qp_drawimage_byte_rle_decoder(void* cb_arg) { - qp_internal_byte_input_state_t* state = (qp_internal_byte_input_state_t*)cb_arg; - - // Work out if we're parsing the initial marker byte - if (state->rle.mode == MARKER_BYTE) { - uint8_t c = qp_stream_get(state->src_stream); - if (c >= 128) { - state->rle.mode = NON_REPEATING_RUN; // non-repeated run - state->rle.remain = c - 127; - } else { - state->rle.mode = REPEATING_RUN; // repeated run - state->rle.remain = c; - } - - state->curr = qp_stream_get(state->src_stream); - } - - // Work out which byte we're returning - uint8_t c = state->curr; - - // Decrement the counter of the bytes remaining - state->rle.remain--; - - if (state->rle.remain > 0) { - // If we're in a non-repeating run, queue up the next byte - if (state->rle.mode == NON_REPEATING_RUN) { - state->curr = qp_stream_get(state->src_stream); - } - } else { - // Swap back to querying the marker byte mode - state->rle.mode = MARKER_BYTE; - } - - return c; -} - -bool qp_internal_pixel_appender(qp_pixel_t* palette, uint8_t index, void* cb_arg) { - qp_internal_pixel_output_state_t* state = (qp_internal_pixel_output_state_t*)cb_arg; - painter_driver_t* driver = (painter_driver_t*)state->device; - - if (!driver->driver_vtable->append_pixels(state->device, qp_internal_global_pixdata_buffer, palette, state->pixel_write_pos++, 1, &index)) { - return false; - } - - // If we've hit the transmit limit, send out the entire buffer and reset the write position - if (state->pixel_write_pos == state->max_pixels) { - if (!driver->driver_vtable->pixdata(state->device, qp_internal_global_pixdata_buffer, state->pixel_write_pos)) { - return false; - } - state->pixel_write_pos = 0; - } - - return true; -} - -bool qp_internal_byte_appender(uint8_t byteval, void* cb_arg) { - qp_internal_byte_output_state_t* state = (qp_internal_byte_output_state_t*)cb_arg; - painter_driver_t* driver = (painter_driver_t*)state->device; - - if (!driver->driver_vtable->append_pixdata(state->device, qp_internal_global_pixdata_buffer, state->byte_write_pos++, byteval)) { - return false; - } - - // If we've hit the transmit limit, send out the entire buffer and reset the write position - if (state->byte_write_pos == state->max_bytes) { - painter_driver_t* driver = (painter_driver_t*)state->device; - if (!driver->driver_vtable->pixdata(state->device, qp_internal_global_pixdata_buffer, state->byte_write_pos * 8 / driver->native_bits_per_pixel)) { - return false; - } - state->byte_write_pos = 0; - } - - return true; -} - -qp_internal_byte_input_callback qp_internal_prepare_input_state(qp_internal_byte_input_state_t* input_state, painter_compression_t compression) { - switch (compression) { - case IMAGE_UNCOMPRESSED: - return qp_drawimage_byte_uncompressed_decoder; - case IMAGE_COMPRESSED_RLE: - input_state->rle.mode = MARKER_BYTE; - input_state->rle.remain = 0; - return qp_drawimage_byte_rle_decoder; - default: - return NULL; - } -} diff --git a/quantum/painter/qp_draw_core.c b/quantum/painter/qp_draw_core.c deleted file mode 100644 index 3988aaedf8e8..000000000000 --- a/quantum/painter/qp_draw_core.c +++ /dev/null @@ -1,294 +0,0 @@ -// Copyright 2021-2022 Nick Brassel (@tzarc) -// Copyright 2021 Paul Cotter (@gr1mr3aver) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_internal.h" -#include "qp_comms.h" -#include "qp_draw.h" -#include "qgf.h" - -_Static_assert((QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE > 0) && (QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE % 16) == 0, "QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE needs to be a non-zero multiple of 16"); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Global variables -// -// NOTE: The variables in this section are intentionally outside a stack frame. They are able to be defined with larger -// sizes than the normal stack frames would allow, and as such need to be external. -// -// **** DO NOT refactor this and decide to place the variables inside the function calling them -- you will **** -// **** very likely get artifacts rendered to the screen as a result. **** -// - -// Buffer used for transmitting native pixel data to the downstream device. -__attribute__((__aligned__(4))) uint8_t qp_internal_global_pixdata_buffer[QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE]; - -// Static buffer to contain a generated color palette -static bool generated_palette = false; -static int16_t generated_steps = -1; -__attribute__((__aligned__(4))) static qp_pixel_t interpolated_fg_hsv888; -__attribute__((__aligned__(4))) static qp_pixel_t interpolated_bg_hsv888; -#if QUANTUM_PAINTER_SUPPORTS_256_PALETTE -__attribute__((__aligned__(4))) qp_pixel_t qp_internal_global_pixel_lookup_table[256]; -#else -__attribute__((__aligned__(4))) qp_pixel_t qp_internal_global_pixel_lookup_table[16]; -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers - -uint32_t qp_internal_num_pixels_in_buffer(painter_device_t device) { - painter_driver_t *driver = (painter_driver_t *)device; - return ((QUANTUM_PAINTER_PIXDATA_BUFFER_SIZE * 8) / driver->native_bits_per_pixel); -} - -// qp_setpixel internal implementation, but accepts a buffer with pre-converted native pixel. Only the first pixel is used. -bool qp_internal_setpixel_impl(painter_device_t device, uint16_t x, uint16_t y) { - painter_driver_t *driver = (painter_driver_t *)device; - return driver->driver_vtable->viewport(device, x, y, x, y) && driver->driver_vtable->pixdata(device, qp_internal_global_pixdata_buffer, 1); -} - -// Fills the global native pixel buffer with equivalent pixels matching the supplied HSV -void qp_internal_fill_pixdata(painter_device_t device, uint32_t num_pixels, uint8_t hue, uint8_t sat, uint8_t val) { - painter_driver_t *driver = (painter_driver_t *)device; - uint32_t pixels_in_pixdata = qp_internal_num_pixels_in_buffer(device); - num_pixels = QP_MIN(pixels_in_pixdata, num_pixels); - - // Convert the color to native pixel format - qp_pixel_t color = {.hsv888 = {.h = hue, .s = sat, .v = val}}; - driver->driver_vtable->palette_convert(device, 1, &color); - - // Append the required number of pixels - uint8_t palette_idx = 0; - for (uint32_t i = 0; i < num_pixels; ++i) { - driver->driver_vtable->append_pixels(device, qp_internal_global_pixdata_buffer, &color, i, 1, &palette_idx); - } -} - -// Resets the global palette so that it can be regenerated. Only needed if the colors are identical, but a different display is used with a different internal pixel format. -void qp_internal_invalidate_palette(void) { - generated_palette = false; - generated_steps = -1; -} - -// Interpolates between two colors to generate a palette -bool qp_internal_interpolate_palette(qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, int16_t steps) { - // Check if we need to generate a new palette -- if the input parameters match then assume the palette can stay unchanged. - // This may present a problem if using the same parameters but a different screen converts pixels -- use qp_internal_invalidate_palette() to reset. - if (generated_palette == true && generated_steps == steps && memcmp(&interpolated_fg_hsv888, &fg_hsv888, sizeof(fg_hsv888)) == 0 && memcmp(&interpolated_bg_hsv888, &bg_hsv888, sizeof(bg_hsv888)) == 0) { - // We already have the correct palette, no point regenerating it. - return false; - } - - // Save the parameters so we know whether we can skip generation - generated_palette = true; - generated_steps = steps; - interpolated_fg_hsv888 = fg_hsv888; - interpolated_bg_hsv888 = bg_hsv888; - - int16_t hue_fg = fg_hsv888.hsv888.h; - int16_t hue_bg = bg_hsv888.hsv888.h; - - // Make sure we take the "shortest" route from one hue to the other - if ((hue_fg - hue_bg) >= 128) { - hue_bg += 256; - } else if ((hue_fg - hue_bg) <= -128) { - hue_bg -= 256; - } - - // Interpolate each of the lookup table entries - for (int16_t i = 0; i < steps; ++i) { - qp_internal_global_pixel_lookup_table[i].hsv888.h = (uint8_t)((hue_fg - hue_bg) * i / (steps - 1) + hue_bg); - qp_internal_global_pixel_lookup_table[i].hsv888.s = (uint8_t)((fg_hsv888.hsv888.s - bg_hsv888.hsv888.s) * i / (steps - 1) + bg_hsv888.hsv888.s); - qp_internal_global_pixel_lookup_table[i].hsv888.v = (uint8_t)((fg_hsv888.hsv888.v - bg_hsv888.hsv888.v) * i / (steps - 1) + bg_hsv888.hsv888.v); - - qp_dprintf("qp_internal_interpolate_palette: %3d of %d -- H: %3d, S: %3d, V: %3d\n", (int)(i + 1), (int)steps, (int)qp_internal_global_pixel_lookup_table[i].hsv888.h, (int)qp_internal_global_pixel_lookup_table[i].hsv888.s, (int)qp_internal_global_pixel_lookup_table[i].hsv888.v); - } - - return true; -} - -// Helper shared between image and font rendering -- sets up the global palette to match the palette block specified in the asset. Expects the stream to be positioned at the start of the block header. -bool qp_internal_load_qgf_palette(qp_stream_t *stream, uint8_t bpp) { - qgf_palette_v1_t palette_descriptor; - if (qp_stream_read(&palette_descriptor, sizeof(qgf_palette_v1_t), 1, stream) != 1) { - qp_dprintf("Failed to read palette_descriptor, expected length was not %d\n", (int)sizeof(qgf_palette_v1_t)); - return false; - } - - // BPP determines the number of palette entries, each entry is a HSV888 triplet. - const uint16_t palette_entries = 1u << bpp; - - // Ensure we aren't reusing any palette - qp_internal_invalidate_palette(); - - // Read the palette entries - for (uint16_t i = 0; i < palette_entries; ++i) { - // Read the palette entry - qgf_palette_entry_v1_t entry; - if (qp_stream_read(&entry, sizeof(qgf_palette_entry_v1_t), 1, stream) != 1) { - return false; - } - - // Update the lookup table - qp_internal_global_pixel_lookup_table[i].hsv888.h = entry.h; - qp_internal_global_pixel_lookup_table[i].hsv888.s = entry.s; - qp_internal_global_pixel_lookup_table[i].hsv888.v = entry.v; - - qp_dprintf("qp_internal_load_qgf_palette: %3d of %d -- H: %3d, S: %3d, V: %3d\n", (int)(i + 1), (int)palette_entries, (int)qp_internal_global_pixel_lookup_table[i].hsv888.h, (int)qp_internal_global_pixel_lookup_table[i].hsv888.s, (int)qp_internal_global_pixel_lookup_table[i].hsv888.v); - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_setpixel - -bool qp_setpixel(painter_device_t device, uint16_t x, uint16_t y, uint8_t hue, uint8_t sat, uint8_t val) { - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_setpixel: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("Failed to start comms in qp_setpixel\n"); - return false; - } - - qp_internal_fill_pixdata(device, 1, hue, sat, val); - bool ret = qp_internal_setpixel_impl(device, x, y); - qp_comms_stop(device); - qp_dprintf("qp_setpixel: %s\n", ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_line - -bool qp_line(painter_device_t device, uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint8_t hue, uint8_t sat, uint8_t val) { - if (x0 == x1 || y0 == y1) { - qp_dprintf("qp_line(%d, %d, %d, %d): entry (deferring to qp_rect)\n", (int)x0, (int)y0, (int)x1, (int)y1); - bool ret = qp_rect(device, x0, y0, x1, y1, hue, sat, val, true); - qp_dprintf("qp_line(%d, %d, %d, %d): %s (deferred to qp_rect)\n", (int)x0, (int)y0, (int)x1, (int)y1, ret ? "ok" : "fail"); - return ret; - } - - qp_dprintf("qp_line(%d, %d, %d, %d): entry\n", (int)x0, (int)y0, (int)x1, (int)y1); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_line: fail (validation_ok == false)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("Failed to start comms in qp_line\n"); - return false; - } - - qp_internal_fill_pixdata(device, 1, hue, sat, val); - - // draw angled line using Bresenham's algo - int16_t x = ((int16_t)x0); - int16_t y = ((int16_t)y0); - int16_t slopex = ((int16_t)x0) < ((int16_t)x1) ? 1 : -1; - int16_t slopey = ((int16_t)y0) < ((int16_t)y1) ? 1 : -1; - int16_t dx = abs(((int16_t)x1) - ((int16_t)x0)); - int16_t dy = -abs(((int16_t)y1) - ((int16_t)y0)); - - int16_t e = dx + dy; - int16_t e2 = 2 * e; - - bool ret = true; - while (x != x1 || y != y1) { - if (!qp_internal_setpixel_impl(device, x, y)) { - ret = false; - break; - } - e2 = 2 * e; - if (e2 >= dy) { - e += dy; - x += slopex; - } - if (e2 <= dx) { - e += dx; - y += slopey; - } - } - // draw the last pixel - if (!qp_internal_setpixel_impl(device, x, y)) { - ret = false; - } - - qp_comms_stop(device); - qp_dprintf("qp_line(%d, %d, %d, %d): %s\n", (int)x0, (int)y0, (int)x1, (int)y1, ret ? "ok" : "fail"); - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_rect - -bool qp_internal_fillrect_helper_impl(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom) { - uint32_t pixels_in_pixdata = qp_internal_num_pixels_in_buffer(device); - painter_driver_t *driver = (painter_driver_t *)device; - - uint16_t l = QP_MIN(left, right); - uint16_t r = QP_MAX(left, right); - uint16_t t = QP_MIN(top, bottom); - uint16_t b = QP_MAX(top, bottom); - uint16_t w = r - l + 1; - uint16_t h = b - t + 1; - - uint32_t remaining = w * h; - driver->driver_vtable->viewport(device, l, t, r, b); - while (remaining > 0) { - uint32_t transmit = QP_MIN(remaining, pixels_in_pixdata); - if (!driver->driver_vtable->pixdata(device, qp_internal_global_pixdata_buffer, transmit)) { - return false; - } - remaining -= transmit; - } - return true; -} - -bool qp_rect(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom, uint8_t hue, uint8_t sat, uint8_t val, bool filled) { - qp_dprintf("qp_rect(%d, %d, %d, %d): entry\n", (int)left, (int)top, (int)right, (int)bottom); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_rect: fail (validation_ok == false)\n"); - return false; - } - - // Cater for cases where people have submitted the coordinates backwards - uint16_t l = QP_MIN(left, right); - uint16_t r = QP_MAX(left, right); - uint16_t t = QP_MIN(top, bottom); - uint16_t b = QP_MAX(top, bottom); - uint16_t w = r - l + 1; - uint16_t h = b - t + 1; - - bool ret = true; - if (!qp_comms_start(device)) { - qp_dprintf("Failed to start comms in qp_rect\n"); - return false; - } - - if (filled) { - // Fill up the pixdata buffer with the required number of native pixels - qp_internal_fill_pixdata(device, w * h, hue, sat, val); - - // Perform the draw - ret = qp_internal_fillrect_helper_impl(device, l, t, r, b); - } else { - // Fill up the pixdata buffer with the required number of native pixels - qp_internal_fill_pixdata(device, QP_MAX(w, h), hue, sat, val); - - // Draw 4x filled single-width rects to create an outline - if (!qp_internal_fillrect_helper_impl(device, l, t, r, t) || !qp_internal_fillrect_helper_impl(device, l, b, r, b) || !qp_internal_fillrect_helper_impl(device, l, t + 1, l, b - 1) || !qp_internal_fillrect_helper_impl(device, r, t + 1, r, b - 1)) { - ret = false; - } - } - - qp_comms_stop(device); - qp_dprintf("qp_rect(%d, %d, %d, %d): %s\n", (int)l, (int)t, (int)r, (int)b, ret ? "ok" : "fail"); - return ret; -} diff --git a/quantum/painter/qp_draw_ellipse.c b/quantum/painter/qp_draw_ellipse.c deleted file mode 100644 index 5c7abd7a7da3..000000000000 --- a/quantum/painter/qp_draw_ellipse.c +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 2021 Paul Cotter (@gr1mr3aver) -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_internal.h" -#include "qp_comms.h" -#include "qp_draw.h" - -// Utilize 4-way symmetry to draw an ellipse -static bool qp_ellipse_helper_impl(painter_device_t device, uint16_t centerx, uint16_t centery, uint16_t offsetx, uint16_t offsety, bool filled) { - /* - Ellipses have the property of 4-way symmetry, so four pixels can be drawn - for each computed [offsetx,offsety] given the center coordinates - represented by [centerx,centery]. - - For filled ellipses, we can draw horizontal lines between each pair of - pixels with the same final value of y. - - When offsetx == 0 only two pixels can be drawn for filled or unfilled ellipses - */ - - int16_t xpx = ((int16_t)centerx) + ((int16_t)offsetx); - int16_t xmx = ((int16_t)centerx) - ((int16_t)offsetx); - int16_t ypy = ((int16_t)centery) + ((int16_t)offsety); - int16_t ymy = ((int16_t)centery) - ((int16_t)offsety); - - if (offsetx == 0) { - if (!qp_internal_setpixel_impl(device, xpx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpx, ymy)) { - return false; - } - } else if (filled) { - if (!qp_internal_fillrect_helper_impl(device, xpx, ypy, xmx, ypy)) { - return false; - } - if (offsety > 0 && !qp_internal_fillrect_helper_impl(device, xpx, ymy, xmx, ymy)) { - return false; - } - } else { - if (!qp_internal_setpixel_impl(device, xpx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xpx, ymy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmx, ypy)) { - return false; - } - if (!qp_internal_setpixel_impl(device, xmx, ymy)) { - return false; - } - } - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_ellipse - -bool qp_ellipse(painter_device_t device, uint16_t x, uint16_t y, uint16_t sizex, uint16_t sizey, uint8_t hue, uint8_t sat, uint8_t val, bool filled) { - qp_dprintf("qp_ellipse: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_ellipse: fail (validation_ok == false)\n"); - return false; - } - - int16_t aa = ((int16_t)sizex) * ((int16_t)sizex); - int16_t bb = ((int16_t)sizey) * ((int16_t)sizey); - int16_t fa = 4 * ((int16_t)aa); - int16_t fb = 4 * ((int16_t)bb); - - int16_t dx = 0; - int16_t dy = ((int16_t)sizey); - - qp_internal_fill_pixdata(device, QP_MAX(sizex, sizey), hue, sat, val); - - if (!qp_comms_start(device)) { - qp_dprintf("qp_ellipse: fail (could not start comms)\n"); - return false; - } - - bool ret = true; - for (int16_t delta = (2 * bb) + (aa * (1 - (2 * sizey))); bb * dx <= aa * dy; dx++) { - if (!qp_ellipse_helper_impl(device, x, y, dx, dy, filled)) { - ret = false; - break; - } - if (delta >= 0) { - delta += fa * (1 - dy); - dy--; - } - delta += bb * (4 * dx + 6); - } - - dx = sizex; - dy = 0; - - for (int16_t delta = (2 * aa) + (bb * (1 - (2 * sizex))); aa * dy <= bb * dx; dy++) { - if (!qp_ellipse_helper_impl(device, x, y, dx, dy, filled)) { - ret = false; - break; - } - if (delta >= 0) { - delta += fb * (1 - dx); - dx--; - } - delta += aa * (4 * dy + 6); - } - - qp_dprintf("qp_ellipse: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret; -} diff --git a/quantum/painter/qp_draw_image.c b/quantum/painter/qp_draw_image.c deleted file mode 100644 index 9f86b29f8b0d..000000000000 --- a/quantum/painter/qp_draw_image.c +++ /dev/null @@ -1,420 +0,0 @@ -// Copyright 2021-2023 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_internal.h" -#include "qp_draw.h" -#include "qp_comms.h" -#include "qgf.h" -#include "deferred_exec.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QGF image handles - -typedef struct qgf_image_handle_t { - painter_image_desc_t base; - bool validate_ok; - union { - qp_stream_t stream; - qp_memory_stream_t mem_stream; -#ifdef QP_STREAM_HAS_FILE_IO - qp_file_stream_t file_stream; -#endif // QP_STREAM_HAS_FILE_IO - }; -} qgf_image_handle_t; - -static qgf_image_handle_t image_descriptors[QUANTUM_PAINTER_NUM_IMAGES] = {0}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helper: load image from stream - -static painter_image_handle_t qp_load_image_internal(bool (*stream_factory)(qgf_image_handle_t *image, void *arg), void *arg) { - qp_dprintf("qp_load_image: entry\n"); - qgf_image_handle_t *image = NULL; - - // Find a free slot - for (int i = 0; i < QUANTUM_PAINTER_NUM_IMAGES; ++i) { - if (!image_descriptors[i].validate_ok) { - image = &image_descriptors[i]; - break; - } - } - - // Drop out if not found - if (!image) { - qp_dprintf("qp_load_image: fail (no free slot)\n"); - return NULL; - } - - if (!stream_factory(image, arg)) { - qp_dprintf("qp_load_image: fail (could not create stream)\n"); - return NULL; - } - - // Now that we know the length, validate the input data - if (!qgf_validate_stream(&image->stream)) { - qp_dprintf("qp_load_image: fail (failed validation)\n"); - return NULL; - } - - // Fill out the QP image descriptor - qgf_read_graphics_descriptor(&image->stream, &image->base.width, &image->base.height, &image->base.frame_count, NULL); - - // Validation success, we can return the handle - image->validate_ok = true; - qp_dprintf("qp_load_image: ok\n"); - return (painter_image_handle_t)image; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_load_image_mem - -static inline bool image_mem_stream_factory(qgf_image_handle_t *image, void *arg) { - void *buffer = arg; - - // Assume we can read the graphics descriptor - image->mem_stream = qp_make_memory_stream((void *)buffer, sizeof(qgf_graphics_descriptor_v1_t)); - - // Update the length of the stream to match, and rewind to the start - image->mem_stream.length = qgf_get_total_size(&image->stream); - image->mem_stream.position = 0; - - return true; -} - -painter_image_handle_t qp_load_image_mem(const void *buffer) { - return qp_load_image_internal(image_mem_stream_factory, (void *)buffer); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_close_image - -bool qp_close_image(painter_image_handle_t image) { - qgf_image_handle_t *qgf_image = (qgf_image_handle_t *)image; - if (!qgf_image->validate_ok) { - qp_dprintf("qp_close_image: fail (invalid image)\n"); - return false; - } - - // Free up this image for use elsewhere. - qgf_image->validate_ok = false; - qp_stream_close(&qgf_image->stream); - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_drawimage - -bool qp_drawimage(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image) { - return qp_drawimage_recolor(device, x, y, image, 0, 0, 255, 0, 0, 0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_drawimage_recolor - -typedef struct qgf_frame_info_t { - painter_compression_t compression_scheme; - uint8_t bpp; - bool has_palette; - bool is_delta; - uint16_t left; - uint16_t top; - uint16_t right; - uint16_t bottom; - uint16_t delay; -} qgf_frame_info_t; - -static bool qp_drawimage_prepare_frame_for_stream_read(painter_device_t device, qgf_image_handle_t *qgf_image, uint16_t frame_number, qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, qgf_frame_info_t *info) { - painter_driver_t *driver = (painter_driver_t *)device; - - // Drop out if we can't actually place the data we read out anywhere - if (!info) { - qp_dprintf("Failed to prepare stream for read, output info buffer unavailable\n"); - return false; - } - - // Seek to the frame - qgf_seek_to_frame_descriptor(&qgf_image->stream, frame_number); - - // Read the frame descriptor - qgf_frame_v1_t frame_descriptor; - if (qp_stream_read(&frame_descriptor, sizeof(qgf_frame_v1_t), 1, &qgf_image->stream) != 1) { - qp_dprintf("Failed to read frame_descriptor, expected length was not %d\n", (int)sizeof(qgf_frame_v1_t)); - return false; - } - - // Parse out the frame info - if (!qgf_parse_frame_descriptor(&frame_descriptor, &info->bpp, &info->has_palette, &info->is_delta, &info->compression_scheme, &info->delay)) { - return false; - } - - // Ensure we aren't reusing any palette - qp_internal_invalidate_palette(); - - if (!qp_internal_bpp_capable(info->bpp)) { - qp_dprintf("qp_drawimage_recolor: fail (image bpp too high (%d), check QUANTUM_PAINTER_SUPPORTS_256_PALETTE or QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS)\n", (int)info->bpp); - qp_comms_stop(device); - return false; - } - - // Handle palette if needed - const uint16_t palette_entries = 1u << info->bpp; - bool needs_pixconvert = false; - if (info->has_palette) { - // Load the palette from the stream - if (!qp_internal_load_qgf_palette((qp_stream_t *)&qgf_image->stream, info->bpp)) { - return false; - } - - needs_pixconvert = true; - } else { - if (info->bpp <= 8) { - // Interpolate from fg/bg - needs_pixconvert = qp_internal_interpolate_palette(fg_hsv888, bg_hsv888, palette_entries); - } - } - - if (needs_pixconvert) { - // Convert the palette to native format - if (!driver->driver_vtable->palette_convert(device, palette_entries, qp_internal_global_pixel_lookup_table)) { - qp_dprintf("qp_drawimage_recolor: fail (could not convert pixels to native)\n"); - qp_comms_stop(device); - return false; - } - } - - // Handle delta if needed - if (info->is_delta) { - qgf_delta_v1_t delta_descriptor; - if (qp_stream_read(&delta_descriptor, sizeof(qgf_delta_v1_t), 1, &qgf_image->stream) != 1) { - qp_dprintf("Failed to read delta_descriptor, expected length was not %d\n", (int)sizeof(qgf_delta_v1_t)); - return false; - } - - info->left = delta_descriptor.left; - info->top = delta_descriptor.top; - info->right = delta_descriptor.right; - info->bottom = delta_descriptor.bottom; - } - - // Read the data block - qgf_data_v1_t data_descriptor; - if (qp_stream_read(&data_descriptor, sizeof(qgf_data_v1_t), 1, &qgf_image->stream) != 1) { - qp_dprintf("Failed to read data_descriptor, expected length was not %d\n", (int)sizeof(qgf_data_v1_t)); - return false; - } - - // Stream is now at the point of being able to read pixdata - return true; -} - -static bool qp_drawimage_recolor_impl(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, int frame_number, qgf_frame_info_t *frame_info, qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888) { - qp_dprintf("qp_drawimage_recolor: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_drawimage_recolor: fail (validation_ok == false)\n"); - return false; - } - - qgf_image_handle_t *qgf_image = (qgf_image_handle_t *)image; - if (!qgf_image->validate_ok) { - qp_dprintf("qp_drawimage_recolor: fail (invalid image)\n"); - return false; - } - - // Read the frame info - if (!qp_drawimage_prepare_frame_for_stream_read(device, qgf_image, frame_number, fg_hsv888, bg_hsv888, frame_info)) { - qp_dprintf("qp_drawimage_recolor: fail (could not read frame %d)\n", frame_number); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_drawimage_recolor: fail (could not start comms)\n"); - return false; - } - - uint16_t l, t, r, b; - if (frame_info->is_delta) { - l = x + frame_info->left; - t = y + frame_info->top; - r = x + frame_info->right - 1; - b = y + frame_info->bottom - 1; - } else { - l = x; - t = y; - r = x + image->width - 1; - b = y + image->height - 1; - } - uint32_t pixel_count = ((uint32_t)(r - l + 1)) * (b - t + 1); - - // Configure where we're going to be rendering to - if (!driver->driver_vtable->viewport(device, l, t, r, b)) { - qp_dprintf("qp_drawimage_recolor: fail (could not set viewport)\n"); - qp_comms_stop(device); - return false; - } - - // Set up the input state - qp_internal_byte_input_state_t input_state = {.device = device, .src_stream = &qgf_image->stream}; - qp_internal_byte_input_callback input_callback = qp_internal_prepare_input_state(&input_state, frame_info->compression_scheme); - if (input_callback == NULL) { - qp_dprintf("qp_drawimage_recolor: fail (invalid image compression scheme)\n"); - qp_comms_stop(device); - return false; - } - - bool ret = false; - if (frame_info->bpp <= 8) { - // Set up the output state - qp_internal_pixel_output_state_t output_state = {.device = device, .pixel_write_pos = 0, .max_pixels = qp_internal_num_pixels_in_buffer(device)}; - - // Decode the pixel data and stream to the display - ret = qp_internal_decode_palette(device, pixel_count, frame_info->bpp, input_callback, &input_state, qp_internal_global_pixel_lookup_table, qp_internal_pixel_appender, &output_state); - // Any leftovers need transmission as well. - if (ret && output_state.pixel_write_pos > 0) { - ret &= driver->driver_vtable->pixdata(device, qp_internal_global_pixdata_buffer, output_state.pixel_write_pos); - } - } else if (frame_info->bpp != driver->native_bits_per_pixel) { - // Prevent stuff like drawing 24bpp images on 16bpp displays - qp_dprintf("Image's bpp doesn't match the target display's native_bits_per_pixel\n"); - return false; - } else { - // Set up the output state - qp_internal_byte_output_state_t output_state = {.device = device, .byte_write_pos = 0, .max_bytes = qp_internal_num_pixels_in_buffer(device) * driver->native_bits_per_pixel / 8}; - - // Stream the raw pixel data to the display - uint32_t byte_count = pixel_count * frame_info->bpp / 8; - ret = qp_internal_send_bytes(device, byte_count, input_callback, &input_state, qp_internal_byte_appender, &output_state); - // Any leftovers need transmission as well. - if (ret && output_state.byte_write_pos > 0) { - ret &= driver->driver_vtable->pixdata(device, qp_internal_global_pixdata_buffer, output_state.byte_write_pos * 8 / driver->native_bits_per_pixel); - } - } - - qp_dprintf("qp_drawimage_recolor: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret; -} - -bool qp_drawimage_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg) { - qgf_frame_info_t frame_info = {0}; - qp_pixel_t fg_hsv888 = {.hsv888 = {.h = hue_fg, .s = sat_fg, .v = val_fg}}; - qp_pixel_t bg_hsv888 = {.hsv888 = {.h = hue_bg, .s = sat_bg, .v = val_bg}}; - return qp_drawimage_recolor_impl(device, x, y, image, 0, &frame_info, fg_hsv888, bg_hsv888); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_animate - -deferred_token qp_animate(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image) { - return qp_animate_recolor(device, x, y, image, 0, 0, 255, 0, 0, 0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_animate_recolor - -typedef struct animation_state_t { - painter_device_t device; - uint16_t x; - uint16_t y; - painter_image_handle_t image; - qp_pixel_t fg_hsv888; - qp_pixel_t bg_hsv888; - uint16_t frame_number; - deferred_token defer_token; -} animation_state_t; - -static deferred_executor_t animation_executors[QUANTUM_PAINTER_CONCURRENT_ANIMATIONS] = {0}; -static animation_state_t animation_states[QUANTUM_PAINTER_CONCURRENT_ANIMATIONS] = {0}; - -static deferred_token qp_render_animation_state(animation_state_t *state, uint16_t *delay_ms) { - qgf_frame_info_t frame_info = {0}; - qp_dprintf("qp_render_animation_state: entry (frame #%d)\n", (int)state->frame_number); - bool ret = qp_drawimage_recolor_impl(state->device, state->x, state->y, state->image, state->frame_number, &frame_info, state->fg_hsv888, state->bg_hsv888); - if (ret) { - ++state->frame_number; - if (state->frame_number >= state->image->frame_count) { - state->frame_number = 0; - } - *delay_ms = frame_info.delay; - } - qp_dprintf("qp_render_animation_state: %s (delay %dms)\n", ret ? "ok" : "fail", (int)(*delay_ms)); - return ret; -} - -static uint32_t animation_callback(uint32_t trigger_time, void *cb_arg) { - animation_state_t *state = (animation_state_t *)cb_arg; - uint16_t delay_ms; - bool ret = qp_render_animation_state(state, &delay_ms); - if (!ret) { - // Setting the device to NULL clears the animation slot - state->device = NULL; - } - // If we're successful, keep animating -- returning 0 cancels the deferred execution - return ret ? delay_ms : 0; -} - -deferred_token qp_animate_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_image_handle_t image, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg) { - qp_dprintf("qp_animate_recolor: entry\n"); - - animation_state_t *anim_state = NULL; - for (int i = 0; i < QUANTUM_PAINTER_CONCURRENT_ANIMATIONS; ++i) { - if (animation_states[i].device == NULL) { - anim_state = &animation_states[i]; - break; - } - } - - if (!anim_state) { - qp_dprintf("qp_animate_recolor: fail (could not find free animation slot)\n"); - return INVALID_DEFERRED_TOKEN; - } - - // Prepare the animation state - anim_state->device = device; - anim_state->x = x; - anim_state->y = y; - anim_state->image = image; - anim_state->fg_hsv888 = (qp_pixel_t){.hsv888 = {.h = hue_fg, .s = sat_fg, .v = val_fg}}; - anim_state->bg_hsv888 = (qp_pixel_t){.hsv888 = {.h = hue_bg, .s = sat_bg, .v = val_bg}}; - anim_state->frame_number = 0; - - // Draw the first frame - uint16_t delay_ms; - if (!qp_render_animation_state(anim_state, &delay_ms)) { - anim_state->device = NULL; // disregard the allocated animation slot - qp_dprintf("qp_animate_recolor: fail (could not render first frame)\n"); - return INVALID_DEFERRED_TOKEN; - } - - // Set up the timer - anim_state->defer_token = defer_exec_advanced(animation_executors, QUANTUM_PAINTER_CONCURRENT_ANIMATIONS, delay_ms, animation_callback, anim_state); - if (anim_state->defer_token == INVALID_DEFERRED_TOKEN) { - anim_state->device = NULL; // disregard the allocated animation slot - qp_dprintf("qp_animate_recolor: fail (could not set up animation executor)\n"); - return INVALID_DEFERRED_TOKEN; - } - - qp_dprintf("qp_animate_recolor: ok (deferred token = %d)\n", (int)anim_state->defer_token); - return anim_state->defer_token; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_stop_animation - -void qp_stop_animation(deferred_token anim_token) { - for (int i = 0; i < QUANTUM_PAINTER_CONCURRENT_ANIMATIONS; ++i) { - if (animation_states[i].defer_token == anim_token) { - cancel_deferred_exec_advanced(animation_executors, QUANTUM_PAINTER_CONCURRENT_ANIMATIONS, anim_token); - animation_states[i].device = NULL; - return; - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Core API: qp_internal_animation_tick - -void qp_internal_animation_tick(void) { - static uint32_t last_anim_exec = 0; - deferred_exec_advanced_task(animation_executors, QUANTUM_PAINTER_CONCURRENT_ANIMATIONS, &last_anim_exec); -} diff --git a/quantum/painter/qp_draw_text.c b/quantum/painter/qp_draw_text.c deleted file mode 100644 index a70caac6f4bc..000000000000 --- a/quantum/painter/qp_draw_text.c +++ /dev/null @@ -1,463 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include -#include - -#include "qp_internal.h" -#include "qp_draw.h" -#include "qp_comms.h" -#include "qff.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// QFF font handles - -typedef struct qff_font_handle_t { - painter_font_desc_t base; - bool validate_ok; - bool has_ascii_table; - uint16_t num_unicode_glyphs; - uint8_t bpp; - bool has_palette; - painter_compression_t compression_scheme; - union { - qp_stream_t stream; - qp_memory_stream_t mem_stream; -#ifdef QP_STREAM_HAS_FILE_IO - qp_file_stream_t file_stream; -#endif // QP_STREAM_HAS_FILE_IO - }; -#if QUANTUM_PAINTER_LOAD_FONTS_TO_RAM - bool owns_buffer; - void *buffer; -#endif // QUANTUM_PAINTER_LOAD_FONTS_TO_RAM -} qff_font_handle_t; - -static qff_font_handle_t font_descriptors[QUANTUM_PAINTER_NUM_FONTS] = {0}; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helper: load font from stream - -static painter_font_handle_t qp_load_font_internal(bool (*stream_factory)(qff_font_handle_t *font, void *arg), void *arg) { - qp_dprintf("qp_load_font: entry\n"); - qff_font_handle_t *font = NULL; - - // Find a free slot - for (int i = 0; i < QUANTUM_PAINTER_NUM_FONTS; ++i) { - if (!font_descriptors[i].validate_ok) { - font = &font_descriptors[i]; - break; - } - } - - // Drop out if not found - if (!font) { - qp_dprintf("qp_load_font: fail (no free slot)\n"); - return NULL; - } - - if (!stream_factory(font, arg)) { - qp_dprintf("qp_load_font: fail (could not create stream)\n"); - return NULL; - } - - // Now that we know the length, validate the input data - if (!qff_validate_stream(&font->stream)) { - qp_dprintf("qp_load_font: fail (failed validation)\n"); - return NULL; - } - -#if QUANTUM_PAINTER_LOAD_FONTS_TO_RAM - // Clear out any existing data - font->owns_buffer = false; - font->buffer = NULL; - - void *ram_buffer = malloc(font->mem_stream.length); - if (ram_buffer == NULL) { - qp_dprintf("qp_load_font: could not allocate enough RAM for font, falling back to original\n"); - } else { - do { - // Copy the data into RAM - if (qp_stream_read(ram_buffer, 1, font->mem_stream.length, &font->mem_stream) != font->mem_stream.length) { - qp_dprintf("qp_load_font: could not copy from flash to RAM, falling back to original\n"); - break; - } - - // Create the new stream with the new buffer - font->buffer = ram_buffer; - font->owns_buffer = true; - font->mem_stream = qp_make_memory_stream(font->buffer, font->mem_stream.length); - } while (0); - } - - // Free the buffer if we were unable to recreate the RAM copy. - if (ram_buffer != NULL && !font->owns_buffer) { - free(ram_buffer); - } -#endif // QUANTUM_PAINTER_LOAD_FONTS_TO_RAM - - // Read the info (parsing already successful above, no need to check return value) - qff_read_font_descriptor(&font->stream, &font->base.line_height, &font->has_ascii_table, &font->num_unicode_glyphs, &font->bpp, &font->has_palette, &font->compression_scheme, NULL); - - if (!qp_internal_bpp_capable(font->bpp)) { - qp_dprintf("qp_load_font: fail (image bpp too high (%d), check QUANTUM_PAINTER_SUPPORTS_256_PALETTE or QUANTUM_PAINTER_SUPPORTS_NATIVE_COLORS)\n", (int)font->bpp); - qp_close_font((painter_font_handle_t)font); - return NULL; - } - - // Validation success, we can return the handle - font->validate_ok = true; - qp_dprintf("qp_load_font: ok\n"); - return (painter_font_handle_t)font; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_load_font_mem - -static inline bool font_mem_stream_factory(qff_font_handle_t *font, void *arg) { - void *buffer = arg; - - // Assume we can read the graphics descriptor - font->mem_stream = qp_make_memory_stream(buffer, sizeof(qff_font_descriptor_v1_t)); - - // Update the length of the stream to match, and rewind to the start - font->mem_stream.length = qff_get_total_size(&font->stream); - font->mem_stream.position = 0; - - return true; -} - -painter_font_handle_t qp_load_font_mem(const void *buffer) { - return qp_load_font_internal(font_mem_stream_factory, (void *)buffer); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_close_font - -bool qp_close_font(painter_font_handle_t font) { - qff_font_handle_t *qff_font = (qff_font_handle_t *)font; - if (!qff_font->validate_ok) { - qp_dprintf("qp_close_font: fail (invalid font)\n"); - return false; - } - -#if QUANTUM_PAINTER_LOAD_FONTS_TO_RAM - // Nuke the buffer, if required - if (qff_font->owns_buffer) { - free(qff_font->buffer); - qff_font->buffer = NULL; - qff_font->owns_buffer = false; - } -#endif // QUANTUM_PAINTER_LOAD_FONTS_TO_RAM - - // Free up this font for use elsewhere. - qp_stream_close(&qff_font->stream); - qff_font->validate_ok = false; - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers - -// Callback to be invoked for each codepoint detected in the UTF8 input string -typedef bool (*code_point_handler)(qff_font_handle_t *qff_font, uint32_t code_point, uint8_t width, uint8_t height, void *cb_arg); - -// Helper that sets up the palette (if required) and returns the offset in the stream that the data starts -static inline bool qp_drawtext_prepare_font_for_render(painter_device_t device, qff_font_handle_t *qff_font, qp_pixel_t fg_hsv888, qp_pixel_t bg_hsv888, uint32_t *data_offset) { - painter_driver_t *driver = (painter_driver_t *)device; - - // Drop out if we can't actually place the data we read out anywhere - if (!data_offset) { - qp_dprintf("Failed to prepare stream for read, output info buffer unavailable\n"); - return false; - } - - // Work out where we're reading from - uint32_t offset = sizeof(qff_font_descriptor_v1_t); - if (qff_font->has_ascii_table) { - offset += sizeof(qff_ascii_glyph_table_v1_t); - } - if (qff_font->num_unicode_glyphs > 0) { - offset += sizeof(qff_unicode_glyph_table_v1_t) + (qff_font->num_unicode_glyphs * 6); - } - - // Handle palette if needed - const uint16_t palette_entries = 1u << qff_font->bpp; - bool needs_pixconvert = false; - if (qff_font->has_palette) { - // If this font has a palette, we need to read it out and set up the pixel lookup table - qp_stream_setpos(&qff_font->stream, offset); - if (!qp_internal_load_qgf_palette(&qff_font->stream, qff_font->bpp)) { - return false; - } - - // Skip this block, as far as offset calculations go - offset += sizeof(qgf_palette_v1_t) + (palette_entries * 3); - needs_pixconvert = true; - } else { - // Interpolate from fg/bg - int16_t palette_entries = 1 << qff_font->bpp; - needs_pixconvert = qp_internal_interpolate_palette(fg_hsv888, bg_hsv888, palette_entries); - } - - if (needs_pixconvert) { - // Convert the palette to native format - if (!driver->driver_vtable->palette_convert(device, palette_entries, qp_internal_global_pixel_lookup_table)) { - qp_dprintf("qp_drawtext_recolor: fail (could not convert pixels to native)\n"); - qp_comms_stop(device); - return false; - } - } - - *data_offset = offset; - return true; -} - -static inline bool qp_drawtext_prepare_glyph_for_render(qff_font_handle_t *qff_font, uint32_t code_point, uint8_t *width) { - if (code_point >= 0x20 && code_point < 0x7F && qff_font->has_ascii_table) { - // Do ascii table - qff_ascii_glyph_v1_t glyph_info; - uint32_t glyph_info_offset = sizeof(qff_font_descriptor_v1_t) // Skip the font descriptor - + sizeof(qgf_block_header_v1_t) // Skip the ascii table header - + (code_point - 0x20) * sizeof(qff_ascii_glyph_v1_t); // Jump direct to the data offset based on the glyph index - if (qp_stream_setpos(&qff_font->stream, glyph_info_offset) < 0) { - qp_dprintf("Failed to set stream position while reading ascii glyph info\n"); - return false; - } - - if (qp_stream_read(&glyph_info, sizeof(qff_ascii_glyph_v1_t), 1, &qff_font->stream) != 1) { - qp_dprintf("Failed to read glyph info\n"); - return false; - } - - uint8_t glyph_width = (uint8_t)(glyph_info.value & QFF_GLYPH_WIDTH_MASK); - uint32_t glyph_offset = ((glyph_info.value & QFF_GLYPH_OFFSET_MASK) >> QFF_GLYPH_WIDTH_BITS); - uint32_t data_offset = sizeof(qff_font_descriptor_v1_t) // Skip the font descriptor - + (qff_font->has_ascii_table ? sizeof(qff_ascii_glyph_table_v1_t) : 0) // Skip the ascii table - + (qff_font->num_unicode_glyphs > 0 ? (sizeof(qff_unicode_glyph_table_v1_t) + (qff_font->num_unicode_glyphs * sizeof(qff_unicode_glyph_v1_t))) : 0) // Skip the unicode table - + (qff_font->has_palette ? (sizeof(qgf_palette_v1_t) + ((1 << qff_font->bpp) * sizeof(qgf_palette_entry_v1_t))) : 0) // Skip the palette - + sizeof(qgf_block_header_v1_t) // Skip the data block header - + glyph_offset; // Jump to the specified glyph offset - - if (qp_stream_setpos(&qff_font->stream, data_offset) < 0) { - qp_dprintf("Failed to set stream position while preparing ascii glyph data\n"); - return false; - } - - *width = glyph_width; - return true; - } else { - // Do unicode table, which may include singular ascii glyphs if full ascii table isn't specified - uint32_t glyph_info_offset = sizeof(qff_font_descriptor_v1_t) // Skip the font descriptor - + (qff_font->has_ascii_table ? sizeof(qff_ascii_glyph_table_v1_t) : 0) // Skip the ascii table - + sizeof(qgf_block_header_v1_t); // Skip the unicode block header - - if (qp_stream_setpos(&qff_font->stream, glyph_info_offset) < 0) { - qp_dprintf("Failed to set stream position while preparing glyph data\n"); - return false; - } - - qff_unicode_glyph_v1_t glyph_info; - for (uint16_t i = 0; i < qff_font->num_unicode_glyphs; ++i) { - if (qp_stream_read(&glyph_info, sizeof(qff_unicode_glyph_v1_t), 1, &qff_font->stream) != 1) { - qp_dprintf("Failed to set stream position while reading unicode glyph info\n"); - return false; - } - - if (glyph_info.code_point == code_point) { - uint8_t glyph_width = (uint8_t)(glyph_info.value & QFF_GLYPH_WIDTH_MASK); - uint32_t glyph_offset = ((glyph_info.value & QFF_GLYPH_OFFSET_MASK) >> QFF_GLYPH_WIDTH_BITS); - uint32_t data_offset = sizeof(qff_font_descriptor_v1_t) // Skip the font descriptor - + (qff_font->has_ascii_table ? sizeof(qff_ascii_glyph_table_v1_t) : 0) // Skip the ascii table - + (qff_font->num_unicode_glyphs > 0 ? (sizeof(qff_unicode_glyph_table_v1_t) + (qff_font->num_unicode_glyphs * sizeof(qff_unicode_glyph_v1_t))) : 0) // Skip the unicode table - + (qff_font->has_palette ? (sizeof(qgf_palette_v1_t) + ((1 << qff_font->bpp) * sizeof(qgf_palette_entry_v1_t))) : 0) // Skip the palette - + sizeof(qgf_block_header_v1_t) // Skip the data block header - + glyph_offset; // Jump to the specified glyph offset - - if (qp_stream_setpos(&qff_font->stream, data_offset) < 0) { - qp_dprintf("Failed to set stream position while preparing unicode glyph data\n"); - return false; - } - - *width = glyph_width; - return true; - } - } - - // Not found - qp_dprintf("Failed to find unicode glyph info\n"); - return false; - } - return false; -} - -// Function to iterate over each UTF8 codepoint, invoking the callback for each decoded glyph -static inline bool qp_iterate_code_points(qff_font_handle_t *qff_font, const char *str, code_point_handler handler, void *cb_arg) { - while (*str) { - int32_t code_point = 0; - str = decode_utf8(str, &code_point); - if (code_point < 0) { - qp_dprintf("Invalid unicode code point decoded. Cannot render.\n"); - return false; - } - - uint8_t width; - if (!qp_drawtext_prepare_glyph_for_render(qff_font, code_point, &width)) { - qp_dprintf("Failed to prepare glyph for rendering.\n"); - return false; - } - - if (!handler(qff_font, code_point, width, qff_font->base.line_height, cb_arg)) { - qp_dprintf("Failed to execute glyph handler.\n"); - return false; - } - } - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// String width calculation - -// Callback state -typedef struct code_point_iter_calcwidth_state_t { - int16_t width; -} code_point_iter_calcwidth_state_t; - -// Codepoint handler callback: width calc -static inline bool qp_font_code_point_handler_calcwidth(qff_font_handle_t *qff_font, uint32_t code_point, uint8_t width, uint8_t height, void *cb_arg) { - code_point_iter_calcwidth_state_t *state = (code_point_iter_calcwidth_state_t *)cb_arg; - - // Increment the overall width by this glyph's width - state->width += width; - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// String drawing implementation - -// Callback state -typedef struct code_point_iter_drawglyph_state_t { - painter_device_t device; - int16_t xpos; - int16_t ypos; - qp_internal_byte_input_callback input_callback; - qp_internal_byte_input_state_t * input_state; - qp_internal_pixel_output_state_t *output_state; -} code_point_iter_drawglyph_state_t; - -// Codepoint handler callback: drawing -static inline bool qp_font_code_point_handler_drawglyph(qff_font_handle_t *qff_font, uint32_t code_point, uint8_t width, uint8_t height, void *cb_arg) { - code_point_iter_drawglyph_state_t *state = (code_point_iter_drawglyph_state_t *)cb_arg; - painter_driver_t * driver = (painter_driver_t *)state->device; - - // Reset the input state's RLE mode -- the stream should already be correctly positioned by qp_iterate_code_points() - state->input_state->rle.mode = MARKER_BYTE; // ignored if not using RLE - - // Reset the output state - state->output_state->pixel_write_pos = 0; - - // Configure where we're going to be rendering to - driver->driver_vtable->viewport(state->device, state->xpos, state->ypos, state->xpos + width - 1, state->ypos + height - 1); - - // Move the x-position for the next glyph - state->xpos += width; - - // Decode the pixel data for the glyph - uint32_t pixel_count = ((uint32_t)width) * height; - bool ret = qp_internal_decode_palette(state->device, pixel_count, qff_font->bpp, state->input_callback, state->input_state, qp_internal_global_pixel_lookup_table, qp_internal_pixel_appender, state->output_state); - - // Any leftovers need transmission as well. - if (ret && state->output_state->pixel_write_pos > 0) { - ret &= driver->driver_vtable->pixdata(state->device, qp_internal_global_pixdata_buffer, state->output_state->pixel_write_pos); - } - - return ret; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_textwidth - -int16_t qp_textwidth(painter_font_handle_t font, const char *str) { - qff_font_handle_t *qff_font = (qff_font_handle_t *)font; - if (!qff_font->validate_ok) { - qp_dprintf("qp_textwidth: fail (invalid font)\n"); - return false; - } - - // Create the codepoint iterator state - code_point_iter_calcwidth_state_t state = {.width = 0}; - // Iterate each codepoint, return the calculated width if successful. - return qp_iterate_code_points(qff_font, str, qp_font_code_point_handler_calcwidth, &state) ? state.width : 0; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_drawtext - -int16_t qp_drawtext(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str) { - // Offload to the recolor variant, substituting fg=white bg=black. - // Traditional LCDs with those colors will need to manually invoke qp_drawtext_recolor with the colors reversed. - return qp_drawtext_recolor(device, x, y, font, str, 0, 0, 255, 0, 0, 0); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter External API: qp_drawtext_recolor - -int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, painter_font_handle_t font, const char *str, uint8_t hue_fg, uint8_t sat_fg, uint8_t val_fg, uint8_t hue_bg, uint8_t sat_bg, uint8_t val_bg) { - qp_dprintf("qp_drawtext_recolor: entry\n"); - painter_driver_t *driver = (painter_driver_t *)device; - if (!driver->validate_ok) { - qp_dprintf("qp_drawtext_recolor: fail (validation_ok == false)\n"); - return 0; - } - - qff_font_handle_t *qff_font = (qff_font_handle_t *)font; - if (!qff_font->validate_ok) { - qp_dprintf("qp_drawtext_recolor: fail (invalid font)\n"); - return false; - } - - if (!qp_comms_start(device)) { - qp_dprintf("qp_drawtext_recolor: fail (could not start comms)\n"); - return 0; - } - - // Set up the byte input state and input callback - qp_internal_byte_input_state_t input_state = {.device = device, .src_stream = &qff_font->stream}; - qp_internal_byte_input_callback input_callback = qp_internal_prepare_input_state(&input_state, qff_font->compression_scheme); - if (input_callback == NULL) { - qp_dprintf("qp_drawtext_recolor: fail (invalid font compression scheme)\n"); - qp_comms_stop(device); - return false; - } - - // Set up the pixel output state - qp_internal_pixel_output_state_t output_state = {.device = device, .pixel_write_pos = 0, .max_pixels = qp_internal_num_pixels_in_buffer(device)}; - - // Set up the codepoint iteration state - code_point_iter_drawglyph_state_t state = {// Common - .device = device, - .xpos = x, - .ypos = y, - // Input - .input_callback = input_callback, - .input_state = &input_state, - // Output - .output_state = &output_state}; - - qp_pixel_t fg_hsv888 = {.hsv888 = {.h = hue_fg, .s = sat_fg, .v = val_fg}}; - qp_pixel_t bg_hsv888 = {.hsv888 = {.h = hue_bg, .s = sat_bg, .v = val_bg}}; - uint32_t data_offset; - if (!qp_drawtext_prepare_font_for_render(driver, qff_font, fg_hsv888, bg_hsv888, &data_offset)) { - qp_dprintf("qp_drawtext_recolor: fail (failed to prepare font for rendering)\n"); - qp_comms_stop(device); - return false; - } - - // Iterate the codepoints with the drawglyph callback - bool ret = qp_iterate_code_points(qff_font, str, qp_font_code_point_handler_drawglyph, &state); - - qp_dprintf("qp_drawtext_recolor: %s\n", ret ? "ok" : "fail"); - qp_comms_stop(device); - return ret ? (state.xpos - x) : 0; -} diff --git a/quantum/painter/qp_internal.c b/quantum/painter/qp_internal.c deleted file mode 100644 index 87a30c3f9b72..000000000000 --- a/quantum/painter/qp_internal.c +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2023 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Core API: device registration - -enum { - // Work out how many devices we're actually going to be instantiating - // NOTE: We intentionally do not include surfaces here, despite them conforming to the same API. - QP_NUM_DEVICES = (ILI9163_NUM_DEVICES) // ILI9163 - + (ILI9341_NUM_DEVICES) // ILI9341 - + (ILI9488_NUM_DEVICES) // ILI9488 - + (ST7789_NUM_DEVICES) // ST7789 - + (ST7735_NUM_DEVICES) // ST7735 - + (GC9A01_NUM_DEVICES) // GC9A01 - + (SSD1351_NUM_DEVICES) // SSD1351 -}; - -static painter_device_t qp_devices[QP_NUM_DEVICES] = {NULL}; - -bool qp_internal_register_device(painter_device_t driver) { - for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) { - if (qp_devices[i] == NULL) { - qp_devices[i] = driver; - return true; - } - } - - // We should never get here -- someone has screwed up their device counts during config - qp_dprintf("qp_internal_register_device: no more space for devices!\n"); - return false; -} - -#if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0 -static void qp_internal_display_timeout_task(void) { - // Handle power on/off state - static bool display_on = true; - bool should_change_display_state = false; - bool target_display_state = false; - if (last_input_activity_elapsed() < (QUANTUM_PAINTER_DISPLAY_TIMEOUT)) { - should_change_display_state = display_on == false; - target_display_state = true; - } else { - should_change_display_state = display_on == true; - target_display_state = false; - } - - if (should_change_display_state) { - for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) { - if (qp_devices[i] != NULL) { - qp_power(qp_devices[i], target_display_state); - } - } - - display_on = target_display_state; - } -} -#endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0 - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter Core API: qp_internal_task - -_Static_assert((QUANTUM_PAINTER_TASK_THROTTLE) > 0 && (QUANTUM_PAINTER_TASK_THROTTLE) < 1000, "QUANTUM_PAINTER_TASK_THROTTLE must be between 1 and 999"); - -void qp_internal_task(void) { - // Perform throttling of the internal processing of Quantum Painter - static uint32_t last_tick = 0; - uint32_t now = timer_read32(); - if (TIMER_DIFF_32(now, last_tick) < (QUANTUM_PAINTER_TASK_THROTTLE)) { - return; - } - last_tick = now; - -#if (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0 - qp_internal_display_timeout_task(); -#endif // (QUANTUM_PAINTER_DISPLAY_TIMEOUT) > 0 - - // Handle animations - void qp_internal_animation_tick(void); - qp_internal_animation_tick(); - -#ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE - // Run LVGL ticks - void qp_lvgl_internal_tick(void); - qp_lvgl_internal_tick(); -#endif - - // Flush (render) dirty regions to corresponding displays -#if !defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT) - bool old_debug_state = debug_enable; - debug_enable = false; -#endif // defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT) - for (uint8_t i = 0; i < QP_NUM_DEVICES; i++) { - if (qp_devices[i] != NULL) { - qp_flush(qp_devices[i]); - } - } -#if !defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT) - debug_enable = old_debug_state; -#endif // defined(QUANTUM_PAINTER_DEBUG_ENABLE_FLUSH_TASK_OUTPUT) -} diff --git a/quantum/painter/qp_internal.h b/quantum/painter/qp_internal.h deleted file mode 100644 index e7a6d113c5a1..000000000000 --- a/quantum/painter/qp_internal.h +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "quantum.h" -#include "qp.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Helpers - -// Mark certain types that there should be no padding bytes between members. -#define QP_PACKED __attribute__((packed)) - -// Min/max defines -#define QP_MIN(X, Y) (((X) < (Y)) ? (X) : (Y)) -#define QP_MAX(X, Y) (((X) > (Y)) ? (X) : (Y)) - -#ifdef QUANTUM_PAINTER_DEBUG -# include -# include -# define qp_dprintf(...) dprintf(__VA_ARGS__) -#else -# define qp_dprintf(...) \ - do { \ - } while (0) -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Specific internal definitions - -#include -#include diff --git a/quantum/painter/qp_internal_driver.h b/quantum/painter/qp_internal_driver.h deleted file mode 100644 index 69da966f8c84..000000000000 --- a/quantum/painter/qp_internal_driver.h +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2021-2023 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Driver callbacks - -typedef bool (*painter_driver_init_func)(painter_device_t device, painter_rotation_t rotation); -typedef bool (*painter_driver_power_func)(painter_device_t device, bool power_on); -typedef bool (*painter_driver_clear_func)(painter_device_t device); -typedef bool (*painter_driver_flush_func)(painter_device_t device); -typedef bool (*painter_driver_viewport_func)(painter_device_t device, uint16_t left, uint16_t top, uint16_t right, uint16_t bottom); -typedef bool (*painter_driver_pixdata_func)(painter_device_t device, const void *pixel_data, uint32_t native_pixel_count); -typedef bool (*painter_driver_convert_palette_func)(painter_device_t device, int16_t palette_size, qp_pixel_t *palette); -typedef bool (*painter_driver_append_pixels)(painter_device_t device, uint8_t *target_buffer, qp_pixel_t *palette, uint32_t pixel_offset, uint32_t pixel_count, uint8_t *palette_indices); -typedef bool (*painter_driver_append_pixdata)(painter_device_t device, uint8_t *target_buffer, uint32_t pixdata_offset, uint8_t pixdata_byte); - -// Driver vtable definition -typedef struct painter_driver_vtable_t { - painter_driver_init_func init; - painter_driver_power_func power; - painter_driver_clear_func clear; - painter_driver_flush_func flush; - painter_driver_viewport_func viewport; - painter_driver_pixdata_func pixdata; - painter_driver_convert_palette_func palette_convert; - painter_driver_append_pixels append_pixels; - painter_driver_append_pixdata append_pixdata; -} painter_driver_vtable_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Comms callbacks - -typedef bool (*painter_driver_comms_init_func)(painter_device_t device); -typedef bool (*painter_driver_comms_start_func)(painter_device_t device); -typedef void (*painter_driver_comms_stop_func)(painter_device_t device); -typedef uint32_t (*painter_driver_comms_send_func)(painter_device_t device, const void *data, uint32_t byte_count); - -typedef struct painter_comms_vtable_t { - painter_driver_comms_init_func comms_init; - painter_driver_comms_start_func comms_start; - painter_driver_comms_stop_func comms_stop; - painter_driver_comms_send_func comms_send; -} painter_comms_vtable_t; - -typedef void (*painter_driver_comms_send_command_func)(painter_device_t device, uint8_t cmd); -typedef void (*painter_driver_comms_bulk_command_sequence)(painter_device_t device, const uint8_t *sequence, size_t sequence_len); - -typedef struct painter_comms_with_command_vtable_t { - painter_comms_vtable_t base; // must be first, so this object can be cast from the painter_comms_vtable_t* type - painter_driver_comms_send_command_func send_command; - painter_driver_comms_bulk_command_sequence bulk_command_sequence; -} painter_comms_with_command_vtable_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Driver base definition - -typedef struct painter_driver_t { - const painter_driver_vtable_t *driver_vtable; - const painter_comms_vtable_t * comms_vtable; - - // Flag signifying if validation was successful - bool validate_ok; - - // Panel geometry - uint16_t panel_width; - uint16_t panel_height; - - // Target drawing rotation - painter_rotation_t rotation; - - // Automated offsets for setting viewport - uint16_t offset_x; - uint16_t offset_y; - - // Number of bits per pixel, used for determining how many pixels can be sent during a transmission of the pixdata buffer - uint8_t native_bits_per_pixel; - - // Comms config pointer -- needs to point to an appropriate comms config if the comms driver requires it. - void *comms_config; -} painter_driver_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Device internals - -bool qp_internal_register_device(painter_device_t driver); diff --git a/quantum/painter/qp_internal_formats.h b/quantum/painter/qp_internal_formats.h deleted file mode 100644 index 194f82b31a88..000000000000 --- a/quantum/painter/qp_internal_formats.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter pixel formats - -// Datatype containing a pixel's color. The internal member used is dependent on the external context. -typedef union QP_PACKED qp_pixel_t { - uint8_t mono; - uint8_t palette_idx; - - struct QP_PACKED { - uint8_t h; - uint8_t s; - uint8_t v; - } hsv888; - - struct QP_PACKED { - uint8_t r; - uint8_t g; - uint8_t b; - } rgb888; - - uint16_t rgb565; - - uint32_t dummy; -} qp_pixel_t; -_Static_assert(sizeof(qp_pixel_t) == 4, "Invalid size for qp_pixel_t"); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Quantum Painter image format - -typedef enum qp_image_format_t { - // Pixel formats available in the QGF frame format - GRAYSCALE_1BPP = 0x00, - GRAYSCALE_2BPP = 0x01, - GRAYSCALE_4BPP = 0x02, - GRAYSCALE_8BPP = 0x03, - PALETTE_1BPP = 0x04, - PALETTE_2BPP = 0x05, - PALETTE_4BPP = 0x06, - PALETTE_8BPP = 0x07, - RGB565_16BPP = 0x08, - RGB888_24BPP = 0x09, -} qp_image_format_t; - -typedef enum painter_compression_t { IMAGE_UNCOMPRESSED, IMAGE_COMPRESSED_RLE } painter_compression_t; diff --git a/quantum/painter/qp_stream.c b/quantum/painter/qp_stream.c deleted file mode 100644 index 1198cf793db8..000000000000 --- a/quantum/painter/qp_stream.c +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2021 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "qp_stream.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Stream API - -uint32_t qp_stream_read_impl(void *output_buf, uint32_t member_size, uint32_t num_members, qp_stream_t *stream) { - uint8_t *output_ptr = (uint8_t *)output_buf; - - uint32_t i; - for (i = 0; i < (num_members * member_size); ++i) { - int16_t c = qp_stream_get(stream); - if (c < 0) { - break; - } - - output_ptr[i] = (uint8_t)(c & 0xFF); - } - - return i / member_size; -} - -uint32_t qp_stream_write_impl(const void *input_buf, uint32_t member_size, uint32_t num_members, qp_stream_t *stream) { - uint8_t *input_ptr = (uint8_t *)input_buf; - - uint32_t i; - for (i = 0; i < (num_members * member_size); ++i) { - if (!qp_stream_put(stream, input_ptr[i])) { - break; - } - } - - return i / member_size; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Memory streams - -static inline int16_t mem_get(qp_stream_t *stream) { - qp_memory_stream_t *s = (qp_memory_stream_t *)stream; - if (s->position >= s->length) { - s->is_eof = true; - return STREAM_EOF; - } - return s->buffer[s->position++]; -} - -static inline bool mem_put(qp_stream_t *stream, uint8_t c) { - qp_memory_stream_t *s = (qp_memory_stream_t *)stream; - if (s->position >= s->length) { - s->is_eof = true; - return false; - } - s->buffer[s->position++] = c; - return true; -} - -static inline int mem_seek(qp_stream_t *stream, int32_t offset, int origin) { - qp_memory_stream_t *s = (qp_memory_stream_t *)stream; - - // Handle as per fseek - int32_t position = s->position; - switch (origin) { - case SEEK_SET: - position = offset; - break; - case SEEK_CUR: - position += offset; - break; - case SEEK_END: - position = s->length + offset; - break; - default: - return -1; - } - - // If we're before the start, ignore it. - if (position < 0) { - return -1; - } - - // If we're at the end it's okay, we only care if we're after the end for failure purposes -- as per lseek() - if (position > s->length) { - return -1; - } - - // Update the offset - s->position = position; - - // Successful invocation of fseek() results in clearing of the EOF flag by default, mirror the same functionality - s->is_eof = false; - - return 0; -} - -static inline int32_t mem_tell(qp_stream_t *stream) { - qp_memory_stream_t *s = (qp_memory_stream_t *)stream; - return s->position; -} - -static inline bool mem_is_eof(qp_stream_t *stream) { - qp_memory_stream_t *s = (qp_memory_stream_t *)stream; - return s->is_eof; -} - -static inline void mem_close(qp_stream_t *stream) { - // No-op. -} - -qp_memory_stream_t qp_make_memory_stream(void *buffer, int32_t length) { - qp_memory_stream_t stream = { - .base = {.get = mem_get, .put = mem_put, .seek = mem_seek, .tell = mem_tell, .is_eof = mem_is_eof, .close = mem_close}, - .buffer = (uint8_t *)buffer, - .length = length, - .position = 0, - }; - return stream; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FILE streams - -#ifdef QP_STREAM_HAS_FILE_IO - -static inline int16_t file_get(qp_stream_t *stream) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - int c = fgetc(s->file); - if (c < 0 || feof(s->file)) return STREAM_EOF; - return (uint16_t)c; -} - -static inline bool file_put(qp_stream_t *stream, uint8_t c) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - return fputc(c, s->file) == c; -} - -static inline int file_seek(qp_stream_t *stream, int32_t offset, int origin) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - return fseek(s->file, offset, origin); -} - -static inline int32_t file_tell(qp_stream_t *stream) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - return (int32_t)ftell(s->file); -} - -static inline bool file_is_eof(qp_stream_t *stream) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - return (bool)feof(s->file); -} - -static inline void file_close(qp_stream_t *stream) { - qp_file_stream_t *s = (qp_file_stream_t *)stream; - fclose(s->file); -} - -qp_file_stream_t qp_make_file_stream(FILE *f) { - qp_file_stream_t stream = { - .base = {.get = file_get, .put = file_put, .seek = file_seek, .tell = file_tell, .is_eof = file_is_eof, .close = file_close}, - .file = f, - }; - return stream; -} -#endif // QP_STREAM_HAS_FILE_IO diff --git a/quantum/painter/qp_stream.h b/quantum/painter/qp_stream.h deleted file mode 100644 index 4f2b612e43f6..000000000000 --- a/quantum/painter/qp_stream.h +++ /dev/null @@ -1,85 +0,0 @@ -/* Copyright 2021 Nick Brassel (@tzarc) - * - * 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 . - */ - -#pragma once - -#include -#include -#include -#include - -#include "qp_internal.h" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Stream API - -typedef struct qp_stream_t qp_stream_t; - -#define qp_stream_get(stream_ptr) (((qp_stream_t *)(stream_ptr))->get((qp_stream_t *)(stream_ptr))) -#define qp_stream_put(stream_ptr, c) (((qp_stream_t *)(stream_ptr))->put((qp_stream_t *)(stream_ptr), (c))) -#define qp_stream_seek(stream_ptr, offset, origin) (((qp_stream_t *)(stream_ptr))->seek((qp_stream_t *)(stream_ptr), (offset), (origin))) -#define qp_stream_tell(stream_ptr) (((qp_stream_t *)(stream_ptr))->tell((qp_stream_t *)(stream_ptr))) -#define qp_stream_eof(stream_ptr) (((qp_stream_t *)(stream_ptr))->is_eof((qp_stream_t *)(stream_ptr))) -#define qp_stream_setpos(stream_ptr, offset) qp_stream_seek((stream_ptr), (offset), SEEK_SET) -#define qp_stream_getpos(stream_ptr) qp_stream_tell((stream_ptr)) -#define qp_stream_read(output_buf, member_size, num_members, stream_ptr) qp_stream_read_impl((output_buf), (member_size), (num_members), (qp_stream_t *)(stream_ptr)) -#define qp_stream_write(input_buf, member_size, num_members, stream_ptr) qp_stream_write_impl((input_buf), (member_size), (num_members), (qp_stream_t *)(stream_ptr)) - -uint32_t qp_stream_read_impl(void *output_buf, uint32_t member_size, uint32_t num_members, qp_stream_t *stream); -uint32_t qp_stream_write_impl(const void *input_buf, uint32_t member_size, uint32_t num_members, qp_stream_t *stream); - -#define qp_stream_close(stream_ptr) (((qp_stream_t *)(stream_ptr))->close((qp_stream_t *)(stream_ptr))) - -#define STREAM_EOF ((int16_t)(-1)) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Stream definition - -typedef struct qp_stream_t { - int16_t (*get)(qp_stream_t *stream); - bool (*put)(qp_stream_t *stream, uint8_t c); - int (*seek)(qp_stream_t *stream, int32_t offset, int origin); - int32_t (*tell)(qp_stream_t *stream); - bool (*is_eof)(qp_stream_t *stream); - void (*close)(qp_stream_t *stream); -} qp_stream_t; - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Memory streams - -typedef struct qp_memory_stream_t { - qp_stream_t base; - uint8_t * buffer; - int32_t length; - int32_t position; - bool is_eof; -} qp_memory_stream_t; - -qp_memory_stream_t qp_make_memory_stream(void *buffer, int32_t length); - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// FILE streams - -#ifdef QP_STREAM_HAS_FILE_IO - -typedef struct qp_file_stream_t { - qp_stream_t base; - FILE * file; -} qp_file_stream_t; - -qp_file_stream_t qp_make_file_stream(FILE *f); - -#endif // QP_STREAM_HAS_FILE_IO diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk deleted file mode 100644 index 7752936cbdc3..000000000000 --- a/quantum/painter/rules.mk +++ /dev/null @@ -1,161 +0,0 @@ -# Quantum Painter Configurables -QUANTUM_PAINTER_DRIVERS ?= -QUANTUM_PAINTER_ANIMATIONS_ENABLE ?= yes - -QUANTUM_PAINTER_LVGL_INTEGRATION ?= no - -# The list of permissible drivers that can be listed in QUANTUM_PAINTER_DRIVERS -VALID_QUANTUM_PAINTER_DRIVERS := \ - rgb565_surface \ - ili9163_spi \ - ili9341_spi \ - ili9488_spi \ - st7735_spi \ - st7789_spi \ - gc9a01_spi \ - ssd1351_spi - -#------------------------------------------------------------------------------- - -OPT_DEFS += -DQUANTUM_PAINTER_ENABLE -COMMON_VPATH += $(QUANTUM_DIR)/painter \ - $(QUANTUM_DIR)/unicode -SRC += \ - $(QUANTUM_DIR)/unicode/utf8.c \ - $(QUANTUM_DIR)/color.c \ - $(QUANTUM_DIR)/painter/qp.c \ - $(QUANTUM_DIR)/painter/qp_internal.c \ - $(QUANTUM_DIR)/painter/qp_stream.c \ - $(QUANTUM_DIR)/painter/qgf.c \ - $(QUANTUM_DIR)/painter/qff.c \ - $(QUANTUM_DIR)/painter/qp_draw_core.c \ - $(QUANTUM_DIR)/painter/qp_draw_codec.c \ - $(QUANTUM_DIR)/painter/qp_draw_circle.c \ - $(QUANTUM_DIR)/painter/qp_draw_ellipse.c \ - $(QUANTUM_DIR)/painter/qp_draw_image.c \ - $(QUANTUM_DIR)/painter/qp_draw_text.c - -# Check if people want animations... enable the defered exec if so. -ifeq ($(strip $(QUANTUM_PAINTER_ANIMATIONS_ENABLE)), yes) - DEFERRED_EXEC_ENABLE := yes - OPT_DEFS += -DQUANTUM_PAINTER_ANIMATIONS_ENABLE -endif - -# Comms flags -QUANTUM_PAINTER_NEEDS_COMMS_SPI ?= no - -# Handler for each driver -define handle_quantum_painter_driver - CURRENT_PAINTER_DRIVER := $1 - - ifeq ($$(filter $$(strip $$(CURRENT_PAINTER_DRIVER)),$$(VALID_QUANTUM_PAINTER_DRIVERS)),) - $$(error "$$(CURRENT_PAINTER_DRIVER)" is not a valid Quantum Painter driver) - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),rgb565_surface) - OPT_DEFS += -DQUANTUM_PAINTER_RGB565_SURFACE_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/generic - SRC += \ - $(DRIVER_PATH)/painter/generic/qp_rgb565_surface.c \ - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ili9163_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_ILI9163_ENABLE -DQUANTUM_PAINTER_ILI9163_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/ili9xxx - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/ili9xxx/qp_ili9163.c \ - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ili9341_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_ILI9341_ENABLE -DQUANTUM_PAINTER_ILI9341_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/ili9xxx - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/ili9xxx/qp_ili9341.c \ - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ili9488_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_ILI9488_ENABLE -DQUANTUM_PAINTER_ILI9488_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/ili9xxx - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/ili9xxx/qp_ili9488.c \ - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),st7735_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_ST7735_ENABLE -DQUANTUM_PAINTER_ST7735_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/st77xx - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/st77xx/qp_st7735.c - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),st7789_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_ST7789_ENABLE -DQUANTUM_PAINTER_ST7789_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/st77xx - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/st77xx/qp_st7789.c - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),gc9a01_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_GC9A01_ENABLE -DQUANTUM_PAINTER_GC9A01_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/gc9a01 - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/gc9a01/qp_gc9a01.c - - else ifeq ($$(strip $$(CURRENT_PAINTER_DRIVER)),ssd1351_spi) - QUANTUM_PAINTER_NEEDS_COMMS_SPI := yes - QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET := yes - OPT_DEFS += -DQUANTUM_PAINTER_SSD1351_ENABLE -DQUANTUM_PAINTER_SSD1351_SPI_ENABLE - COMMON_VPATH += \ - $(DRIVER_PATH)/painter/tft_panel \ - $(DRIVER_PATH)/painter/ssd1351 - SRC += \ - $(DRIVER_PATH)/painter/tft_panel/qp_tft_panel.c \ - $(DRIVER_PATH)/painter/ssd1351/qp_ssd1351.c - - endif -endef - -# Iterate through the listed drivers for the build, including what's necessary -$(foreach qp_driver,$(QUANTUM_PAINTER_DRIVERS),$(eval $(call handle_quantum_painter_driver,$(qp_driver)))) - -# If SPI comms is needed, set up the required files -ifeq ($(strip $(QUANTUM_PAINTER_NEEDS_COMMS_SPI)), yes) - OPT_DEFS += -DQUANTUM_PAINTER_SPI_ENABLE - QUANTUM_LIB_SRC += spi_master.c - VPATH += $(DRIVER_PATH)/painter/comms - SRC += \ - $(QUANTUM_DIR)/painter/qp_comms.c \ - $(DRIVER_PATH)/painter/comms/qp_comms_spi.c - - ifeq ($(strip $(QUANTUM_PAINTER_NEEDS_COMMS_SPI_DC_RESET)), yes) - OPT_DEFS += -DQUANTUM_PAINTER_SPI_DC_RESET_ENABLE - endif -endif - -# Check if LVGL needs to be enabled -ifeq ($(strip $(QUANTUM_PAINTER_LVGL_INTEGRATION)), yes) - include $(QUANTUM_DIR)/painter/lvgl/rules.mk -endif diff --git a/quantum/pointing_device/pointing_device.c b/quantum/pointing_device/pointing_device.c deleted file mode 100644 index abb3817b5f65..000000000000 --- a/quantum/pointing_device/pointing_device.c +++ /dev/null @@ -1,497 +0,0 @@ -/* Copyright 2017 Joshua Broekhuijsen - * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) - * Copyright 2021 Dasky (@daskygit) - * - * 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 . - */ - -#include "pointing_device.h" -#include -#include "timer.h" -#ifdef MOUSEKEY_ENABLE -# include "mousekey.h" -#endif - -#if (defined(POINTING_DEVICE_ROTATION_90) + defined(POINTING_DEVICE_ROTATION_180) + defined(POINTING_DEVICE_ROTATION_270)) > 1 -# error More than one rotation selected. This is not supported. -#endif - -#if defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT) || defined(POINTING_DEVICE_COMBINED) -# ifndef SPLIT_POINTING_ENABLE -# error "Using POINTING_DEVICE_LEFT or POINTING_DEVICE_RIGHT or POINTING_DEVICE_COMBINED, then SPLIT_POINTING_ENABLE is required but has not been defined" -# endif -#endif - -#if defined(SPLIT_POINTING_ENABLE) -# include "transactions.h" -# include "keyboard.h" - -report_mouse_t shared_mouse_report = {}; -uint16_t shared_cpi = 0; - -/** - * @brief Sets the shared mouse report used be pointing device task - * - * NOTE : Only available when using SPLIT_POINTING_ENABLE - * - * @param[in] new_mouse_report report_mouse_t - */ -void pointing_device_set_shared_report(report_mouse_t new_mouse_report) { - shared_mouse_report = new_mouse_report; -} - -/** - * @brief Gets current pointing device CPI if supported - * - * Gets current cpi of the shared report and returns it as uint16_t - * - * NOTE : Only available when using SPLIT_POINTING_ENABLE - * - * @return cpi value as uint16_t - */ -uint16_t pointing_device_get_shared_cpi(void) { - return shared_cpi; -} - -# if defined(POINTING_DEVICE_LEFT) -# define POINTING_DEVICE_THIS_SIDE is_keyboard_left() -# elif defined(POINTING_DEVICE_RIGHT) -# define POINTING_DEVICE_THIS_SIDE !is_keyboard_left() -# elif defined(POINTING_DEVICE_COMBINED) -# define POINTING_DEVICE_THIS_SIDE true -# endif - -#endif // defined(SPLIT_POINTING_ENABLE) - -static report_mouse_t local_mouse_report = {}; -static bool pointing_device_force_send = false; - -extern const pointing_device_driver_t pointing_device_driver; - -/** - * @brief Keyboard level code pointing device initialisation - * - */ -__attribute__((weak)) void pointing_device_init_kb(void) {} - -/** - * @brief User level code pointing device initialisation - * - */ -__attribute__((weak)) void pointing_device_init_user(void) {} - -/** - * @brief Weak function allowing for keyboard level mouse report modification - * - * Takes report_mouse_t struct allowing modification at keyboard level then returns report_mouse_t. - * - * @param[in] mouse_report report_mouse_t - * @return report_mouse_t - */ -__attribute__((weak)) report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report) { - return pointing_device_task_user(mouse_report); -} - -/** - * @brief Weak function allowing for user level mouse report modification - * - * Takes report_mouse_t struct allowing modification at user level then returns report_mouse_t. - * - * @param[in] mouse_report report_mouse_t - * @return report_mouse_t - */ -__attribute__((weak)) report_mouse_t pointing_device_task_user(report_mouse_t mouse_report) { - return mouse_report; -} - -/** - * @brief Handles pointing device buttons - * - * Returns modified button bitmask using bool pressed and selected pointing_device_buttons_t button in uint8_t buttons bitmask. - * - * @param buttons[in] uint8_t bitmask - * @param pressed[in] bool - * @param button[in] pointing_device_buttons_t value - * @return Modified uint8_t bitmask buttons - */ -__attribute__((weak)) uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button) { - if (pressed) { - buttons |= 1 << (button); - } else { - buttons &= ~(1 << (button)); - } - return buttons; -} - -/** - * @brief Initialises pointing device - * - * Initialises pointing device, perform driver init and optional keyboard/user level code. - */ -__attribute__((weak)) void pointing_device_init(void) { -#if defined(SPLIT_POINTING_ENABLE) - if ((POINTING_DEVICE_THIS_SIDE)) -#endif - { - pointing_device_driver.init(); -#ifdef POINTING_DEVICE_MOTION_PIN -# ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW - setPinInputHigh(POINTING_DEVICE_MOTION_PIN); -# else - setPinInput(POINTING_DEVICE_MOTION_PIN); -# endif -#endif - } - - pointing_device_init_kb(); - pointing_device_init_user(); -} - -/** - * @brief Sends processed mouse report to host - * - * This sends the mouse report generated by pointing_device_task if changed since the last report. Once send zeros mouse report except buttons. - * - */ -__attribute__((weak)) bool pointing_device_send(void) { - static report_mouse_t old_report = {}; - bool should_send_report = has_mouse_report_changed(&local_mouse_report, &old_report); - - if (should_send_report) { - host_mouse_send(&local_mouse_report); - } - // send it and 0 it out except for buttons, so those stay until they are explicity over-ridden using update_pointing_device - uint8_t buttons = local_mouse_report.buttons; - memset(&local_mouse_report, 0, sizeof(local_mouse_report)); - local_mouse_report.buttons = buttons; - memcpy(&old_report, &local_mouse_report, sizeof(local_mouse_report)); - - return should_send_report || buttons; -} - -/** - * @brief Adjust mouse report by any optional common pointing configuration defines - * - * This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines. - * - * @param mouse_report[in] takes a report_mouse_t to be adjusted - * @return report_mouse_t with adjusted values - */ -report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report) { - // Support rotation of the sensor data -#if defined(POINTING_DEVICE_ROTATION_90) || defined(POINTING_DEVICE_ROTATION_180) || defined(POINTING_DEVICE_ROTATION_270) - mouse_xy_report_t x = mouse_report.x; - mouse_xy_report_t y = mouse_report.y; -# if defined(POINTING_DEVICE_ROTATION_90) - mouse_report.x = y; - mouse_report.y = -x; -# elif defined(POINTING_DEVICE_ROTATION_180) - mouse_report.x = -x; - mouse_report.y = -y; -# elif defined(POINTING_DEVICE_ROTATION_270) - mouse_report.x = -y; - mouse_report.y = x; -# else -# error "How the heck did you get here?!" -# endif -#endif - // Support Inverting the X and Y Axises -#if defined(POINTING_DEVICE_INVERT_X) - mouse_report.x = -mouse_report.x; -#endif -#if defined(POINTING_DEVICE_INVERT_Y) - mouse_report.y = -mouse_report.y; -#endif - return mouse_report; -} - -/** - * @brief Retrieves and processes pointing device data. - * - * This function is part of the keyboard loop and retrieves the mouse report from the pointing device driver. - * It applies any optional configuration e.g. rotation or axis inversion and then initiates a send. - * - */ -__attribute__((weak)) bool pointing_device_task(void) { -#if defined(SPLIT_POINTING_ENABLE) - // Don't poll the target side pointing device. - if (!is_keyboard_master()) { - return false; - }; -#endif - -#if (POINTING_DEVICE_TASK_THROTTLE_MS > 0) - static uint32_t last_exec = 0; - if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) { - return false; - } - last_exec = timer_read32(); -#endif - - // Gather report info -#ifdef POINTING_DEVICE_MOTION_PIN -# if defined(SPLIT_POINTING_ENABLE) -# error POINTING_DEVICE_MOTION_PIN not supported when sharing the pointing device report between sides. -# endif -# ifdef POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW - if (!readPin(POINTING_DEVICE_MOTION_PIN)) -# else - if (readPin(POINTING_DEVICE_MOTION_PIN)) -# endif -#endif - -#if defined(SPLIT_POINTING_ENABLE) -# if defined(POINTING_DEVICE_COMBINED) - static uint8_t old_buttons = 0; - local_mouse_report.buttons = old_buttons; - local_mouse_report = pointing_device_driver.get_report(local_mouse_report); - old_buttons = local_mouse_report.buttons; -# elif defined(POINTING_DEVICE_LEFT) || defined(POINTING_DEVICE_RIGHT) - local_mouse_report = POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_report(local_mouse_report) : shared_mouse_report; -# else -# error "You need to define the side(s) the pointing device is on. POINTING_DEVICE_COMBINED / POINTING_DEVICE_LEFT / POINTING_DEVICE_RIGHT" -# endif -#else - local_mouse_report = pointing_device_driver.get_report(local_mouse_report); -#endif // defined(SPLIT_POINTING_ENABLE) - - // allow kb to intercept and modify report -#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) - if (is_keyboard_left()) { - local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report); - shared_mouse_report = pointing_device_adjust_by_defines_right(shared_mouse_report); - } else { - local_mouse_report = pointing_device_adjust_by_defines_right(local_mouse_report); - shared_mouse_report = pointing_device_adjust_by_defines(shared_mouse_report); - } - local_mouse_report = is_keyboard_left() ? pointing_device_task_combined_kb(local_mouse_report, shared_mouse_report) : pointing_device_task_combined_kb(shared_mouse_report, local_mouse_report); -#else - local_mouse_report = pointing_device_adjust_by_defines(local_mouse_report); - local_mouse_report = pointing_device_task_kb(local_mouse_report); -#endif - // automatic mouse layer function -#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE - pointing_device_task_auto_mouse(local_mouse_report); -#endif - // combine with mouse report to ensure that the combined is sent correctly -#ifdef MOUSEKEY_ENABLE - report_mouse_t mousekey_report = mousekey_get_report(); - local_mouse_report.buttons = local_mouse_report.buttons | mousekey_report.buttons; -#endif - - const bool send_report = pointing_device_send() || pointing_device_force_send; - pointing_device_force_send = false; - - return send_report; -} - -/** - * @brief Gets current mouse report used by pointing device task - * - * @return report_mouse_t - */ -report_mouse_t pointing_device_get_report(void) { - return local_mouse_report; -} - -/** - * @brief Sets mouse report used be pointing device task - * - * @param[in] mouse_report - */ -void pointing_device_set_report(report_mouse_t mouse_report) { - pointing_device_force_send = has_mouse_report_changed(&local_mouse_report, &mouse_report); - memcpy(&local_mouse_report, &mouse_report, sizeof(local_mouse_report)); -} - -/** - * @brief Gets current pointing device CPI if supported - * - * Gets current cpi from pointing device driver if supported and returns it as uint16_t - * - * @return cpi value as uint16_t - */ -uint16_t pointing_device_get_cpi(void) { -#if defined(SPLIT_POINTING_ENABLE) - return POINTING_DEVICE_THIS_SIDE ? pointing_device_driver.get_cpi() : shared_cpi; -#else - return pointing_device_driver.get_cpi(); -#endif -} - -/** - * @brief Set pointing device CPI if supported - * - * Takes a uint16_t value to set pointing device cpi if supported by driver. - * - * @param[in] cpi uint16_t value. - */ -void pointing_device_set_cpi(uint16_t cpi) { -#if defined(SPLIT_POINTING_ENABLE) - if (POINTING_DEVICE_THIS_SIDE) { - pointing_device_driver.set_cpi(cpi); - } else { - shared_cpi = cpi; - } -#else - pointing_device_driver.set_cpi(cpi); -#endif -} - -#if defined(SPLIT_POINTING_ENABLE) && defined(POINTING_DEVICE_COMBINED) -/** - * @brief Set pointing device CPI if supported - * - * Takes a bool and uint16_t and allows setting cpi for a single side when using 2 pointing devices with a split keyboard. - * - * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED - * - * @param[in] left true = left, false = right. - * @param[in] cpi uint16_t value. - */ -void pointing_device_set_cpi_on_side(bool left, uint16_t cpi) { - bool local = (is_keyboard_left() & left) ? true : false; - if (local) { - pointing_device_driver.set_cpi(cpi); - } else { - shared_cpi = cpi; - } -} - -/** - * @brief clamps int16_t to int8_t - * - * @param[in] int16_t value - * @return int8_t clamped value - */ -static inline int8_t pointing_device_hv_clamp(int16_t value) { - if (value < INT8_MIN) { - return INT8_MIN; - } else if (value > INT8_MAX) { - return INT8_MAX; - } else { - return value; - } -} - -/** - * @brief clamps int16_t to int8_t - * - * @param[in] clamp_range_t value - * @return mouse_xy_report_t clamped value - */ -static inline mouse_xy_report_t pointing_device_xy_clamp(clamp_range_t value) { - if (value < XY_REPORT_MIN) { - return XY_REPORT_MIN; - } else if (value > XY_REPORT_MAX) { - return XY_REPORT_MAX; - } else { - return value; - } -} -/** - * @brief combines 2 mouse reports and returns 2 - * - * Combines 2 report_mouse_t structs, clamping movement values to int8_t and ignores report_id then returns the resulting report_mouse_t struct. - * - * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED - * - * @param[in] left_report left report_mouse_t - * @param[in] right_report right report_mouse_t - * @return combined report_mouse_t of left_report and right_report - */ -report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report) { - left_report.x = pointing_device_xy_clamp((clamp_range_t)left_report.x + right_report.x); - left_report.y = pointing_device_xy_clamp((clamp_range_t)left_report.y + right_report.y); - left_report.h = pointing_device_hv_clamp((int16_t)left_report.h + right_report.h); - left_report.v = pointing_device_hv_clamp((int16_t)left_report.v + right_report.v); - left_report.buttons |= right_report.buttons; - return left_report; -} - -/** - * @brief Adjust mouse report by any optional right pointing configuration defines - * - * This applies rotation or inversion to the mouse report as selected by the pointing device common configuration defines. - * - * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED - * - * @param[in] mouse_report report_mouse_t to be adjusted - * @return report_mouse_t with adjusted values - */ -report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report) { - // Support rotation of the sensor data -# if defined(POINTING_DEVICE_ROTATION_90_RIGHT) || defined(POINTING_DEVICE_ROTATION_180_RIGHT) || defined(POINTING_DEVICE_ROTATION_270_RIGHT) - mouse_xy_report_t x = mouse_report.x; - mouse_xy_report_t y = mouse_report.y; -# if defined(POINTING_DEVICE_ROTATION_90_RIGHT) - mouse_report.x = y; - mouse_report.y = -x; -# elif defined(POINTING_DEVICE_ROTATION_180_RIGHT) - mouse_report.x = -x; - mouse_report.y = -y; -# elif defined(POINTING_DEVICE_ROTATION_270_RIGHT) - mouse_report.x = -y; - mouse_report.y = x; -# else -# error "How the heck did you get here?!" -# endif -# endif - // Support Inverting the X and Y Axises -# if defined(POINTING_DEVICE_INVERT_X_RIGHT) - mouse_report.x = -mouse_report.x; -# endif -# if defined(POINTING_DEVICE_INVERT_Y_RIGHT) - mouse_report.y = -mouse_report.y; -# endif - return mouse_report; -} - -/** - * @brief Weak function allowing for keyboard level mouse report modification - * - * Takes 2 report_mouse_t structs allowing individual modification of sides at keyboard level then returns pointing_device_task_combined_user. - * - * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED - * - * @param[in] left_report report_mouse_t - * @param[in] right_report report_mouse_t - * @return pointing_device_task_combined_user(left_report, right_report) by default - */ -__attribute__((weak)) report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report) { - return pointing_device_task_combined_user(left_report, right_report); -} - -/** - * @brief Weak function allowing for user level mouse report modification - * - * Takes 2 report_mouse_t structs allowing individual modification of sides at user level then returns pointing_device_combine_reports. - * - * NOTE: Only available when using SPLIT_POINTING_ENABLE and POINTING_DEVICE_COMBINED - * - * @param[in] left_report report_mouse_t - * @param[in] right_report report_mouse_t - * @return pointing_device_combine_reports(left_report, right_report) by default - */ -__attribute__((weak)) report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report) { - return pointing_device_combine_reports(left_report, right_report); -} -#endif - -__attribute__((weak)) void pointing_device_keycode_handler(uint16_t keycode, bool pressed) { - if IS_MOUSEKEY_BUTTON (keycode) { - local_mouse_report.buttons = pointing_device_handle_buttons(local_mouse_report.buttons, pressed, keycode - KC_MS_BTN1); - pointing_device_send(); - } -} diff --git a/quantum/pointing_device/pointing_device.h b/quantum/pointing_device/pointing_device.h deleted file mode 100644 index afd653eaeeee..000000000000 --- a/quantum/pointing_device/pointing_device.h +++ /dev/null @@ -1,131 +0,0 @@ -/* -Copyright 2017 Joshua Broekhuijsen - -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 . -*/ - -#pragma once - -#include -#include "host.h" -#include "report.h" - -#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE -# include "pointing_device_auto_mouse.h" -#endif - -#if defined(POINTING_DEVICE_DRIVER_adns5050) -# include "drivers/sensors/adns5050.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_pmw3320) -# include "drivers/sensors/pmw3320.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_adns9800) -# include "spi_master.h" -# include "drivers/sensors/adns9800.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_analog_joystick) -# include "analog.h" -# include "drivers/sensors/analog_joystick.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi) -# include "drivers/sensors/cirque_pinnacle.h" -# include "drivers/sensors/cirque_pinnacle_gestures.h" -# include "pointing_device_gestures.h" -#elif defined(POINTING_DEVICE_DRIVER_paw3204) -# include "drivers/sensors/paw3204.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) -# include "i2c_master.h" -# include "drivers/sensors/pimoroni_trackball.h" -// support for legacy pimoroni defines -# ifdef PIMORONI_TRACKBALL_INVERT_X -# define POINTING_DEVICE_INVERT_X -# endif -# ifdef PIMORONI_TRACKBALL_INVERT_Y -# define POINTING_DEVICE_INVERT_Y -# endif -# ifdef PIMORONI_TRACKBALL_ROTATE -# define POINTING_DEVICE_ROTATION_90 -# endif -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389) -# include "spi_master.h" -# include "drivers/sensors/pmw33xx_common.h" -# define POINTING_DEVICE_MOTION_PIN_ACTIVE_LOW -#else -void pointing_device_driver_init(void); -report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report); -uint16_t pointing_device_driver_get_cpi(void); -void pointing_device_driver_set_cpi(uint16_t cpi); -#endif - -typedef struct { - void (*init)(void); - report_mouse_t (*get_report)(report_mouse_t mouse_report); - void (*set_cpi)(uint16_t); - uint16_t (*get_cpi)(void); -} pointing_device_driver_t; - -typedef enum { - POINTING_DEVICE_BUTTON1, - POINTING_DEVICE_BUTTON2, - POINTING_DEVICE_BUTTON3, - POINTING_DEVICE_BUTTON4, - POINTING_DEVICE_BUTTON5, - POINTING_DEVICE_BUTTON6, - POINTING_DEVICE_BUTTON7, - POINTING_DEVICE_BUTTON8, -} pointing_device_buttons_t; - -#ifdef MOUSE_EXTENDED_REPORT -# define XY_REPORT_MIN INT16_MIN -# define XY_REPORT_MAX INT16_MAX -typedef int32_t clamp_range_t; -#else -# define XY_REPORT_MIN INT8_MIN -# define XY_REPORT_MAX INT8_MAX -typedef int16_t clamp_range_t; -#endif - -void pointing_device_init(void); -bool pointing_device_task(void); -bool pointing_device_send(void); -report_mouse_t pointing_device_get_report(void); -void pointing_device_set_report(report_mouse_t mouse_report); -uint16_t pointing_device_get_cpi(void); -void pointing_device_set_cpi(uint16_t cpi); - -void pointing_device_init_kb(void); -void pointing_device_init_user(void); -report_mouse_t pointing_device_task_kb(report_mouse_t mouse_report); -report_mouse_t pointing_device_task_user(report_mouse_t mouse_report); -uint8_t pointing_device_handle_buttons(uint8_t buttons, bool pressed, pointing_device_buttons_t button); -report_mouse_t pointing_device_adjust_by_defines(report_mouse_t mouse_report); -void pointing_device_keycode_handler(uint16_t keycode, bool pressed); - -#if defined(SPLIT_POINTING_ENABLE) -void pointing_device_set_shared_report(report_mouse_t report); -uint16_t pointing_device_get_shared_cpi(void); -# if !defined(POINTING_DEVICE_TASK_THROTTLE_MS) -# define POINTING_DEVICE_TASK_THROTTLE_MS 1 -# endif -# if defined(POINTING_DEVICE_COMBINED) -void pointing_device_set_cpi_on_side(bool left, uint16_t cpi); -report_mouse_t pointing_device_combine_reports(report_mouse_t left_report, report_mouse_t right_report); -report_mouse_t pointing_device_task_combined_kb(report_mouse_t left_report, report_mouse_t right_report); -report_mouse_t pointing_device_task_combined_user(report_mouse_t left_report, report_mouse_t right_report); -report_mouse_t pointing_device_adjust_by_defines_right(report_mouse_t mouse_report); -# endif // defined(POINTING_DEVICE_COMBINED) -#endif // defined(SPLIT_POINTING_ENABLE) diff --git a/quantum/pointing_device/pointing_device_auto_mouse.c b/quantum/pointing_device/pointing_device_auto_mouse.c deleted file mode 100644 index b008d18db54a..000000000000 --- a/quantum/pointing_device/pointing_device_auto_mouse.c +++ /dev/null @@ -1,432 +0,0 @@ -/* Copyright 2021 Christopher Courtney, aka Drashna Jael're (@drashna) - * Copyright 2022 Alabastard - * - * 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 . - */ - -#ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE - -# include "pointing_device_auto_mouse.h" - -/* local data structure for tracking auto mouse */ -static auto_mouse_context_t auto_mouse_context = { - .config.layer = (uint8_t)(AUTO_MOUSE_DEFAULT_LAYER), - .config.timeout = (uint16_t)(AUTO_MOUSE_TIME), - .config.debounce = (uint8_t)(AUTO_MOUSE_DEBOUNCE), -}; - -/* local functions */ -static bool is_mouse_record(uint16_t keycode, keyrecord_t* record); -static void auto_mouse_reset(void); - -/* check for target layer deactivation overrides */ -static inline bool layer_hold_check(void) { - return get_auto_mouse_toggle() || -# ifndef NO_ACTION_ONESHOT - get_oneshot_layer() == (AUTO_MOUSE_TARGET_LAYER) || -# endif - false; -} - -/* check all layer activation criteria */ -static inline bool is_auto_mouse_active(void) { - return auto_mouse_context.status.is_activated || auto_mouse_context.status.mouse_key_tracker || layer_hold_check(); -} - -/** - * @brief Get auto mouse enable state - * - * Return is_enabled value - * - * @return bool true: auto mouse enabled false: auto mouse disabled - */ -bool get_auto_mouse_enable(void) { - return auto_mouse_context.config.is_enabled; -} - -/** - * @brief get current target layer index - * - * NOTE: (AUTO_MOUSE_TARGET_LAYER) is an alias for this function - * - * @return uint8_t target layer index - */ -uint8_t get_auto_mouse_layer(void) { - return auto_mouse_context.config.layer; -} - -/** - * @brief Get the current timeout to turn off mouse layer - * - * @return uint16_t timeout in ms - */ -uint16_t get_auto_mouse_timeout(void) { - return auto_mouse_context.config.timeout; -} - -/** - * @brief Get the auto mouse debouncing timeout - * - * @return uint8_t - */ -uint8_t get_auto_mouse_debounce(void) { - return auto_mouse_context.config.debounce; -} - -/** - * @brief get layer_toggled value - * - * @return bool of current layer_toggled state - */ -bool get_auto_mouse_toggle(void) { - return auto_mouse_context.status.is_toggled; -} - -/** - * @brief Reset auto mouse context - * - * Clear timers and status - * - * NOTE: this will set is_toggled to false so careful when using it - */ -static void auto_mouse_reset(void) { - memset(&auto_mouse_context.status, 0, sizeof(auto_mouse_context.status)); - memset(&auto_mouse_context.timer, 0, sizeof(auto_mouse_context.timer)); -} - -/** - * @brief Set auto mouse enable state - * - * Set local auto mouse enabled state - * - * @param[in] state bool - */ -void set_auto_mouse_enable(bool enable) { - // skip if unchanged - if (auto_mouse_context.config.is_enabled == enable) return; - auto_mouse_context.config.is_enabled = enable; - auto_mouse_reset(); -} - -/** - * @brief Change target layer for auto mouse - * - * Sets input as the new target layer if different from current and resets auto mouse - * - * NOTE: remove_auto_mouse_layer(state, false) or auto_mouse_layer_off should be called - * before this function to avoid issues with layers getting stuck - * - * @param[in] layer uint8_t - */ -void set_auto_mouse_layer(uint8_t layer) { - // skip if unchanged - if (auto_mouse_context.config.layer == layer) return; - auto_mouse_context.config.layer = layer; - auto_mouse_reset(); -} - -/** - * @brief Changes the timeout for the mouse auto layer to be disabled - * - * @param timeout - */ -void set_auto_mouse_timeout(uint16_t timeout) { - if (auto_mouse_context.config.timeout == timeout) return; - auto_mouse_context.config.timeout = timeout; - auto_mouse_reset(); -} - -/** - * @brief Set the auto mouse key debounce - * - * @param debounce - */ -void set_auto_mouse_debounce(uint8_t debounce) { - if (auto_mouse_context.config.debounce == debounce) return; - auto_mouse_context.config.debounce = debounce; - auto_mouse_reset(); -} - -/** - * @brief toggle mouse layer setting - * - * Change state of local layer_toggled bool meant to track when the mouse layer is toggled on by other means - * - * NOTE: While is_toggled is true it will prevent deactiving target layer (but not activation) - */ -void auto_mouse_toggle(void) { - auto_mouse_context.status.is_toggled ^= 1; - auto_mouse_context.timer.delay = 0; -} - -/** - * @brief Remove current auto mouse target layer from layer state - * - * Will remove auto mouse target layer from given layer state if appropriate. - * - * NOTE: Removal can be forced, ignoring appropriate critera - * - * @params state[in] layer_state_t original layer state - * @params force[in] bool force removal - * - * @return layer_state_t modified layer state - */ -layer_state_t remove_auto_mouse_layer(layer_state_t state, bool force) { - if (force || ((AUTO_MOUSE_ENABLED) && !layer_hold_check())) { - state &= ~((layer_state_t)1 << (AUTO_MOUSE_TARGET_LAYER)); - } - return state; -} - -/** - * @brief Disable target layer - * - * Will disable target layer if appropriate. - * NOTE: NOT TO BE USED in layer_state_set stack!!! - */ -void auto_mouse_layer_off(void) { - if (layer_state_is((AUTO_MOUSE_TARGET_LAYER)) && (AUTO_MOUSE_ENABLED) && !layer_hold_check()) { - layer_off((AUTO_MOUSE_TARGET_LAYER)); - } -} - -/** - * @brief Weak function to handel testing if pointing_device is active - * - * Will trigger target layer activation(if delay timer has expired) and prevent deactivation when true. - * May be replaced by bool in report_mouse_t in future - * - * NOTE: defined weakly to allow for changing and adding conditions for specific hardware/customization - * - * @param[in] mouse_report report_mouse_t - * @return bool of pointing_device activation - */ -__attribute__((weak)) bool auto_mouse_activation(report_mouse_t mouse_report) { - return mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons; -} - -/** - * @brief Update the auto mouse based on mouse_report - * - * Handel activation/deactivation of target layer based on auto_mouse_activation and state timers and local key/layer tracking data - * - * @param[in] mouse_report report_mouse_t - */ -void pointing_device_task_auto_mouse(report_mouse_t mouse_report) { - // skip if disabled, delay timer running, or debounce - if (!(AUTO_MOUSE_ENABLED) || timer_elapsed(auto_mouse_context.timer.active) <= auto_mouse_context.config.debounce || timer_elapsed(auto_mouse_context.timer.delay) <= AUTO_MOUSE_DELAY) { - return; - } - // update activation and reset debounce - auto_mouse_context.status.is_activated = auto_mouse_activation(mouse_report); - if (is_auto_mouse_active()) { - auto_mouse_context.timer.active = timer_read(); - auto_mouse_context.timer.delay = 0; - if (!layer_state_is((AUTO_MOUSE_TARGET_LAYER))) { - layer_on((AUTO_MOUSE_TARGET_LAYER)); - } - } else if (layer_state_is((AUTO_MOUSE_TARGET_LAYER)) && timer_elapsed(auto_mouse_context.timer.active) > auto_mouse_context.config.timeout) { - layer_off((AUTO_MOUSE_TARGET_LAYER)); - auto_mouse_context.timer.active = 0; - } -} - -/** - * @brief Handle mouskey event - * - * Increments/decrements mouse_key_tracker and restart active timer - * - * @param[in] pressed bool - */ -void auto_mouse_keyevent(bool pressed) { - if (pressed) { - auto_mouse_context.status.mouse_key_tracker++; - } else { - auto_mouse_context.status.mouse_key_tracker--; - } - auto_mouse_context.timer.delay = 0; -} - -/** - * @brief Handle auto mouse non mousekey reset - * - * Start/restart delay timer and reset auto mouse on keydown as well as turn the - * target layer off if on and reset toggle status - * - * NOTE: NOT TO BE USED in layer_state_set stack!!! - * - * @param[in] pressed bool - */ -void auto_mouse_reset_trigger(bool pressed) { - if (pressed) { - if (layer_state_is((AUTO_MOUSE_TARGET_LAYER))) { - layer_off((AUTO_MOUSE_TARGET_LAYER)); - }; - auto_mouse_reset(); - } - auto_mouse_context.timer.delay = timer_read(); -} - -/** - * @brief handle key events processing for auto mouse - * - * Will process keys differently depending on if key is defined as mousekey or not. - * Some keys have built in behaviour(not overwritable): - * mouse buttons : auto_mouse_keyevent() - * non-mouse keys : auto_mouse_reset_trigger() - * mod keys : skip auto mouse key processing - * mod tap : skip on hold (mod keys) - * QK mods e.g. LCTL(kc): default to non-mouse key, add at kb/user level as needed - * non target layer keys: skip auto mouse key processing (same as mod keys) - * MO(target layer) : auto_mouse_keyevent() - * target layer toggles : auto_mouse_toggle() (on both key up and keydown) - * target layer tap : default processing on tap mouse key on hold - * all other keycodes : default to non-mouse key, add at kb/user level as needed - * - * Will deactivate target layer once a non mouse key is pressed if nothing is holding the layer active - * such as held mousekey, toggled current target layer, or auto_mouse_activation is true - * - * @params keycode[in] uint16_t - * @params record[in] keyrecord_t pointer - */ -bool process_auto_mouse(uint16_t keycode, keyrecord_t* record) { - // skip if not enabled or mouse_layer not set - if (!(AUTO_MOUSE_ENABLED)) return true; - - switch (keycode) { - // Skip Mod keys to avoid layer reset - case KC_LEFT_CTRL ... KC_RIGHT_GUI: - case QK_MODS ... QK_MODS_MAX: - break; - // TO((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- - case QK_TO ... QK_TO_MAX: - if (QK_TO_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - if (!(record->event.pressed)) auto_mouse_toggle(); - } - break; - // TG((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- - case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: - if (QK_TOGGLE_LAYER_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - if (!(record->event.pressed)) auto_mouse_toggle(); - } - break; - // MO((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------- - case QK_MOMENTARY ... QK_MOMENTARY_MAX: - if (QK_MOMENTARY_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - auto_mouse_keyevent(record->event.pressed); - } - // DF --------------------------------------------------------------------------------------------------------- - case QK_DEF_LAYER ... QK_DEF_LAYER_MAX: -# ifndef NO_ACTION_ONESHOT - // OSL((AUTO_MOUSE_TARGET_LAYER))------------------------------------------------------------------------------ - case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: - case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: -# endif - break; - // LM((AUTO_MOUSE_TARGET_LAYER), mod)-------------------------------------------------------------------------- - case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: - if (QK_LAYER_MOD_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - auto_mouse_keyevent(record->event.pressed); - } - break; - // TT((AUTO_MOUSE_TARGET_LAYER))--------------------------------------------------------------------------- -# ifndef NO_ACTION_TAPPING - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: - if (QK_LAYER_TAP_TOGGLE_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - auto_mouse_keyevent(record->event.pressed); -# if TAPPING_TOGGLE != 0 - if (record->tap.count == TAPPING_TOGGLE) { - if (record->event.pressed) { - auto_mouse_context.status.mouse_key_tracker--; - } else { - auto_mouse_toggle(); - auto_mouse_context.status.mouse_key_tracker++; - } - } -# endif - } - break; - // LT((AUTO_MOUSE_TARGET_LAYER), kc)--------------------------------------------------------------------------- - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: - if (!record->tap.count) { - if (QK_LAYER_TAP_GET_LAYER(keycode) == (AUTO_MOUSE_TARGET_LAYER)) { - auto_mouse_keyevent(record->event.pressed); - } - break; - } - // MT(kc) only skip on hold - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - if (!record->tap.count) break; -# endif - // QK_MODS goes to default - default: - // skip on no event - if (IS_NOEVENT(record->event)) break; - // check if keyrecord is mousekey - if (is_mouse_record(keycode, record)) { - auto_mouse_keyevent(record->event.pressed); - } else if (!is_auto_mouse_active()) { - // all non-mousekey presses restart delay timer and reset status - auto_mouse_reset_trigger(record->event.pressed); - } - } - if (auto_mouse_context.status.mouse_key_tracker < 0) { - auto_mouse_context.status.mouse_key_tracker = 0; - dprintf("key tracker error (<0) \n"); - } - return true; -} - -/** - * @brief Local function to handle checking if a keycode is a mouse button - * - * Starts code stack for checking keyrecord if defined as mousekey - * - * @params keycode[in] uint16_t - * @params record[in] keyrecord_t pointer - * @return bool true: keyrecord is mousekey false: keyrecord is not mousekey - */ -static bool is_mouse_record(uint16_t keycode, keyrecord_t* record) { - // allow for keyboard to hook in and override if need be - if (is_mouse_record_kb(keycode, record) || IS_MOUSEKEY(keycode)) return true; - return false; -} - -/** - * @brief Weakly defined keyboard level callback for adding keyrecords as mouse keys - * - * Meant for redefinition at keyboard level and should return is_mouse_record_user by default at end of function - * - * @params keycode[in] uint16_t - * @params record[in] keyrecord_t pointer - * @return bool true: keyrecord is defined as mouse key false: keyrecord is not defined as mouse key - */ -__attribute__((weak)) bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record) { - return is_mouse_record_user(keycode, record); -} - -/** - * @brief Weakly defined keymap/user level callback for adding keyrecords as mouse keys - * - * Meant for redefinition at keymap/user level and should return false by default at end of function - * - * @params keycode[in] uint16_t - * @params record[in] keyrecord_t pointer - * @return bool true: keyrecord is defined as mouse key false: keyrecord is not defined as mouse key - */ -__attribute__((weak)) bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record) { - return false; -} - -#endif // POINTING_DEVICE_AUTO_MOUSE_ENABLE diff --git a/quantum/pointing_device/pointing_device_auto_mouse.h b/quantum/pointing_device/pointing_device_auto_mouse.h deleted file mode 100644 index 7db63bc6b8ab..000000000000 --- a/quantum/pointing_device/pointing_device_auto_mouse.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Copyright 2022 Alabastard - * - * 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 . - */ - -#pragma once - -#include - -#include "quantum.h" -#include "pointing_device.h" -#include "print.h" - -/* check settings and set defaults */ -#ifndef POINTING_DEVICE_AUTO_MOUSE_ENABLE -# error "POINTING_DEVICE_AUTO_MOUSE_ENABLE not defined! check config settings" -#endif - -#ifndef AUTO_MOUSE_DEFAULT_LAYER -# define AUTO_MOUSE_DEFAULT_LAYER 1 -#endif -#ifndef AUTO_MOUSE_TIME -# define AUTO_MOUSE_TIME 650 -#endif -#ifndef AUTO_MOUSE_DELAY -# define AUTO_MOUSE_DELAY GET_TAPPING_TERM(KC_MS_BTN1, &(keyrecord_t){}) -#endif -#ifndef AUTO_MOUSE_DEBOUNCE -# define AUTO_MOUSE_DEBOUNCE 25 -#endif - -/* data structure */ -typedef struct { - struct { - bool is_enabled; - uint8_t layer; - uint16_t timeout; - uint8_t debounce; - } config; - struct { - uint16_t active; - uint16_t delay; - } timer; - struct { - bool is_activated; - bool is_toggled; - int8_t mouse_key_tracker; - } status; -} auto_mouse_context_t; - -/* ----------Set up and control------------------------------------------------------------------------------ */ -void set_auto_mouse_enable(bool enable); // enable/disable auto mouse feature -bool get_auto_mouse_enable(void); // get auto_mouse_enable -void set_auto_mouse_layer(uint8_t layer); // set target layer by index -uint8_t get_auto_mouse_layer(void); // get target layer index -void set_auto_mouse_timeout(uint16_t timeout); // set layer timeout -uint16_t get_auto_mouse_timeout(void); // get layer timeout -void set_auto_mouse_debounce(uint8_t debounce); // set debounce -uint8_t get_auto_mouse_debounce(void); // get debounce -void auto_mouse_layer_off(void); // disable target layer if appropriate (DO NOT USE in layer_state_set stack!!) -layer_state_t remove_auto_mouse_layer(layer_state_t state, bool force); // remove auto mouse target layer from state if appropriate (can be forced) - -/* ----------For custom pointing device activation----------------------------------------------------------- */ -bool auto_mouse_activation(report_mouse_t mouse_report); // handles pointing device trigger conditions for target layer activation (overwritable) - -/* ----------Handling keyevents------------------------------------------------------------------------------ */ -void auto_mouse_keyevent(bool pressed); // trigger auto mouse keyevent: mouse_keytracker increment/decrement on press/release -void auto_mouse_reset_trigger(bool pressed); // trigger non mouse keyevent: reset and start delay timer (DO NOT USE in layer_state_set stack!!) -void auto_mouse_toggle(void); // toggle mouse layer flag disables mouse layer deactivation while on (meant for tap toggle or toggle of target) -bool get_auto_mouse_toggle(void); // get toggle mouse layer flag value - -/* ----------Callbacks for adding keycodes to mouse record checking------------------------------------------ */ -bool is_mouse_record_kb(uint16_t keycode, keyrecord_t* record); -bool is_mouse_record_user(uint16_t keycode, keyrecord_t* record); - -/* ----------Core functions (only used in custom pointing devices or key processing)------------------------- */ -void pointing_device_task_auto_mouse(report_mouse_t mouse_report); // add to pointing_device_task_* -bool process_auto_mouse(uint16_t keycode, keyrecord_t* record); // add to process_record_* - -/* ----------Macros/Aliases---------------------------------------------------------------------------------- */ -#define AUTO_MOUSE_TARGET_LAYER get_auto_mouse_layer() -#define AUTO_MOUSE_ENABLED get_auto_mouse_enable() diff --git a/quantum/pointing_device/pointing_device_drivers.c b/quantum/pointing_device/pointing_device_drivers.c deleted file mode 100644 index 9a4315f76fdf..000000000000 --- a/quantum/pointing_device/pointing_device_drivers.c +++ /dev/null @@ -1,401 +0,0 @@ -/* Copyright 2017 Joshua Broekhuijsen - * Copyright 2020 Christopher Courtney, aka Drashna Jael're (@drashna) - * Copyright 2021 Dasky (@daskygit) - * - * 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 . - */ - -#include "pointing_device.h" -#include "pointing_device_internal.h" -#include "debug.h" -#include "wait.h" -#include "timer.h" -#include - -#define CONSTRAIN_HID(amt) ((amt) < INT8_MIN ? INT8_MIN : ((amt) > INT8_MAX ? INT8_MAX : (amt))) -#define CONSTRAIN_HID_XY(amt) ((amt) < XY_REPORT_MIN ? XY_REPORT_MIN : ((amt) > XY_REPORT_MAX ? XY_REPORT_MAX : (amt))) - -// get_report functions should probably be moved to their respective drivers. - -#if defined(POINTING_DEVICE_DRIVER_adns5050) -report_mouse_t adns5050_get_report(report_mouse_t mouse_report) { - report_adns5050_t data = adns5050_read_burst(); - - if (data.dx != 0 || data.dy != 0) { - pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy); - mouse_report.x = (mouse_xy_report_t)data.dx; - mouse_report.y = (mouse_xy_report_t)data.dy; - } - - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = adns5050_init, - .get_report = adns5050_get_report, - .set_cpi = adns5050_set_cpi, - .get_cpi = adns5050_get_cpi, -}; -// clang-format on - -#elif defined(POINTING_DEVICE_DRIVER_pmw3320) -report_mouse_t pmw3320_get_report(report_mouse_t mouse_report) { - report_pmw3320_t data = pmw3320_read_burst(); - - if (data.dx != 0 || data.dy != 0) { - pd_dprintf("Raw ] X: %d, Y: %d\n", data.dx, data.dy); - mouse_report.x = (mouse_xy_report_t)data.dx; - mouse_report.y = (mouse_xy_report_t)data.dy; - } - - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = pmw3320_init, - .get_report = pmw3320_get_report, - .set_cpi = pmw3320_set_cpi, - .get_cpi = pmw3320_get_cpi, -}; -// clang-format on - -#elif defined(POINTING_DEVICE_DRIVER_adns9800) - -report_mouse_t adns9800_get_report_driver(report_mouse_t mouse_report) { - report_adns9800_t sensor_report = adns9800_get_report(); - - mouse_report.x = CONSTRAIN_HID_XY(sensor_report.x); - mouse_report.y = CONSTRAIN_HID_XY(sensor_report.y); - - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = adns9800_init, - .get_report = adns9800_get_report_driver, - .set_cpi = adns9800_set_cpi, - .get_cpi = adns9800_get_cpi -}; -// clang-format on - -#elif defined(POINTING_DEVICE_DRIVER_analog_joystick) -report_mouse_t analog_joystick_get_report(report_mouse_t mouse_report) { - report_analog_joystick_t data = analog_joystick_read(); - - pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); - - mouse_report.x = data.x; - mouse_report.y = data.y; - - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, data.button, POINTING_DEVICE_BUTTON1); - - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = analog_joystick_init, - .get_report = analog_joystick_get_report, - .set_cpi = NULL, - .get_cpi = NULL -}; -// clang-format on - -#elif defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_i2c) || defined(POINTING_DEVICE_DRIVER_cirque_pinnacle_spi) -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE -static bool cursor_glide_enable = true; - -static cursor_glide_context_t glide = {.config = { - .coef = 102, /* Good default friction coef */ - .interval = 10, /* 100sps */ - .trigger_px = 10, /* Default threshold in case of hover, set to 0 if you'd like */ - }}; - -void cirque_pinnacle_enable_cursor_glide(bool enable) { - cursor_glide_enable = enable; -} - -void cirque_pinnacle_configure_cursor_glide(float trigger_px) { - glide.config.trigger_px = trigger_px; -} -# endif - -# if CIRQUE_PINNACLE_POSITION_MODE - -# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE -static bool is_touch_down; - -bool auto_mouse_activation(report_mouse_t mouse_report) { - return is_touch_down || mouse_report.x != 0 || mouse_report.y != 0 || mouse_report.h != 0 || mouse_report.v != 0 || mouse_report.buttons; -} -# endif - -report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { - uint16_t scale = cirque_pinnacle_get_scale(); - pinnacle_data_t touchData = cirque_pinnacle_read_data(); - mouse_xy_report_t report_x = 0, report_y = 0; - static uint16_t x = 0, y = 0, last_scale = 0; - -# if defined(CIRQUE_PINNACLE_TAP_ENABLE) - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); -# endif -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE - cursor_glide_t glide_report = {0}; - - if (cursor_glide_enable) { - glide_report = cursor_glide_check(&glide); - } -# endif - - if (!touchData.valid) { -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE - if (cursor_glide_enable && glide_report.valid) { - report_x = glide_report.dx; - report_y = glide_report.dy; - goto mouse_report_update; - } -# endif - return mouse_report; - } - - if (touchData.touchDown) { - pd_dprintf("cirque_pinnacle touchData x=%4d y=%4d z=%2d\n", touchData.xValue, touchData.yValue, touchData.zValue); - } - -# ifdef POINTING_DEVICE_AUTO_MOUSE_ENABLE - is_touch_down = touchData.touchDown; -# endif - - // Scale coordinates to arbitrary X, Y resolution - cirque_pinnacle_scale_data(&touchData, scale, scale); - - if (!cirque_pinnacle_gestures(&mouse_report, touchData)) { - if (last_scale && scale == last_scale && x && y && touchData.xValue && touchData.yValue) { - report_x = CONSTRAIN_HID_XY((int16_t)(touchData.xValue - x)); - report_y = CONSTRAIN_HID_XY((int16_t)(touchData.yValue - y)); - } - x = touchData.xValue; - y = touchData.yValue; - last_scale = scale; - -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE - if (cursor_glide_enable) { - if (touchData.touchDown) { - cursor_glide_update(&glide, report_x, report_y, touchData.zValue); - } else if (!glide_report.valid) { - glide_report = cursor_glide_start(&glide); - if (glide_report.valid) { - report_x = glide_report.dx; - report_y = glide_report.dy; - } - } - } -# endif - } - -# ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE -mouse_report_update: -# endif - mouse_report.x = report_x; - mouse_report.y = report_y; - - return mouse_report; -} - -uint16_t cirque_pinnacle_get_cpi(void) { - return CIRQUE_PINNACLE_PX_TO_INCH(cirque_pinnacle_get_scale()); -} -void cirque_pinnacle_set_cpi(uint16_t cpi) { - cirque_pinnacle_set_scale(CIRQUE_PINNACLE_INCH_TO_PX(cpi)); -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = cirque_pinnacle_init, - .get_report = cirque_pinnacle_get_report, - .set_cpi = cirque_pinnacle_set_cpi, - .get_cpi = cirque_pinnacle_get_cpi -}; -// clang-format on -# else -report_mouse_t cirque_pinnacle_get_report(report_mouse_t mouse_report) { - pinnacle_data_t touchData = cirque_pinnacle_read_data(); - - // Scale coordinates to arbitrary X, Y resolution - cirque_pinnacle_scale_data(&touchData, cirque_pinnacle_get_scale(), cirque_pinnacle_get_scale()); - - if (touchData.valid) { - mouse_report.buttons = touchData.buttons; - mouse_report.x = CONSTRAIN_HID_XY(touchData.xDelta); - mouse_report.y = CONSTRAIN_HID_XY(touchData.yDelta); - mouse_report.v = touchData.wheelCount; - } - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = cirque_pinnacle_init, - .get_report = cirque_pinnacle_get_report, - .set_cpi = cirque_pinnacle_set_scale, - .get_cpi = cirque_pinnacle_get_scale -}; -// clang-format on -# endif - -#elif defined(POINTING_DEVICE_DRIVER_paw3204) - -report_mouse_t paw3204_get_report(report_mouse_t mouse_report) { - report_paw3204_t data = paw3204_read(); - if (data.isMotion) { - pd_dprintf("Raw ] X: %d, Y: %d\n", data.x, data.y); - - mouse_report.x = data.x; - mouse_report.y = data.y; - } - - return mouse_report; -} -const pointing_device_driver_t pointing_device_driver = { - .init = paw3204_init, - .get_report = paw3204_get_report, - .set_cpi = paw3204_set_cpi, - .get_cpi = paw3204_get_cpi, -}; -#elif defined(POINTING_DEVICE_DRIVER_pimoroni_trackball) - -mouse_xy_report_t pimoroni_trackball_adapt_values(clamp_range_t* offset) { - if (*offset > XY_REPORT_MAX) { - *offset -= XY_REPORT_MAX; - return (mouse_xy_report_t)XY_REPORT_MAX; - } else if (*offset < XY_REPORT_MIN) { - *offset += XY_REPORT_MAX; - return (mouse_xy_report_t)XY_REPORT_MIN; - } else { - mouse_xy_report_t temp_return = *offset; - *offset = 0; - return temp_return; - } -} - -report_mouse_t pimoroni_trackball_get_report(report_mouse_t mouse_report) { - static uint16_t debounce = 0; - static uint8_t error_count = 0; - pimoroni_data_t pimoroni_data = {0}; - static clamp_range_t x_offset = 0, y_offset = 0; - - if (error_count < PIMORONI_TRACKBALL_ERROR_COUNT) { - i2c_status_t status = read_pimoroni_trackball(&pimoroni_data); - - if (status == I2C_STATUS_SUCCESS) { - error_count = 0; - - if (!(pimoroni_data.click & 128)) { - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, false, POINTING_DEVICE_BUTTON1); - if (!debounce) { - x_offset += pimoroni_trackball_get_offsets(pimoroni_data.right, pimoroni_data.left, PIMORONI_TRACKBALL_SCALE); - y_offset += pimoroni_trackball_get_offsets(pimoroni_data.down, pimoroni_data.up, PIMORONI_TRACKBALL_SCALE); - mouse_report.x = pimoroni_trackball_adapt_values(&x_offset); - mouse_report.y = pimoroni_trackball_adapt_values(&y_offset); - } else { - debounce--; - } - } else { - mouse_report.buttons = pointing_device_handle_buttons(mouse_report.buttons, true, POINTING_DEVICE_BUTTON1); - debounce = PIMORONI_TRACKBALL_DEBOUNCE_CYCLES; - } - } else { - error_count++; - } - } - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = pimoroni_trackball_device_init, - .get_report = pimoroni_trackball_get_report, - .set_cpi = pimoroni_trackball_set_cpi, - .get_cpi = pimoroni_trackball_get_cpi -}; -// clang-format on - -#elif defined(POINTING_DEVICE_DRIVER_pmw3360) || defined(POINTING_DEVICE_DRIVER_pmw3389) -static void pmw33xx_init_wrapper(void) { - pmw33xx_init(0); -} - -static void pmw33xx_set_cpi_wrapper(uint16_t cpi) { - pmw33xx_set_cpi(0, cpi); -} - -static uint16_t pmw33xx_get_cpi_wrapper(void) { - return pmw33xx_get_cpi(0); -} - -report_mouse_t pmw33xx_get_report(report_mouse_t mouse_report) { - pmw33xx_report_t report = pmw33xx_read_burst(0); - static bool in_motion = false; - - if (report.motion.b.is_lifted) { - return mouse_report; - } - - if (!report.motion.b.is_motion) { - in_motion = false; - return mouse_report; - } - - if (!in_motion) { - in_motion = true; - pd_dprintf("PWM3360 (0): starting motion\n"); - } - - mouse_report.x = CONSTRAIN_HID_XY(report.delta_x); - mouse_report.y = CONSTRAIN_HID_XY(report.delta_y); - return mouse_report; -} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = pmw33xx_init_wrapper, - .get_report = pmw33xx_get_report, - .set_cpi = pmw33xx_set_cpi_wrapper, - .get_cpi = pmw33xx_get_cpi_wrapper -}; -// clang-format on - -#else -__attribute__((weak)) void pointing_device_driver_init(void) {} -__attribute__((weak)) report_mouse_t pointing_device_driver_get_report(report_mouse_t mouse_report) { - return mouse_report; -} -__attribute__((weak)) uint16_t pointing_device_driver_get_cpi(void) { - return 0; -} -__attribute__((weak)) void pointing_device_driver_set_cpi(uint16_t cpi) {} - -// clang-format off -const pointing_device_driver_t pointing_device_driver = { - .init = pointing_device_driver_init, - .get_report = pointing_device_driver_get_report, - .get_cpi = pointing_device_driver_get_cpi, - .set_cpi = pointing_device_driver_set_cpi -}; -// clang-format on - -#endif diff --git a/quantum/pointing_device/pointing_device_gestures.c b/quantum/pointing_device/pointing_device_gestures.c deleted file mode 100644 index 02b11ebe3fd1..000000000000 --- a/quantum/pointing_device/pointing_device_gestures.c +++ /dev/null @@ -1,133 +0,0 @@ -/* Copyright 2022 Daniel Kao - * - * 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 . - */ -#include -#include "pointing_device_gestures.h" -#include "timer.h" - -#ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE -# ifdef POINTING_DEVICE_MOTION_PIN -# error POINTING_DEVICE_MOTION_PIN not supported when using inertial cursor. Need repeated calls to get_report() to generate glide events. -# endif - -static void cursor_glide_stop(cursor_glide_context_t* glide) { - memset(&glide->status, 0, sizeof(glide->status)); -} - -static cursor_glide_t cursor_glide(cursor_glide_context_t* glide) { - cursor_glide_status_t* status = &glide->status; - cursor_glide_t report; - int32_t p; - int32_t x, y; - - if (status->v0 == 0) { - report.dx = 0; - report.dy = 0; - report.valid = false; - cursor_glide_stop(glide); - goto exit; - } - - status->counter++; - /* Calculate current 1D position */ - p = status->v0 * status->counter - (int32_t)glide->config.coef * status->counter * status->counter / 2; - /* - * Translate to x & y axes - * Done this way instead of applying friction to each axis separately, so we don't end up with the shorter axis stuck at 0 towards the end of diagonal movements. - */ - x = (int32_t)(p * status->dx0 / status->v0); - y = (int32_t)(p * status->dy0 / status->v0); - report.dx = (mouse_xy_report_t)(x - status->x); - report.dy = (mouse_xy_report_t)(y - status->y); - report.valid = true; - if (report.dx <= 1 && report.dx >= -1 && report.dy <= 1 && report.dy >= -1) { - /* Stop gliding once speed is low enough */ - cursor_glide_stop(glide); - goto exit; - } - status->x = x; - status->y = y; - status->timer = timer_read(); - -exit: - return report; -} - -cursor_glide_t cursor_glide_check(cursor_glide_context_t* glide) { - cursor_glide_t invalid_report = {0, 0, false}; - cursor_glide_status_t* status = &glide->status; - - if (status->z || (status->dx0 == 0 && status->dy0 == 0) || timer_elapsed(status->timer) < glide->config.interval) { - return invalid_report; - } else { - return cursor_glide(glide); - } -} - -static inline uint16_t sqrt32(uint32_t x) { - uint32_t l, m, h; - - if (x == 0) { - return 0; - } else if (x > (UINT16_MAX >> 2)) { - /* Safe upper bound to avoid integer overflow with m * m */ - h = UINT16_MAX; - } else { - /* Upper bound based on closest log2 */ - h = (1 << (((__builtin_clzl(1) - __builtin_clzl(x) + 1) + 1) >> 1)); - } - /* Lower bound based on closest log2 */ - l = (1 << ((__builtin_clzl(1) - __builtin_clzl(x)) >> 1)); - - /* Binary search to find integer square root */ - while (l != h - 1) { - m = (l + h) / 2; - if (m * m <= x) { - l = m; - } else { - h = m; - } - } - return l; -} - -cursor_glide_t cursor_glide_start(cursor_glide_context_t* glide) { - cursor_glide_t invalid_report = {0, 0, false}; - cursor_glide_status_t* status = &glide->status; - - status->timer = timer_read(); - status->counter = 0; - status->v0 = (status->dx0 == 0 && status->dy0 == 0) ? 0.0 : sqrt32(((int32_t)status->dx0 * 256 * status->dx0 * 256) + ((int32_t)status->dy0 * 256 * status->dy0 * 256)); // skip trigonometry if not needed, calculate distance in Q8 - status->x = 0; - status->y = 0; - status->z = 0; - - if (status->v0 < ((uint32_t)glide->config.trigger_px * 256)) { /* Q8 comparison */ - /* Not enough velocity to be worth gliding, abort */ - cursor_glide_stop(glide); - return invalid_report; - } - - return cursor_glide(glide); -} - -void cursor_glide_update(cursor_glide_context_t* glide, mouse_xy_report_t dx, mouse_xy_report_t dy, uint16_t z) { - cursor_glide_status_t* status = &glide->status; - - status->dx0 = dx; - status->dy0 = dy; - status->z = z; -} -#endif diff --git a/quantum/pointing_device/pointing_device_gestures.h b/quantum/pointing_device/pointing_device_gestures.h deleted file mode 100644 index d2ea44971b80..000000000000 --- a/quantum/pointing_device/pointing_device_gestures.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright 2022 Daniel Kao - * - * 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 . - */ -#pragma once - -#include -#include "report.h" - -#ifdef POINTING_DEVICE_GESTURES_CURSOR_GLIDE_ENABLE -typedef struct { - mouse_xy_report_t dx; - mouse_xy_report_t dy; - bool valid; -} cursor_glide_t; - -typedef struct { - uint16_t trigger_px; /* Pixels of movement needed to trigger cursor glide */ - uint16_t coef; /* Coefficient of friction */ - uint16_t interval; /* Glide report interval, in milliseconds */ -} cursor_glide_config_t; - -typedef struct { - int32_t v0; - int32_t x; - int32_t y; - uint16_t z; - uint16_t timer; - uint16_t counter; - mouse_xy_report_t dx0; - mouse_xy_report_t dy0; -} cursor_glide_status_t; - -typedef struct { - cursor_glide_config_t config; - cursor_glide_status_t status; -} cursor_glide_context_t; - -/* Check glide report conditions, calculates glide coordinates */ -cursor_glide_t cursor_glide_check(cursor_glide_context_t* glide); - -/* Start glide reporting, gives first set of glide coordinates */ -cursor_glide_t cursor_glide_start(cursor_glide_context_t* glide); - -/* Update glide engine on the latest cursor movement, cursor glide is based on the final movement */ -void cursor_glide_update(cursor_glide_context_t* glide, mouse_xy_report_t dx, mouse_xy_report_t dy, uint16_t z); -#endif diff --git a/quantum/pointing_device_internal.h b/quantum/pointing_device_internal.h deleted file mode 100644 index ef649407caf3..000000000000 --- a/quantum/pointing_device_internal.h +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2022 Stefan Kerkmann -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#ifdef POINTING_DEVICE_DEBUG -# include "debug.h" -# include "print.h" -# define pd_dprintf(...) dprintf(__VA_ARGS__) -#else -# define pd_dprintf(...) \ - do { \ - } while (0) -#endif diff --git a/quantum/process_keycode/autocorrect_data_default.h b/quantum/process_keycode/autocorrect_data_default.h deleted file mode 100644 index bfc29666df69..000000000000 --- a/quantum/process_keycode/autocorrect_data_default.h +++ /dev/null @@ -1,85 +0,0 @@ -// Generated code. - -// Autocorrection dictionary (70 entries): -// :guage -> gauge -// :the:the: -> the -// :thier -> their -// :ture -> true -// accomodate -> accommodate -// acommodate -> accommodate -// aparent -> apparent -// aparrent -> apparent -// apparant -> apparent -// apparrent -> apparent -// aquire -> acquire -// becuase -> because -// cauhgt -> caught -// cheif -> chief -// choosen -> chosen -// cieling -> ceiling -// collegue -> colleague -// concensus -> consensus -// contians -> contains -// cosnt -> const -// dervied -> derived -// fales -> false -// fasle -> false -// fitler -> filter -// flase -> false -// foward -> forward -// frequecy -> frequency -// gaurantee -> guarantee -// guaratee -> guarantee -// heigth -> height -// heirarchy -> hierarchy -// inclued -> include -// interator -> iterator -// intput -> input -// invliad -> invalid -// lenght -> length -// liasion -> liaison -// libary -> library -// listner -> listener -// looses: -> loses -// looup -> lookup -// manefist -> manifest -// namesapce -> namespace -// namespcae -> namespace -// occassion -> occasion -// occured -> occurred -// ouptut -> output -// ouput -> output -// overide -> override -// postion -> position -// priviledge -> privilege -// psuedo -> pseudo -// recieve -> receive -// refered -> referred -// relevent -> relevant -// repitition -> repetition -// retrun -> return -// retun -> return -// reuslt -> result -// reutrn -> return -// saftey -> safety -// seperate -> separate -// singed -> signed -// stirng -> string -// strign -> string -// swithc -> switch -// swtich -> switch -// thresold -> threshold -// udpate -> update -// widht -> width - -#define AUTOCORRECT_MIN_LENGTH 5 // ":ture" -#define AUTOCORRECT_MAX_LENGTH 10 // "accomodate" - -#define DICTIONARY_SIZE 1104 - -static const uint8_t autocorrect_data[DICTIONARY_SIZE] PROGMEM = {108, 43, 0, 6, 71, 0, 7, 81, 0, 8, 199, 0, 9, 240, 1, 10, 250, 1, 11, 26, 2, 17, 53, 2, 18, 190, 2, 19, 202, 2, 21, 212, 2, 22, 20, 3, 23, 67, 3, 28, 16, 4, 0, 72, 50, 0, 22, 60, 0, 0, 11, 23, 44, 8, 11, 23, 44, 0, 132, 0, 8, 22, 18, 18, 15, 0, 132, 115, 101, 115, 0, 11, 23, 12, 26, 22, 0, 129, 99, 104, 0, 68, 94, 0, 8, 106, 0, 15, 174, 0, 21, 187, 0, 0, 12, 15, 25, 17, 12, 0, 131, 97, 108, 105, 100, 0, 74, 119, 0, 12, 129, 0, 21, 140, 0, 24, 165, 0, 0, 17, 12, 22, 0, 131, 103, 110, 101, 100, 0, 25, 21, 8, 7, 0, 131, 105, 118, 101, 100, 0, 72, 147, 0, 24, 156, 0, 0, 9, 8, 21, 0, 129, 114, 101, 100, 0, 6, 6, 18, 0, 129, 114, 101, 100, 0, 15, 6, 17, 12, 0, 129, 100, 101, 0, 18, 22, 8, 21, 11, 23, 0, 130, 104, 111, - 108, 100, 0, 4, 26, 18, 9, 0, 131, 114, 119, 97, 114, 100, 0, 68, 233, 0, 6, 246, 0, 7, 4, 1, 8, 16, 1, 10, 52, 1, 15, 81, 1, 21, 90, 1, 22, 117, 1, 23, 144, 1, 24, 215, 1, 25, 228, 1, 0, 6, 19, 22, 8, 16, 4, 17, 0, 130, 97, 99, 101, 0, 19, 4, 22, 8, 16, 4, 17, 0, 131, 112, 97, 99, 101, 0, 12, 21, 8, 25, 18, 0, 130, 114, 105, 100, 101, 0, 23, 0, 68, 25, 1, 17, 36, 1, 0, 21, 4, 24, 10, 0, 130, 110, 116, 101, 101, 0, 4, 21, 24, 4, 10, 0, 135, 117, 97, 114, 97, 110, 116, 101, 101, 0, 68, 59, 1, 7, 69, 1, 0, 24, 10, 44, 0, 131, 97, 117, 103, 101, 0, 8, 15, 12, 25, 12, 21, 19, 0, 130, 103, 101, 0, 22, 4, 9, 0, 130, 108, 115, 101, 0, 76, 97, 1, 24, 109, 1, 0, 24, 20, 4, 0, 132, 99, 113, 117, 105, 114, 101, 0, 23, 44, 0, - 130, 114, 117, 101, 0, 4, 0, 79, 126, 1, 24, 134, 1, 0, 9, 0, 131, 97, 108, 115, 101, 0, 6, 8, 5, 0, 131, 97, 117, 115, 101, 0, 4, 0, 71, 156, 1, 19, 193, 1, 21, 203, 1, 0, 18, 16, 0, 80, 166, 1, 18, 181, 1, 0, 18, 6, 4, 0, 135, 99, 111, 109, 109, 111, 100, 97, 116, 101, 0, 6, 6, 4, 0, 132, 109, 111, 100, 97, 116, 101, 0, 7, 24, 0, 132, 112, 100, 97, 116, 101, 0, 8, 19, 8, 22, 0, 132, 97, 114, 97, 116, 101, 0, 10, 8, 15, 15, 18, 6, 0, 130, 97, 103, 117, 101, 0, 8, 12, 6, 8, 21, 0, 131, 101, 105, 118, 101, 0, 12, 8, 11, 6, 0, 130, 105, 101, 102, 0, 17, 0, 76, 3, 2, 21, 16, 2, 0, 15, 8, 12, 6, 0, 133, 101, 105, 108, 105, 110, 103, 0, 12, 23, 22, 0, 131, 114, 105, 110, 103, 0, 70, 33, 2, 23, 44, 2, 0, 12, 23, 26, 22, 0, 131, 105, - 116, 99, 104, 0, 10, 12, 8, 11, 0, 129, 104, 116, 0, 72, 69, 2, 10, 80, 2, 18, 89, 2, 21, 156, 2, 24, 167, 2, 0, 22, 18, 18, 11, 6, 0, 131, 115, 101, 110, 0, 12, 21, 23, 22, 0, 129, 110, 103, 0, 12, 0, 86, 98, 2, 23, 124, 2, 0, 68, 105, 2, 22, 114, 2, 0, 12, 15, 0, 131, 105, 115, 111, 110, 0, 4, 6, 6, 18, 0, 131, 105, 111, 110, 0, 76, 131, 2, 22, 146, 2, 0, 23, 12, 19, 8, 21, 0, 134, 101, 116, 105, 116, 105, 111, 110, 0, 18, 19, 0, 131, 105, 116, 105, 111, 110, 0, 23, 24, 8, 21, 0, 131, 116, 117, 114, 110, 0, 85, 174, 2, 23, 183, 2, 0, 23, 8, 21, 0, 130, 117, 114, 110, 0, 8, 21, 0, 128, 114, 110, 0, 7, 8, 24, 22, 19, 0, 131, 101, 117, 100, 111, 0, 24, 18, 18, 15, 0, 129, 107, 117, 112, 0, 72, 219, 2, 18, 3, 3, 0, 76, 229, 2, 15, 238, - 2, 17, 248, 2, 0, 11, 23, 44, 0, 130, 101, 105, 114, 0, 23, 12, 9, 0, 131, 108, 116, 101, 114, 0, 23, 22, 12, 15, 0, 130, 101, 110, 101, 114, 0, 23, 4, 21, 8, 23, 17, 12, 0, 135, 116, 101, 114, 97, 116, 111, 114, 0, 72, 30, 3, 17, 38, 3, 24, 51, 3, 0, 15, 4, 9, 0, 129, 115, 101, 0, 4, 12, 23, 17, 18, 6, 0, 131, 97, 105, 110, 115, 0, 22, 17, 8, 6, 17, 18, 6, 0, 133, 115, 101, 110, 115, 117, 115, 0, 74, 86, 3, 11, 96, 3, 15, 118, 3, 17, 129, 3, 22, 218, 3, 24, 232, 3, 0, 11, 24, 4, 6, 0, 130, 103, 104, 116, 0, 71, 103, 3, 10, 110, 3, 0, 12, 26, 0, 129, 116, 104, 0, 17, 8, 15, 0, 129, 116, 104, 0, 22, 24, 8, 21, 0, 131, 115, 117, 108, 116, 0, 68, 139, 3, 8, 150, 3, 22, 210, 3, 0, 21, 4, 19, 19, 4, 0, 130, 101, 110, 116, 0, 85, 157, - 3, 25, 200, 3, 0, 68, 164, 3, 21, 175, 3, 0, 19, 4, 0, 132, 112, 97, 114, 101, 110, 116, 0, 4, 19, 0, 68, 185, 3, 19, 193, 3, 0, 133, 112, 97, 114, 101, 110, 116, 0, 4, 0, 131, 101, 110, 116, 0, 8, 15, 8, 21, 0, 130, 97, 110, 116, 0, 18, 6, 0, 130, 110, 115, 116, 0, 12, 9, 8, 17, 4, 16, 0, 132, 105, 102, 101, 115, 116, 0, 83, 239, 3, 23, 6, 4, 0, 87, 246, 3, 24, 254, 3, 0, 17, 12, 0, 131, 112, 117, 116, 0, 18, 0, 130, 116, 112, 117, 116, 0, 19, 24, 18, 0, 131, 116, 112, 117, 116, 0, 70, 29, 4, 8, 41, 4, 11, 51, 4, 21, 69, 4, 0, 8, 24, 20, 8, 21, 9, 0, 129, 110, 99, 121, 0, 23, 9, 4, 22, 0, 130, 101, 116, 121, 0, 6, 21, 4, 21, 12, 8, 11, 0, 135, 105, 101, 114, 97, 114, 99, 104, 121, 0, 4, 5, 12, 15, 0, 130, 114, 97, 114, 121, 0}; diff --git a/quantum/process_keycode/process_audio.c b/quantum/process_keycode/process_audio.c deleted file mode 100644 index c189dd02b713..000000000000 --- a/quantum/process_keycode/process_audio.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "audio.h" -#include "process_audio.h" - -#ifndef VOICE_CHANGE_SONG -# define VOICE_CHANGE_SONG SONG(VOICE_CHANGE_SOUND) -#endif -float voice_change_song[][2] = VOICE_CHANGE_SONG; - -#ifndef PITCH_STANDARD_A -# define PITCH_STANDARD_A 440.0f -#endif - -float compute_freq_for_midi_note(uint8_t note) { - // https://en.wikipedia.org/wiki/MIDI_tuning_standard - return pow(2.0, (note - 69) / 12.0) * PITCH_STANDARD_A; -} - -bool process_audio(uint16_t keycode, keyrecord_t *record) { - if (keycode == QK_AUDIO_ON && record->event.pressed) { - audio_on(); - return false; - } - - if (keycode == QK_AUDIO_OFF && record->event.pressed) { - audio_off(); - return false; - } - - if (keycode == QK_AUDIO_TOGGLE && record->event.pressed) { - if (is_audio_on()) { - audio_off(); - } else { - audio_on(); - } - return false; - } - - if (keycode == QK_AUDIO_VOICE_NEXT && record->event.pressed) { - voice_iterate(); - PLAY_SONG(voice_change_song); - return false; - } - - if (keycode == QK_AUDIO_VOICE_PREVIOUS && record->event.pressed) { - voice_deiterate(); - PLAY_SONG(voice_change_song); - return false; - } - - return true; -} - -void process_audio_noteon(uint8_t note) { - play_note(compute_freq_for_midi_note(note), 0xF); -} - -void process_audio_noteoff(uint8_t note) { - stop_note(compute_freq_for_midi_note(note)); -} - -void process_audio_all_notes_off(void) { - stop_all_notes(); -} - -__attribute__((weak)) void audio_on_user(void) {} -__attribute__((weak)) void audio_off_user(void) {} diff --git a/quantum/process_keycode/process_audio.h b/quantum/process_keycode/process_audio.h deleted file mode 100644 index 42cfab4af27d..000000000000 --- a/quantum/process_keycode/process_audio.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -float compute_freq_for_midi_note(uint8_t note); - -bool process_audio(uint16_t keycode, keyrecord_t *record); -void process_audio_noteon(uint8_t note); -void process_audio_noteoff(uint8_t note); -void process_audio_all_notes_off(void); - -void audio_on_user(void); -void audio_off_user(void); diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c deleted file mode 100644 index 62c347ae0cd7..000000000000 --- a/quantum/process_keycode/process_auto_shift.c +++ /dev/null @@ -1,490 +0,0 @@ -/* Copyright 2017 Jeremy Cowgar - * - * 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 . - */ - -#ifdef AUTO_SHIFT_ENABLE - -# include -# include "process_auto_shift.h" - -# ifndef AUTO_SHIFT_DISABLED_AT_STARTUP -# define AUTO_SHIFT_STARTUP_STATE true /* enabled */ -# else -# define AUTO_SHIFT_STARTUP_STATE false /* disabled */ -# endif - -// Stores the last Auto Shift key's up or down time, for evaluation or keyrepeat. -static uint16_t autoshift_time = 0; -# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) -// Stores the last key's up or down time, to replace autoshift_time so that Tap Hold times are accurate. -static uint16_t retroshift_time = 0; -// Stores a possibly Retro Shift key's up or down time, as retroshift_time needs -// to be set before the Retro Shift key is evaluated if it is interrupted by an -// Auto Shifted key. -static uint16_t last_retroshift_time; -# endif -static uint16_t autoshift_timeout = AUTO_SHIFT_TIMEOUT; -static uint16_t autoshift_lastkey = KC_NO; -static keyrecord_t autoshift_lastrecord; -// Keys take 8 bits if modifiers are excluded. This records the shift state -// when pressed for each key, so that can be passed to the release function -// and it knows which key needs to be released (if shifted is different base). -static uint16_t autoshift_shift_states[((1 << 8) + 15) / 16]; -static struct { - // Whether Auto Shift is enabled. - bool enabled : 1; - // Whether the last auto-shifted key was released after the timeout. This - // is used to replicate the last key for a tap-then-hold. - bool lastshifted : 1; - // Whether an auto-shiftable key has been pressed but not processed. - bool in_progress : 1; - // Whether the auto-shifted keypress has been registered. - bool holding_shift : 1; - // Whether the user is holding a shift and we removed it. - bool cancelling_lshift : 1; - bool cancelling_rshift : 1; - // clang-format wants to remove the true for some reason. - // clang-format off -} autoshift_flags = {AUTO_SHIFT_STARTUP_STATE, false, false, false, false, false}; -// clang-format on - -/** \brief Called on physical press, returns whether key should be added to Auto Shift */ -__attribute__((weak)) bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { - return false; -} - -/** \brief Called on physical press, returns whether is Auto Shift key */ -__attribute__((weak)) bool get_auto_shifted_key(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { -# ifndef NO_AUTO_SHIFT_ALPHA - case AUTO_SHIFT_ALPHA: -# endif -# ifndef NO_AUTO_SHIFT_NUMERIC - case AUTO_SHIFT_NUMERIC: -# endif -# ifndef NO_AUTO_SHIFT_SPECIAL - case AUTO_SHIFT_SPECIAL: -# endif - return true; - } - return get_custom_auto_shifted_key(keycode, record); -} - -/** \brief Called to check whether defines should apply if PER_KEY is set for it */ -__attribute__((weak)) bool get_auto_shift_repeat(uint16_t keycode, keyrecord_t *record) { - return true; -} -__attribute__((weak)) bool get_auto_shift_no_auto_repeat(uint16_t keycode, keyrecord_t *record) { - return true; -} - -/** \brief Called when an Auto Shift key needs to be pressed */ -__attribute__((weak)) void autoshift_press_user(uint16_t keycode, bool shifted, keyrecord_t *record) { - if (shifted) { - add_weak_mods(MOD_BIT(KC_LSFT)); - } - register_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); -} - -/** \brief Called when an Auto Shift key needs to be released */ -__attribute__((weak)) void autoshift_release_user(uint16_t keycode, bool shifted, keyrecord_t *record) { - unregister_code16((IS_RETRO(keycode)) ? keycode & 0xFF : keycode); -} - -/** \brief Sets the shift state to use when keyrepeating, required by custom shifts */ -void set_autoshift_shift_state(uint16_t keycode, bool shifted) { - keycode = keycode & 0xFF; - if (shifted) { - autoshift_shift_states[keycode / 16] |= (uint16_t)1 << keycode % 16; - } else { - autoshift_shift_states[keycode / 16] &= ~((uint16_t)1 << keycode % 16); - } -} - -/** \brief Gets the shift state to use when keyrepeating, required by custom shifts */ -bool get_autoshift_shift_state(uint16_t keycode) { - keycode = keycode & 0xFF; - return (autoshift_shift_states[keycode / 16] & (uint16_t)1 << keycode % 16) != (uint16_t)0; -} - -/** \brief Restores the shift key if it was cancelled by Auto Shift */ -static void autoshift_flush_shift(void) { - autoshift_flags.holding_shift = false; -# ifdef CAPS_WORD_ENABLE - if (!is_caps_word_on()) -# endif // CAPS_WORD_ENABLE - { - del_weak_mods(MOD_BIT(KC_LSFT)); - } - if (autoshift_flags.cancelling_lshift) { - autoshift_flags.cancelling_lshift = false; - add_mods(MOD_BIT(KC_LSFT)); - } - if (autoshift_flags.cancelling_rshift) { - autoshift_flags.cancelling_rshift = false; - add_mods(MOD_BIT(KC_RSFT)); - } - send_keyboard_report(); -} - -/** \brief Record the press of an autoshiftable key - * - * \return Whether the record should be further processed. - */ -static bool autoshift_press(uint16_t keycode, uint16_t now, keyrecord_t *record) { - // clang-format off - if ((get_mods() -# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - | get_oneshot_mods() -# endif - ) & (~MOD_BIT(KC_LSFT)) - ) { - // clang-format on - // Prevents keyrepeating unshifted value of key after using it in a key combo. - autoshift_lastkey = KC_NO; -# ifndef AUTO_SHIFT_MODIFIERS - // We can't return true here anymore because custom unshifted values are - // possible and there's no good way to tell whether the press returned - // true upon release. - set_autoshift_shift_state(keycode, false); - autoshift_press_user(keycode, false, record); -# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - set_oneshot_mods(get_oneshot_mods() & (~MOD_BIT(KC_LSFT))); - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); -# endif - return false; -# endif - } - - // Store record to be sent to user functions if there's no release record then. - autoshift_lastrecord = *record; - autoshift_lastrecord.event.pressed = false; - autoshift_lastrecord.event.time = 0; - // clang-format off -# if defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY) - if (keycode == autoshift_lastkey && -# ifdef AUTO_SHIFT_REPEAT_PER_KEY - get_auto_shift_repeat(autoshift_lastkey, record) && -# endif -# if !defined(AUTO_SHIFT_NO_AUTO_REPEAT) || defined(AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY) - ( - !autoshift_flags.lastshifted -# ifdef AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY - || get_auto_shift_no_auto_repeat(autoshift_lastkey, record) -# endif - ) && -# endif - TIMER_DIFF_16(now, autoshift_time) < GET_TAPPING_TERM(autoshift_lastkey, record) - ) { - // clang-format on - // Allow a tap-then-hold for keyrepeat. - if (get_mods() & MOD_BIT(KC_LSFT)) { - autoshift_flags.cancelling_lshift = true; - del_mods(MOD_BIT(KC_LSFT)); - } - if (get_mods() & MOD_BIT(KC_RSFT)) { - autoshift_flags.cancelling_rshift = true; - del_mods(MOD_BIT(KC_RSFT)); - } - // autoshift_shift_state doesn't need to be changed. - autoshift_press_user(autoshift_lastkey, autoshift_flags.lastshifted, record); - return false; - } -# endif - - // Use physical shift state of press event to be more like normal typing. -# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - autoshift_flags.lastshifted = (get_mods() | get_oneshot_mods()) & MOD_BIT(KC_LSFT); - set_oneshot_mods(get_oneshot_mods() & (~MOD_BIT(KC_LSFT))); -# else - autoshift_flags.lastshifted = get_mods() & MOD_BIT(KC_LSFT); -# endif - // Record the keycode so we can simulate it later. - autoshift_lastkey = keycode; - autoshift_time = now; - autoshift_flags.in_progress = true; - -# if !defined(NO_ACTION_ONESHOT) && !defined(NO_ACTION_TAPPING) - clear_oneshot_layer_state(ONESHOT_OTHER_KEY_PRESSED); -# endif - return false; -} - -/** \brief Registers an autoshiftable key under the right conditions - * - * If autoshift_timeout has elapsed, register a shift and the key. - * - * If the Auto Shift key is released before the delay has elapsed, register the - * key without a shift. - * - * Called on key down with keycode=KC_NO, auto-shifted key up, and timeout. - */ -static void autoshift_end(uint16_t keycode, uint16_t now, bool matrix_trigger, keyrecord_t *record) { - if (autoshift_flags.in_progress && (keycode == autoshift_lastkey || keycode == KC_NO)) { - // Process the auto-shiftable key. - autoshift_flags.in_progress = false; - // clang-format off - autoshift_flags.lastshifted = - autoshift_flags.lastshifted - || TIMER_DIFF_16(now, autoshift_time) >= -# ifdef AUTO_SHIFT_TIMEOUT_PER_KEY - get_autoshift_timeout(autoshift_lastkey, record) -# else - autoshift_timeout -# endif - ; - // clang-format on - set_autoshift_shift_state(autoshift_lastkey, autoshift_flags.lastshifted); - if (get_mods() & MOD_BIT(KC_LSFT)) { - autoshift_flags.cancelling_lshift = true; - del_mods(MOD_BIT(KC_LSFT)); - } - if (get_mods() & MOD_BIT(KC_RSFT)) { - autoshift_flags.cancelling_rshift = true; - del_mods(MOD_BIT(KC_RSFT)); - } - autoshift_press_user(autoshift_lastkey, autoshift_flags.lastshifted, record); - - // clang-format off -# if (defined(AUTO_SHIFT_REPEAT) || defined(AUTO_SHIFT_REPEAT_PER_KEY)) && (!defined(AUTO_SHIFT_NO_AUTO_REPEAT) || defined(AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY)) - if (matrix_trigger -# ifdef AUTO_SHIFT_REPEAT_PER_KEY - && get_auto_shift_repeat(autoshift_lastkey, record) -# endif -# ifdef AUTO_SHIFT_NO_AUTO_REPEAT_PER_KEY - && !get_auto_shift_no_auto_repeat(autoshift_lastkey, record) -# endif - ) { - // Prevents release. - return; - } -# endif - // clang-format on -# if TAP_CODE_DELAY > 0 - wait_ms(TAP_CODE_DELAY); -# endif - - autoshift_release_user(autoshift_lastkey, autoshift_flags.lastshifted, record); - autoshift_flush_shift(); - } else { - // Release after keyrepeat. - autoshift_release_user(keycode, get_autoshift_shift_state(keycode), record); - if (keycode == autoshift_lastkey) { - // This will only fire when the key was the last auto-shiftable - // pressed. That prevents 'aaaaBBBB' then releasing a from unshifting - // later 'B's (if 'B' wasn't auto-shiftable). - autoshift_flush_shift(); - } - } - // Roll the autoshift_time forward for detecting tap-and-hold. - autoshift_time = now; -} - -/** \brief Simulates auto-shifted key releases when timeout is hit - * - * Can be called from \c matrix_scan_user so that auto-shifted keys are sent - * immediately after the timeout has expired, rather than waiting for the key - * to be released. - */ -void autoshift_matrix_scan(void) { - if (autoshift_flags.in_progress) { - const uint16_t now = timer_read(); - if (TIMER_DIFF_16(now, autoshift_time) >= -# ifdef AUTO_SHIFT_TIMEOUT_PER_KEY - get_autoshift_timeout(autoshift_lastkey, &autoshift_lastrecord) -# else - autoshift_timeout -# endif - ) { - autoshift_end(autoshift_lastkey, now, true, &autoshift_lastrecord); - } - } -} - -void autoshift_toggle(void) { - autoshift_flags.enabled = !autoshift_flags.enabled; - autoshift_flush_shift(); -} - -void autoshift_enable(void) { - autoshift_flags.enabled = true; -} - -void autoshift_disable(void) { - autoshift_flags.enabled = false; - autoshift_flush_shift(); -} - -# ifndef AUTO_SHIFT_NO_SETUP -void autoshift_timer_report(void) { -# ifdef SEND_STRING_ENABLE - const char *autoshift_timeout_str = get_u16_str(autoshift_timeout, ' '); - // Skip padding spaces - while (*autoshift_timeout_str == ' ') { - autoshift_timeout_str++; - } - send_string(autoshift_timeout_str); -# endif -} -# endif - -bool get_autoshift_state(void) { - return autoshift_flags.enabled; -} - -uint16_t get_generic_autoshift_timeout(void) { - return autoshift_timeout; -} -__attribute__((weak)) uint16_t get_autoshift_timeout(uint16_t keycode, keyrecord_t *record) { - return autoshift_timeout; -} - -void set_autoshift_timeout(uint16_t timeout) { - autoshift_timeout = timeout; -} - -bool process_auto_shift(uint16_t keycode, keyrecord_t *record) { - // Note that record->event.time isn't reliable, see: - // https://github.com/qmk/qmk_firmware/pull/9826#issuecomment-733559550 - // clang-format off - const uint16_t now = -# if !defined(RETRO_SHIFT) || defined(NO_ACTION_TAPPING) - timer_read() -# else - (record->event.pressed) ? retroshift_time : timer_read() -# endif - ; - // clang-format on - - if (record->event.pressed) { - if (autoshift_flags.in_progress) { - // Evaluate previous key if there is one. - autoshift_end(KC_NO, now, false, &autoshift_lastrecord); - } - - switch (keycode) { - case AS_TOGG: - autoshift_toggle(); - break; - case AS_ON: - autoshift_enable(); - break; - case AS_OFF: - autoshift_disable(); - break; - -# ifndef AUTO_SHIFT_NO_SETUP - case AS_UP: - autoshift_timeout += 5; - break; - case AS_DOWN: - autoshift_timeout -= 5; - break; - case AS_RPT: - autoshift_timer_report(); - break; -# endif - } - // If Retro Shift is disabled, possible custom actions shouldn't happen. - // clang-format off -# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - const bool is_hold_on_interrupt = get_hold_on_other_key_press(keycode, record); -# else - const bool is_hold_on_interrupt = false; -# endif -# endif - if (IS_RETRO(keycode) -# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) - // Not tapped or #defines mean that rolls should use hold action. - && ( - record->tap.count == 0 -# ifdef RETRO_TAPPING_PER_KEY - || !get_retro_tapping(keycode, record) -# endif - || (record->tap.interrupted && is_hold_on_interrupt)) -# endif - ) { - // clang-format on - autoshift_lastkey = KC_NO; - return true; - } - } else { - if (keycode == KC_LSFT) { - autoshift_flags.cancelling_lshift = false; - } else if (keycode == KC_RSFT) { - autoshift_flags.cancelling_rshift = false; - } - // Same as above (for pressed), additional checks are not needed because - // tap.count gets set to 0 in process_action - // clang-format off - else if (IS_RETRO(keycode) -# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) - && ( - record->tap.count == 0 -# ifdef RETRO_TAPPING_PER_KEY - || !get_retro_tapping(keycode, record) -# endif - ) -# endif - ) { - // Fixes modifiers not being applied to rolls with AUTO_SHIFT_MODIFIERS set. -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - if (autoshift_flags.in_progress && get_hold_on_other_key_press(keycode, record)) { - autoshift_end(KC_NO, now, false, &autoshift_lastrecord); - } -# endif - // clang-format on - return true; - } - } - - if (!autoshift_flags.enabled) { - return true; - } - if (get_auto_shifted_key(keycode, record)) { - if (record->event.pressed) { - return autoshift_press(keycode, now, record); - } else { - autoshift_end(keycode, now, false, record); - return false; - } - } - - // Prevent keyrepeating of older keys upon non-AS key event. - // Not commented at above returns but they serve the same function. - if (record->event.pressed) { - autoshift_lastkey = KC_NO; - } - return true; -} - -# if defined(RETRO_SHIFT) && !defined(NO_ACTION_TAPPING) -// Called to record time before possible delays by action_tapping_process. -void retroshift_poll_time(keyevent_t *event) { - last_retroshift_time = retroshift_time; - retroshift_time = timer_read(); -} -// Used to swap the times of Retro Shifted key and Auto Shift key that interrupted it. -void retroshift_swap_times(void) { - if (last_retroshift_time != 0 && autoshift_flags.in_progress) { - uint16_t temp = retroshift_time; - retroshift_time = last_retroshift_time; - last_retroshift_time = temp; - } -} -# endif - -#endif diff --git a/quantum/process_keycode/process_auto_shift.h b/quantum/process_keycode/process_auto_shift.h deleted file mode 100644 index 66a4b3138a39..000000000000 --- a/quantum/process_keycode/process_auto_shift.h +++ /dev/null @@ -1,51 +0,0 @@ -/* Copyright 2017 Jeremy Cowgar - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -#ifndef AUTO_SHIFT_TIMEOUT -# define AUTO_SHIFT_TIMEOUT 175 -#endif - -#define IS_RETRO(kc) (IS_QK_MOD_TAP(kc) || IS_QK_LAYER_TAP(kc)) - -#define DO_GET_AUTOSHIFT_TIMEOUT(keycode, record, ...) record -// clang-format off -#define AUTO_SHIFT_ALPHA KC_A ... KC_Z -#define AUTO_SHIFT_NUMERIC KC_1 ... KC_0 -#define AUTO_SHIFT_SPECIAL \ - KC_TAB: \ - case KC_MINUS ... KC_SLASH: \ - case KC_NONUS_BACKSLASH -// clang-format on - -bool process_auto_shift(uint16_t keycode, keyrecord_t *record); -void retroshift_poll_time(keyevent_t *event); -void retroshift_swap_times(void); - -void autoshift_enable(void); -void autoshift_disable(void); -void autoshift_toggle(void); -bool get_autoshift_state(void); -uint16_t get_generic_autoshift_timeout(void); -// clang-format off -uint16_t (get_autoshift_timeout)(uint16_t keycode, keyrecord_t *record); -void set_autoshift_timeout(uint16_t timeout); -void autoshift_matrix_scan(void); -bool get_custom_auto_shifted_key(uint16_t keycode, keyrecord_t *record); -// clang-format on diff --git a/quantum/process_keycode/process_autocorrect.c b/quantum/process_keycode/process_autocorrect.c index 137678826646..7c9cb814e592 100644 --- a/quantum/process_keycode/process_autocorrect.c +++ b/quantum/process_keycode/process_autocorrect.c @@ -57,7 +57,7 @@ void autocorrect_toggle(void) { } /** - * @brief handler for determining if autocorrect should process keypress + * @brief handler for user to override whether autocorrect should process this keypress * * @param keycode Keycode registered by matrix press, per keymap * @param record keyrecord_t structure @@ -67,6 +67,23 @@ void autocorrect_toggle(void) { * @return false Stop processing and escape from autocorrect. */ __attribute__((weak)) bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) { + return process_autocorrect_default_handler(keycode, record, typo_buffer_size, mods); +} + +/** + * @brief fallback handler for determining if autocorrect should process this keypress + * can be used by user callback to get the basic keycode being "wrapped" + * + * NOTE: These values may have been edited by user callback before getting here + * + * @param keycode Keycode registered by matrix press, per keymap + * @param record keyrecord_t structure + * @param typo_buffer_size passed along to allow resetting of autocorrect buffer + * @param mods allow processing of mod status + * @return true Allow autocorection + * @return false Stop processing and escape from autocorrect. + */ +bool process_autocorrect_default_handler(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods) { // See quantum_keycodes.h for reference on these matched ranges. switch (*keycode) { // Exclude these keycodes from processing. diff --git a/quantum/process_keycode/process_autocorrect.h b/quantum/process_keycode/process_autocorrect.h index c7596107e505..00dacbf958bd 100644 --- a/quantum/process_keycode/process_autocorrect.h +++ b/quantum/process_keycode/process_autocorrect.h @@ -9,6 +9,7 @@ bool process_autocorrect(uint16_t keycode, keyrecord_t *record); bool process_autocorrect_user(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods); +bool process_autocorrect_default_handler(uint16_t *keycode, keyrecord_t *record, uint8_t *typo_buffer_size, uint8_t *mods); bool apply_autocorrect(uint8_t backspaces, const char *str); bool autocorrect_is_enabled(void); diff --git a/quantum/process_keycode/process_backlight.c b/quantum/process_keycode/process_backlight.c deleted file mode 100644 index c1596ec07d18..000000000000 --- a/quantum/process_keycode/process_backlight.c +++ /dev/null @@ -1,76 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -#include "process_backlight.h" - -#ifdef LED_MATRIX_ENABLE -# include "led_matrix.h" -#else -# include "backlight.h" -#endif - -bool process_backlight(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - switch (keycode) { -#ifdef LED_MATRIX_ENABLE - case QK_BACKLIGHT_ON: - led_matrix_enable(); - return false; - case QK_BACKLIGHT_OFF: - led_matrix_disable(); - return false; - case QK_BACKLIGHT_DOWN: - led_matrix_decrease_val(); - return false; - case QK_BACKLIGHT_UP: - led_matrix_increase_val(); - return false; - case QK_BACKLIGHT_TOGGLE: - led_matrix_toggle(); - return false; - case QK_BACKLIGHT_STEP: - led_matrix_step(); - return false; -#else - case QK_BACKLIGHT_ON: - backlight_level(BACKLIGHT_LEVELS); - return false; - case QK_BACKLIGHT_OFF: - backlight_level(0); - return false; - case QK_BACKLIGHT_DOWN: - backlight_decrease(); - return false; - case QK_BACKLIGHT_UP: - backlight_increase(); - return false; - case QK_BACKLIGHT_TOGGLE: - backlight_toggle(); - return false; - case QK_BACKLIGHT_STEP: - backlight_step(); - return false; -# ifdef BACKLIGHT_BREATHING - case QK_BACKLIGHT_TOGGLE_BREATHING: - backlight_toggle_breathing(); - return false; -# endif -#endif - } - } - - return true; -} diff --git a/quantum/process_keycode/process_backlight.h b/quantum/process_keycode/process_backlight.h deleted file mode 100644 index 7fe887ae6752..000000000000 --- a/quantum/process_keycode/process_backlight.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -bool process_backlight(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_caps_word.c b/quantum/process_keycode/process_caps_word.c deleted file mode 100644 index d4382680bf47..000000000000 --- a/quantum/process_keycode/process_caps_word.c +++ /dev/null @@ -1,260 +0,0 @@ -// Copyright 2021-2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "process_caps_word.h" - -#ifdef CAPS_WORD_INVERT_ON_SHIFT -static uint8_t held_mods = 0; - -static bool handle_shift(uint16_t keycode, keyrecord_t* record) { - switch (keycode) { - case OSM(MOD_LSFT): - keycode = KC_LSFT; - break; - case OSM(MOD_RSFT): - keycode = KC_RSFT; - break; - -# ifndef NO_ACTION_TAPPING - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - if (record->tap.count == 0) { // Mod-tap key is held. - switch (QK_MOD_TAP_GET_MODS(keycode)) { - case MOD_LSFT: - keycode = KC_LSFT; - break; - case MOD_RSFT: - keycode = KC_RSFT; - break; - } - } -# endif // NO_ACTION_TAPPING - } - - if (keycode == KC_LSFT || keycode == KC_RSFT) { - const uint8_t mod = MOD_BIT(keycode); - - if (is_caps_word_on()) { - if (record->event.pressed) { - held_mods |= mod; - } else { - held_mods &= ~mod; - } - return false; - } else if ((held_mods & mod) != 0) { - held_mods &= ~mod; - del_mods(mod); - return record->event.pressed; - } - } - - return true; -} -#endif // CAPS_WORD_INVERT_ON_SHIFT - -bool process_caps_word(uint16_t keycode, keyrecord_t* record) { - if (keycode == QK_CAPS_WORD_TOGGLE) { - if (record->event.pressed) { - caps_word_toggle(); - } - return false; - } -#ifdef CAPS_WORD_INVERT_ON_SHIFT - if (!handle_shift(keycode, record)) { - return false; - } -#endif // CAPS_WORD_INVERT_ON_SHIFT - -#ifndef NO_ACTION_ONESHOT - const uint8_t mods = get_mods() | get_oneshot_mods(); -#else - const uint8_t mods = get_mods(); -#endif // NO_ACTION_ONESHOT - - if (!is_caps_word_on()) { - // The following optionally turns on Caps Word by holding left and - // right shifts or by double tapping left shift. This way Caps Word - // may be used without needing a dedicated key and also without - // needing combos or tap dance. - -#ifdef BOTH_SHIFTS_TURNS_ON_CAPS_WORD - // Many keyboards enable the Command feature by default, which also - // uses left+right shift. It can be configured to use a different - // key combination by defining IS_COMMAND(). We make a non-fatal - // warning if Command is enabled but IS_COMMAND() is *not* defined. -# if defined(COMMAND_ENABLE) && !defined(IS_COMMAND) -# pragma message "BOTH_SHIFTS_TURNS_ON_CAPS_WORD and Command should not be enabled at the same time, since both use the Left Shift + Right Shift key combination. Please disable Command, or ensure that `IS_COMMAND` is not set to (get_mods() == MOD_MASK_SHIFT)." -# else - if (mods == MOD_MASK_SHIFT -# ifdef COMMAND_ENABLE - // Don't activate Caps Word at the same time as Command. - && !(IS_COMMAND()) -# endif // COMMAND_ENABLE - ) { - caps_word_on(); - } -# endif // defined(COMMAND_ENABLE) && !defined(IS_COMMAND) -#endif // BOTH_SHIFTS_TURNS_ON_CAPS_WORD - -#ifdef DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD - // Double tapping left shift turns on Caps Word. - // - // NOTE: This works with KC_LSFT and one-shot left shift. It - // wouldn't make sense with mod-tap or Space Cadet shift since - // double tapping would of course trigger the tapping action. - if (record->event.pressed) { - static bool tapped = false; - static uint16_t timer = 0; - if (keycode == KC_LSFT || keycode == OSM(MOD_LSFT)) { - if (tapped && !timer_expired(record->event.time, timer)) { - // Left shift was double tapped, activate Caps Word. - caps_word_on(); - } - tapped = true; - timer = record->event.time + GET_TAPPING_TERM(keycode, record); - } else { - tapped = false; // Reset when any other key is pressed. - } - } -#endif // DOUBLE_TAP_SHIFT_TURNS_ON_CAPS_WORD - - return true; - } - -#if CAPS_WORD_IDLE_TIMEOUT > 0 - caps_word_reset_idle_timer(); -#endif // CAPS_WORD_IDLE_TIMEOUT > 0 - - // From here on, we only take action on press events. - if (!record->event.pressed) { - return true; - } - - if (!(mods & ~(MOD_MASK_SHIFT | MOD_BIT(KC_RALT)))) { - switch (keycode) { - // Ignore MO, TO, TG, TT, and OSL layer switch keys. - case QK_MOMENTARY ... QK_MOMENTARY_MAX: - case QK_TO ... QK_TO_MAX: - case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: - case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: - case QK_TRI_LAYER_LOWER ... QK_TRI_LAYER_UPPER: - // Ignore AltGr. - case KC_RALT: - case OSM(MOD_RALT): - return true; - -#ifndef NO_ACTION_TAPPING - // Corresponding to mod keys above, a held mod-tap is handled as: - // * For shift mods, pass KC_LSFT or KC_RSFT to - // caps_word_press_user() to determine whether to continue. - // * For Shift + AltGr (MOD_RSFT | MOD_RALT), pass RSFT(KC_RALT). - // * AltGr (MOD_RALT) is ignored. - // * Otherwise stop Caps Word. - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - if (record->tap.count == 0) { // Mod-tap key is held. - const uint8_t mods = QK_MOD_TAP_GET_MODS(keycode); - switch (mods) { -# ifndef CAPS_WORD_INVERT_ON_SHIFT - case MOD_LSFT: - keycode = KC_LSFT; - break; - case MOD_RSFT: - keycode = KC_RSFT; - break; -# endif // CAPS_WORD_INVERT_ON_SHIFT - case MOD_RSFT | MOD_RALT: - keycode = RSFT(KC_RALT); - break; - case MOD_RALT: - return true; - default: - caps_word_off(); -# ifdef CAPS_WORD_INVERT_ON_SHIFT - add_mods(held_mods); -# endif // CAPS_WORD_INVERT_ON_SHIFT - return true; - } - } else { - keycode = QK_MOD_TAP_GET_TAP_KEYCODE(keycode); - } - break; - -# ifndef NO_ACTION_LAYER - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: -# endif // NO_ACTION_LAYER - if (record->tap.count == 0) { - return true; - } - keycode = QK_LAYER_TAP_GET_TAP_KEYCODE(keycode); - break; -#endif // NO_ACTION_TAPPING - -#ifdef SWAP_HANDS_ENABLE - case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: - // Note: IS_SWAP_HANDS_KEYCODE() actually tests for the special action keycodes like SH_TOGG, SH_TT, ..., - // which currently overlap the SH_T(kc) range. - if (IS_SWAP_HANDS_KEYCODE(keycode) -# ifndef NO_ACTION_TAPPING - || record->tap.count == 0 -# endif // NO_ACTION_TAPPING - ) { - return true; - } - keycode = QK_SWAP_HANDS_GET_TAP_KEYCODE(keycode); - break; -#endif // SWAP_HANDS_ENABLE - } - -#ifdef AUTO_SHIFT_ENABLE - del_weak_mods(get_autoshift_state() ? ~MOD_BIT(KC_LSFT) : 0xff); -#else - clear_weak_mods(); -#endif // AUTO_SHIFT_ENABLE - if (caps_word_press_user(keycode)) { -#ifdef CAPS_WORD_INVERT_ON_SHIFT - if (held_mods) { - set_weak_mods(get_weak_mods() ^ MOD_BIT(KC_LSFT)); - } -#endif // CAPS_WORD_INVERT_ON_SHIFT - send_keyboard_report(); - return true; - } - } - - caps_word_off(); -#ifdef CAPS_WORD_INVERT_ON_SHIFT - add_mods(held_mods); -#endif // CAPS_WORD_INVERT_ON_SHIFT - return true; -} - -__attribute__((weak)) bool caps_word_press_user(uint16_t keycode) { - switch (keycode) { - // Keycodes that continue Caps Word, with shift applied. - case KC_A ... KC_Z: - case KC_MINS: - add_weak_mods(MOD_BIT(KC_LSFT)); // Apply shift to next key. - return true; - - // Keycodes that continue Caps Word, without shifting. - case KC_1 ... KC_0: - case KC_BSPC: - case KC_DEL: - case KC_UNDS: - return true; - - default: - return false; // Deactivate Caps Word. - } -} diff --git a/quantum/process_keycode/process_caps_word.h b/quantum/process_keycode/process_caps_word.h deleted file mode 100644 index f215bbc3a3df..000000000000 --- a/quantum/process_keycode/process_caps_word.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2021-2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "quantum.h" -#include "caps_word.h" - -/** - * @brief Process handler for Caps Word feature. - * - * @param keycode Keycode registered by matrix press, per keymap - * @param record keyrecord_t structure - * @return true Continue processing keycodes, and send to host - * @return false Stop processing keycodes, and don't send to host - */ -bool process_caps_word(uint16_t keycode, keyrecord_t* record); - -/** - * @brief Weak function for user-level Caps Word press modification. - * - * @param keycode Keycode registered by matrix press, per keymap - * @return true Continue Caps Word - * @return false Stop Caps Word - */ -bool caps_word_press_user(uint16_t keycode); diff --git a/quantum/process_keycode/process_clicky.c b/quantum/process_keycode/process_clicky.c deleted file mode 100644 index b662a3f2f4d1..000000000000 --- a/quantum/process_keycode/process_clicky.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "audio.h" -#include "process_clicky.h" - -#ifdef AUDIO_CLICKY - -# ifndef AUDIO_CLICKY_DELAY_DURATION -# define AUDIO_CLICKY_DELAY_DURATION 1 -# endif // !AUDIO_CLICKY_DELAY_DURATION -# ifndef AUDIO_CLICKY_FREQ_DEFAULT -# define AUDIO_CLICKY_FREQ_DEFAULT 440.0f -# endif // !AUDIO_CLICKY_FREQ_DEFAULT -# ifndef AUDIO_CLICKY_FREQ_MIN -# define AUDIO_CLICKY_FREQ_MIN 65.0f -# endif // !AUDIO_CLICKY_FREQ_MIN -# ifndef AUDIO_CLICKY_FREQ_MAX -# define AUDIO_CLICKY_FREQ_MAX 1500.0f -# endif // !AUDIO_CLICKY_FREQ_MAX -# ifndef AUDIO_CLICKY_FREQ_FACTOR -# define AUDIO_CLICKY_FREQ_FACTOR 1.18921f -# endif // !AUDIO_CLICKY_FREQ_FACTOR -# ifndef AUDIO_CLICKY_FREQ_RANDOMNESS -# define AUDIO_CLICKY_FREQ_RANDOMNESS 0.05f -# endif // !AUDIO_CLICKY_FREQ_RANDOMNESS - -float clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; -float clicky_rand = AUDIO_CLICKY_FREQ_RANDOMNESS; - -// the first "note" is an intentional delay; the 2nd and 3rd notes are the "clicky" -float clicky_song[][2] = {{AUDIO_CLICKY_FREQ_MIN, AUDIO_CLICKY_DELAY_DURATION}, {AUDIO_CLICKY_FREQ_DEFAULT, 3}, {AUDIO_CLICKY_FREQ_DEFAULT, 1}}; // 3 and 1 --> durations - -extern audio_config_t audio_config; - -# ifndef NO_MUSIC_MODE -extern bool music_activated; -extern bool midi_activated; -# endif // !NO_MUSIC_MODE - -void clicky_play(void) { -# ifndef NO_MUSIC_MODE - if (music_activated || midi_activated || !audio_config.enable) return; -# endif // !NO_MUSIC_MODE - clicky_song[1][0] = 2.0f * clicky_freq * (1.0f + clicky_rand * (((float)rand()) / ((float)(RAND_MAX)))); - clicky_song[2][0] = clicky_freq * (1.0f + clicky_rand * (((float)rand()) / ((float)(RAND_MAX)))); - PLAY_SONG(clicky_song); -} - -void clicky_freq_up(void) { - float new_freq = clicky_freq * AUDIO_CLICKY_FREQ_FACTOR; - if (new_freq < AUDIO_CLICKY_FREQ_MAX) { - clicky_freq = new_freq; - } -} - -void clicky_freq_down(void) { - float new_freq = clicky_freq / AUDIO_CLICKY_FREQ_FACTOR; - if (new_freq > AUDIO_CLICKY_FREQ_MIN) { - clicky_freq = new_freq; - } -} - -void clicky_freq_reset(void) { - clicky_freq = AUDIO_CLICKY_FREQ_DEFAULT; -} - -void clicky_toggle(void) { - audio_config.clicky_enable ^= 1; - eeconfig_update_audio(audio_config.raw); -} - -void clicky_on(void) { - audio_config.clicky_enable = 1; - eeconfig_update_audio(audio_config.raw); -} - -void clicky_off(void) { - audio_config.clicky_enable = 0; - eeconfig_update_audio(audio_config.raw); -} - -bool is_clicky_on(void) { - return (audio_config.clicky_enable != 0); -} - -bool process_clicky(uint16_t keycode, keyrecord_t *record) { - if (keycode == QK_AUDIO_CLICKY_TOGGLE && record->event.pressed) { - clicky_toggle(); - } - - if (keycode == QK_AUDIO_CLICKY_ON && record->event.pressed) { - clicky_on(); - } - if (keycode == QK_AUDIO_CLICKY_OFF && record->event.pressed) { - clicky_off(); - } - - if (keycode == QK_AUDIO_CLICKY_RESET && record->event.pressed) { - clicky_freq_reset(); - } - - if (keycode == QK_AUDIO_CLICKY_UP && record->event.pressed) { - clicky_freq_up(); - } - if (keycode == QK_AUDIO_CLICKY_DOWN && record->event.pressed) { - clicky_freq_down(); - } - - if (audio_config.enable && audio_config.clicky_enable) { - if (record->event.pressed) { // Leave this separate so it's easier to add upstroke sound - if (keycode != QK_AUDIO_ON && keycode != QK_AUDIO_OFF) { // DO NOT PLAY if audio will be disabled, and causes issuse on ARM - clicky_play(); - } - } - } - return true; -} - -#endif // AUDIO_CLICKY diff --git a/quantum/process_keycode/process_clicky.h b/quantum/process_keycode/process_clicky.h deleted file mode 100644 index 67b6463c5d4d..000000000000 --- a/quantum/process_keycode/process_clicky.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -void clicky_play(void); -bool process_clicky(uint16_t keycode, keyrecord_t *record); - -void clicky_freq_up(void); -void clicky_freq_down(void); -void clicky_freq_reset(void); - -void clicky_toggle(void); -void clicky_on(void); -void clicky_off(void); - -bool is_clicky_on(void); diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c deleted file mode 100644 index bbee560be9cc..000000000000 --- a/quantum/process_keycode/process_combo.c +++ /dev/null @@ -1,646 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#include "keymap_common.h" -#include "print.h" -#include "process_combo.h" -#include "action_tapping.h" -#include "action.h" -#include "keymap_introspection.h" - -__attribute__((weak)) void process_combo_event(uint16_t combo_index, bool pressed) {} - -#ifndef COMBO_ONLY_FROM_LAYER -__attribute__((weak)) uint8_t combo_ref_from_layer(uint8_t layer) { - return layer; -} -#endif - -#ifdef COMBO_MUST_HOLD_PER_COMBO -__attribute__((weak)) bool get_combo_must_hold(uint16_t index, combo_t *combo) { - return false; -} -#endif - -#ifdef COMBO_MUST_TAP_PER_COMBO -__attribute__((weak)) bool get_combo_must_tap(uint16_t index, combo_t *combo) { - return false; -} -#endif - -#ifdef COMBO_TERM_PER_COMBO -__attribute__((weak)) uint16_t get_combo_term(uint16_t index, combo_t *combo) { - return COMBO_TERM; -} -#endif - -#ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO -__attribute__((weak)) bool get_combo_must_press_in_order(uint16_t combo_index, combo_t *combo) { - return true; -} -#endif - -#ifdef COMBO_PROCESS_KEY_RELEASE -__attribute__((weak)) bool process_combo_key_release(uint16_t combo_index, combo_t *combo, uint8_t key_index, uint16_t keycode) { - return false; -} -#endif - -#ifdef COMBO_SHOULD_TRIGGER -__attribute__((weak)) bool combo_should_trigger(uint16_t combo_index, combo_t *combo, uint16_t keycode, keyrecord_t *record) { - return true; -} -#endif - -#ifndef COMBO_NO_TIMER -static uint16_t timer = 0; -#endif -static bool b_combo_enable = true; // defaults to enabled -static uint16_t longest_term = 0; - -typedef struct { - keyrecord_t record; - uint16_t combo_index; - uint16_t keycode; -} queued_record_t; -static uint8_t key_buffer_size = 0; -static queued_record_t key_buffer[COMBO_KEY_BUFFER_LENGTH]; - -typedef struct { - uint16_t combo_index; -} queued_combo_t; -static uint8_t combo_buffer_write = 0; -static uint8_t combo_buffer_read = 0; -static queued_combo_t combo_buffer[COMBO_BUFFER_LENGTH]; - -#define INCREMENT_MOD(i) i = (i + 1) % COMBO_BUFFER_LENGTH - -#ifndef EXTRA_SHORT_COMBOS -/* flags are their own elements in combo_t struct. */ -# define COMBO_ACTIVE(combo) (combo->active) -# define COMBO_DISABLED(combo) (combo->disabled) -# define COMBO_STATE(combo) (combo->state) - -# define ACTIVATE_COMBO(combo) \ - do { \ - combo->active = true; \ - } while (0) -# define DEACTIVATE_COMBO(combo) \ - do { \ - combo->active = false; \ - } while (0) -# define DISABLE_COMBO(combo) \ - do { \ - combo->disabled = true; \ - } while (0) -# define RESET_COMBO_STATE(combo) \ - do { \ - combo->disabled = false; \ - combo->state = 0; \ - } while (0) -#else -/* flags are at the two high bits of state. */ -# define COMBO_ACTIVE(combo) (combo->state & 0x80) -# define COMBO_DISABLED(combo) (combo->state & 0x40) -# define COMBO_STATE(combo) (combo->state & 0x3F) - -# define ACTIVATE_COMBO(combo) \ - do { \ - combo->state |= 0x80; \ - } while (0) -# define DEACTIVATE_COMBO(combo) \ - do { \ - combo->state &= ~0x80; \ - } while (0) -# define DISABLE_COMBO(combo) \ - do { \ - combo->state |= 0x40; \ - } while (0) -# define RESET_COMBO_STATE(combo) \ - do { \ - combo->state &= ~0x7F; \ - } while (0) -#endif - -static inline void release_combo(uint16_t combo_index, combo_t *combo) { - if (combo->keycode) { - keyrecord_t record = { - .event = MAKE_COMBOEVENT(false), - .keycode = combo->keycode, - }; -#ifndef NO_ACTION_TAPPING - action_tapping_process(record); -#else - process_record(&record); -#endif - } else { - process_combo_event(combo_index, false); - } - DEACTIVATE_COMBO(combo); -} - -static inline bool _get_combo_must_hold(uint16_t combo_index, combo_t *combo) { -#ifdef COMBO_NO_TIMER - return false; -#elif defined(COMBO_MUST_HOLD_PER_COMBO) - return get_combo_must_hold(combo_index, combo); -#elif defined(COMBO_MUST_HOLD_MODS) - return (KEYCODE_IS_MOD(combo->keycode) || (combo->keycode >= QK_MOMENTARY && combo->keycode <= QK_MOMENTARY_MAX)); -#endif - return false; -} - -static inline uint16_t _get_wait_time(uint16_t combo_index, combo_t *combo) { - if (_get_combo_must_hold(combo_index, combo) -#ifdef COMBO_MUST_TAP_PER_COMBO - || get_combo_must_tap(combo_index, combo) -#endif - ) { - if (longest_term < COMBO_HOLD_TERM) { - return COMBO_HOLD_TERM; - } - } - - return longest_term; -} - -static inline uint16_t _get_combo_term(uint16_t combo_index, combo_t *combo) { -#if defined(COMBO_TERM_PER_COMBO) - return get_combo_term(combo_index, combo); -#endif - - return COMBO_TERM; -} - -void clear_combos(void) { - uint16_t index = 0; - longest_term = 0; - for (index = 0; index < combo_count(); ++index) { - combo_t *combo = combo_get(index); - if (!COMBO_ACTIVE(combo)) { - RESET_COMBO_STATE(combo); - } - } -} - -static inline void dump_key_buffer(void) { - /* First call start from 0 index; recursive calls need to start from i+1 index */ - static uint8_t key_buffer_next = 0; -#if TAP_CODE_DELAY > 0 - bool delay_done = false; -#endif - - if (key_buffer_size == 0) { - return; - } - - for (uint8_t key_buffer_i = key_buffer_next; key_buffer_i < key_buffer_size; key_buffer_i++) { - key_buffer_next = key_buffer_i + 1; - - queued_record_t *qrecord = &key_buffer[key_buffer_i]; - keyrecord_t * record = &qrecord->record; - - if (IS_NOEVENT(record->event)) { - continue; - } - - if (!record->keycode && qrecord->combo_index != (uint16_t)-1) { - process_combo_event(qrecord->combo_index, true); - } else { -#ifndef NO_ACTION_TAPPING - action_tapping_process(*record); -#else - process_record(record); -#endif - } - record->event.type = TICK_EVENT; - -#if defined(CAPS_WORD_ENABLE) && defined(AUTO_SHIFT_ENABLE) - // Edge case: preserve the weak Left Shift mod if both Caps Word and - // Auto Shift are on. Caps Word capitalizes by setting the weak Left - // Shift mod during the press event, but Auto Shift doesn't send the - // key until it receives the release event. - del_weak_mods((is_caps_word_on() && get_autoshift_state()) ? ~MOD_BIT(KC_LSFT) : 0xff); -#else - clear_weak_mods(); -#endif // defined(CAPS_WORD_ENABLE) && defined(AUTO_SHIFT_ENABLE) - -#if TAP_CODE_DELAY > 0 - // only delay once and for a non-tapping key - if (!delay_done && !is_tap_record(record)) { - delay_done = true; - wait_ms(TAP_CODE_DELAY); - } -#endif - } - - key_buffer_next = key_buffer_size = 0; -} - -#define NO_COMBO_KEYS_ARE_DOWN (0 == COMBO_STATE(combo)) -#define ALL_COMBO_KEYS_ARE_DOWN(state, key_count) (((1 << key_count) - 1) == state) -#define ONLY_ONE_KEY_IS_DOWN(state) !(state & (state - 1)) -#define KEY_NOT_YET_RELEASED(state, key_index) ((1 << key_index) & state) -#define KEY_STATE_DOWN(state, key_index) \ - do { \ - state |= (1 << key_index); \ - } while (0) -#define KEY_STATE_UP(state, key_index) \ - do { \ - state &= ~(1 << key_index); \ - } while (0) - -static inline void _find_key_index_and_count(const uint16_t *keys, uint16_t keycode, uint16_t *key_index, uint8_t *key_count) { - while (true) { - uint16_t key = pgm_read_word(&keys[*key_count]); - if (keycode == key) *key_index = *key_count; - if (COMBO_END == key) break; - (*key_count)++; - } -} - -void drop_combo_from_buffer(uint16_t combo_index) { - /* Mark a combo as processed from the buffer. If the buffer is in the - * beginning of the buffer, drop it. */ - uint8_t i = combo_buffer_read; - while (i != combo_buffer_write) { - queued_combo_t *qcombo = &combo_buffer[i]; - - if (qcombo->combo_index == combo_index) { - combo_t *combo = combo_get(combo_index); - DISABLE_COMBO(combo); - - if (i == combo_buffer_read) { - INCREMENT_MOD(combo_buffer_read); - } - break; - } - INCREMENT_MOD(i); - } -} - -void apply_combo(uint16_t combo_index, combo_t *combo) { - /* Apply combo's result keycode to the last chord key of the combo and - * disable the other keys. */ - - if (COMBO_DISABLED(combo)) { - return; - } - - // state to check against so we find the last key of the combo from the buffer -#if defined(EXTRA_EXTRA_LONG_COMBOS) - uint32_t state = 0; -#elif defined(EXTRA_LONG_COMBOS) - uint16_t state = 0; -#else - uint8_t state = 0; -#endif - - for (uint8_t key_buffer_i = 0; key_buffer_i < key_buffer_size; key_buffer_i++) { - queued_record_t *qrecord = &key_buffer[key_buffer_i]; - keyrecord_t * record = &qrecord->record; - uint16_t keycode = qrecord->keycode; - - uint8_t key_count = 0; - uint16_t key_index = -1; - _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); - - if (-1 == (int16_t)key_index) { - // key not part of this combo - continue; - } - - KEY_STATE_DOWN(state, key_index); - if (ALL_COMBO_KEYS_ARE_DOWN(state, key_count)) { - // this in the end executes the combo when the key_buffer is dumped. - record->keycode = combo->keycode; - record->event.type = COMBO_EVENT; - record->event.key = MAKE_KEYPOS(0, 0); - - qrecord->combo_index = combo_index; - ACTIVATE_COMBO(combo); - - break; - } else { - // key was part of the combo but not the last one, "disable" it - // by making it a TICK event. - record->event.type = TICK_EVENT; - } - } - drop_combo_from_buffer(combo_index); -} - -static inline void apply_combos(void) { - // Apply all buffered normal combos. - for (uint8_t i = combo_buffer_read; i != combo_buffer_write; INCREMENT_MOD(i)) { - queued_combo_t *buffered_combo = &combo_buffer[i]; - combo_t * combo = combo_get(buffered_combo->combo_index); - -#ifdef COMBO_MUST_TAP_PER_COMBO - if (get_combo_must_tap(buffered_combo->combo_index, combo)) { - // Tap-only combos are applied on key release only, so let's drop 'em here. - drop_combo_from_buffer(buffered_combo->combo_index); - continue; - } -#endif - apply_combo(buffered_combo->combo_index, combo); - } - dump_key_buffer(); - clear_combos(); -} - -combo_t *overlaps(combo_t *combo1, combo_t *combo2) { - /* Checks if the combos overlap and returns the combo that should be - * dropped from the combo buffer. - * The combo that has less keys will be dropped. If they have the same - * amount of keys, drop combo1. */ - - uint8_t idx1 = 0, idx2 = 0; - uint16_t key1, key2; - bool overlaps = false; - - while ((key1 = pgm_read_word(&combo1->keys[idx1])) != COMBO_END) { - idx2 = 0; - while ((key2 = pgm_read_word(&combo2->keys[idx2])) != COMBO_END) { - if (key1 == key2) overlaps = true; - idx2 += 1; - } - idx1 += 1; - } - - if (!overlaps) return NULL; - if (idx2 < idx1) return combo2; - return combo1; -} - -#if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) -static bool keys_pressed_in_order(uint16_t combo_index, combo_t *combo, uint16_t key_index, uint16_t keycode, keyrecord_t *record) { -# ifdef COMBO_MUST_PRESS_IN_ORDER_PER_COMBO - if (!get_combo_must_press_in_order(combo_index, combo)) { - return true; - } -# endif - if ( - // The `state` bit for the key being pressed. - (1 << key_index) == - // The *next* combo key's bit. - (COMBO_STATE(combo) + 1) - // E.g. two keys already pressed: `state == 11`. - // Next possible `state` is `111`. - // So the needed bit is `100` which we get with `11 + 1`. - ) { - return true; - } - return false; -} -#endif - -static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record, uint16_t combo_index) { - uint8_t key_count = 0; - uint16_t key_index = -1; - _find_key_index_and_count(combo->keys, keycode, &key_index, &key_count); - - /* Continue processing if key isn't part of current combo. */ - if (-1 == (int16_t)key_index) { - return false; - } - - bool key_is_part_of_combo = (!COMBO_DISABLED(combo) && is_combo_enabled() -#if defined(COMBO_MUST_PRESS_IN_ORDER) || defined(COMBO_MUST_PRESS_IN_ORDER_PER_COMBO) - && keys_pressed_in_order(combo_index, combo, key_index, keycode, record) -#endif -#ifdef COMBO_SHOULD_TRIGGER - && combo_should_trigger(combo_index, combo, keycode, record) -#endif - ); - - if (record->event.pressed && key_is_part_of_combo) { - uint16_t time = _get_combo_term(combo_index, combo); - if (!COMBO_ACTIVE(combo)) { - KEY_STATE_DOWN(combo->state, key_index); - if (longest_term < time) { - longest_term = time; - } - } - if (ALL_COMBO_KEYS_ARE_DOWN(COMBO_STATE(combo), key_count)) { - /* Combo was fully pressed */ - /* Buffer the combo so we can fire it after COMBO_TERM */ - -#ifndef COMBO_NO_TIMER - /* Don't buffer this combo if its combo term has passed. */ - if (timer && timer_elapsed(timer) > time) { - DISABLE_COMBO(combo); - return true; - } else -#endif - { - - // disable readied combos that overlap with this combo - combo_t *drop = NULL; - for (uint8_t combo_buffer_i = combo_buffer_read; combo_buffer_i != combo_buffer_write; INCREMENT_MOD(combo_buffer_i)) { - queued_combo_t *qcombo = &combo_buffer[combo_buffer_i]; - combo_t * buffered_combo = combo_get(qcombo->combo_index); - - if ((drop = overlaps(buffered_combo, combo))) { - DISABLE_COMBO(drop); - if (drop == combo) { - // stop checking for overlaps if dropped combo was current combo. - break; - } else if (combo_buffer_i == combo_buffer_read && drop == buffered_combo) { - /* Drop the disabled buffered combo from the buffer if - * it is in the beginning of the buffer. */ - INCREMENT_MOD(combo_buffer_read); - } - } - } - - if (drop != combo) { - // save this combo to buffer - combo_buffer[combo_buffer_write] = (queued_combo_t){ - .combo_index = combo_index, - }; - INCREMENT_MOD(combo_buffer_write); - - // get possible longer waiting time for tap-/hold-only combos. - longest_term = _get_wait_time(combo_index, combo); - } - } // if timer elapsed end - } - } else { - // chord releases - if (!COMBO_ACTIVE(combo) && ALL_COMBO_KEYS_ARE_DOWN(COMBO_STATE(combo), key_count)) { - /* First key quickly released */ - if (COMBO_DISABLED(combo) || _get_combo_must_hold(combo_index, combo)) { - // combo wasn't tappable, disable it and drop it from buffer. - drop_combo_from_buffer(combo_index); - key_is_part_of_combo = false; - } -#ifdef COMBO_MUST_TAP_PER_COMBO - else if (get_combo_must_tap(combo_index, combo)) { - // immediately apply tap-only combo - apply_combo(combo_index, combo); - apply_combos(); // also apply other prepared combos and dump key buffer -# ifdef COMBO_PROCESS_KEY_RELEASE - if (process_combo_key_release(combo_index, combo, key_index, keycode)) { - release_combo(combo_index, combo); - } -# endif - } -#endif - } else if (COMBO_ACTIVE(combo) && ONLY_ONE_KEY_IS_DOWN(COMBO_STATE(combo)) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) { - /* last key released */ - release_combo(combo_index, combo); - key_is_part_of_combo = true; - -#ifdef COMBO_PROCESS_KEY_RELEASE - process_combo_key_release(combo_index, combo, key_index, keycode); -#endif - } else if (COMBO_ACTIVE(combo) && KEY_NOT_YET_RELEASED(COMBO_STATE(combo), key_index)) { - /* first or middle key released */ - key_is_part_of_combo = true; - -#ifdef COMBO_PROCESS_KEY_RELEASE - if (process_combo_key_release(combo_index, combo, key_index, keycode)) { - release_combo(combo_index, combo); - } -#endif - } else { - /* The released key was part of an incomplete combo */ - key_is_part_of_combo = false; - } - - KEY_STATE_UP(combo->state, key_index); - } - - return key_is_part_of_combo; -} - -bool process_combo(uint16_t keycode, keyrecord_t *record) { - bool is_combo_key = false; - bool no_combo_keys_pressed = true; - - if (keycode == QK_COMBO_ON && record->event.pressed) { - combo_enable(); - return true; - } - - if (keycode == QK_COMBO_OFF && record->event.pressed) { - combo_disable(); - return true; - } - - if (keycode == QK_COMBO_TOGGLE && record->event.pressed) { - combo_toggle(); - return true; - } - -#ifdef COMBO_ONLY_FROM_LAYER - /* Only check keycodes from one layer. */ - keycode = keymap_key_to_keycode(COMBO_ONLY_FROM_LAYER, record->event.key); -#else - uint8_t highest_layer = get_highest_layer(layer_state); - uint8_t ref_layer = combo_ref_from_layer(highest_layer); - if (ref_layer != highest_layer) { - keycode = keymap_key_to_keycode(ref_layer, record->event.key); - } -#endif - - for (uint16_t idx = 0; idx < combo_count(); ++idx) { - combo_t *combo = combo_get(idx); - is_combo_key |= process_single_combo(combo, keycode, record, idx); - no_combo_keys_pressed = no_combo_keys_pressed && (NO_COMBO_KEYS_ARE_DOWN || COMBO_ACTIVE(combo) || COMBO_DISABLED(combo)); - } - - if (record->event.pressed && is_combo_key) { -#ifndef COMBO_NO_TIMER -# ifdef COMBO_STRICT_TIMER - if (!timer) { - // timer is set only on the first key - timer = timer_read(); - } -# else - timer = timer_read(); -# endif -#endif - - if (key_buffer_size < COMBO_KEY_BUFFER_LENGTH) { - key_buffer[key_buffer_size++] = (queued_record_t){ - .record = *record, - .keycode = keycode, - .combo_index = -1, // this will be set when applying combos - }; - } - } else { - if (combo_buffer_read != combo_buffer_write) { - // some combo is prepared - apply_combos(); - } else { - // reset state if there are no combo keys pressed at all - dump_key_buffer(); -#ifndef COMBO_NO_TIMER - timer = 0; -#endif - clear_combos(); - } - } - return !is_combo_key; -} - -void combo_task(void) { - if (!b_combo_enable) { - return; - } - -#ifndef COMBO_NO_TIMER - if (timer && timer_elapsed(timer) > longest_term) { - if (combo_buffer_read != combo_buffer_write) { - apply_combos(); - longest_term = 0; - timer = 0; - } else { - dump_key_buffer(); - timer = 0; - clear_combos(); - } - } -#endif -} - -void combo_enable(void) { - b_combo_enable = true; -} - -void combo_disable(void) { -#ifndef COMBO_NO_TIMER - timer = 0; -#endif - b_combo_enable = false; - combo_buffer_read = combo_buffer_write; - clear_combos(); - dump_key_buffer(); -} - -void combo_toggle(void) { - if (b_combo_enable) { - combo_disable(); - } else { - combo_enable(); - } -} - -bool is_combo_enabled(void) { - return b_combo_enable; -} diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h deleted file mode 100644 index bba5d5ee6301..000000000000 --- a/quantum/process_keycode/process_combo.h +++ /dev/null @@ -1,81 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "progmem.h" -#include "quantum.h" -#include - -#ifdef EXTRA_SHORT_COMBOS -# define MAX_COMBO_LENGTH 6 -#elif defined(EXTRA_EXTRA_LONG_COMBOS) -# define MAX_COMBO_LENGTH 32 -#elif defined(EXTRA_LONG_COMBOS) -# define MAX_COMBO_LENGTH 16 -#else -# define MAX_COMBO_LENGTH 8 -#endif - -#ifndef COMBO_KEY_BUFFER_LENGTH -# define COMBO_KEY_BUFFER_LENGTH MAX_COMBO_LENGTH -#endif -#ifndef COMBO_BUFFER_LENGTH -# define COMBO_BUFFER_LENGTH 4 -#endif - -typedef struct combo_t { - const uint16_t *keys; - uint16_t keycode; -#ifdef EXTRA_SHORT_COMBOS - uint8_t state; -#else - bool disabled; - bool active; -# if defined(EXTRA_EXTRA_LONG_COMBOS) - uint32_t state; -# elif defined(EXTRA_LONG_COMBOS) - uint16_t state; -# else - uint8_t state; -# endif -#endif -} combo_t; - -#define COMBO(ck, ca) \ - { .keys = &(ck)[0], .keycode = (ca) } -#define COMBO_ACTION(ck) \ - { .keys = &(ck)[0] } - -#define COMBO_END 0 -#ifndef COMBO_TERM -# define COMBO_TERM 50 -#endif -#ifndef COMBO_HOLD_TERM -# define COMBO_HOLD_TERM TAPPING_TERM -#endif - -/* check if keycode is only modifiers */ -#define KEYCODE_IS_MOD(code) (IS_MODIFIER_KEYCODE(code) || (IS_QK_MODS(code) && !QK_MODS_GET_BASIC_KEYCODE(code))) - -bool process_combo(uint16_t keycode, keyrecord_t *record); -void combo_task(void); -void process_combo_event(uint16_t combo_index, bool pressed); - -void combo_enable(void); -void combo_disable(void); -void combo_toggle(void); -bool is_combo_enabled(void); diff --git a/quantum/process_keycode/process_dynamic_macro.c b/quantum/process_keycode/process_dynamic_macro.c index bf6af566e2a8..a022949d3d3a 100644 --- a/quantum/process_keycode/process_dynamic_macro.c +++ b/quantum/process_keycode/process_dynamic_macro.c @@ -151,6 +151,67 @@ void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_poin *macro_end = macro_pointer; } +/* Both macros use the same buffer but read/write on different + * ends of it. + * + * Macro1 is written left-to-right starting from the beginning of + * the buffer. + * + * Macro2 is written right-to-left starting from the end of the + * buffer. + * + * ¯o_buffer macro_end + * v v + * +------------------------------------------------------------+ + * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| + * +------------------------------------------------------------+ + * ^ ^ + * r_macro_end r_macro_buffer + * + * During the recording when one macro encounters the end of the + * other macro, the recording is stopped. Apart from this, there + * are no arbitrary limits for the macros' length in relation to + * each other: for example one can either have two medium sized + * macros or one long macro and one short macro. Or even one empty + * and one using the whole buffer. + */ +static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; + +/* Pointer to the first buffer element after the first macro. + * Initially points to the very beginning of the buffer since the + * macro is empty. */ +static keyrecord_t *macro_end = macro_buffer; + +/* The other end of the macro buffer. Serves as the beginning of + * the second macro. */ +static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; + +/* Like macro_end but for the second macro. */ +static keyrecord_t *r_macro_end = r_macro_buffer; + +/* A persistent pointer to the current macro position (iterator) + * used during the recording. */ +static keyrecord_t *macro_pointer = NULL; + +/* 0 - no macro is being recorded right now + * 1,2 - either macro 1 or 2 is being recorded */ +static uint8_t macro_id = 0; + +/** + * If a dynamic macro is currently being recorded, stop recording. + */ +void dynamic_macro_stop_recording(void) { + switch (macro_id) { + case 1: + dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); + break; + case 2: + dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); + break; + } + macro_id = 0; +} + /* Handle the key events related to the dynamic macros. Should be * called from process_record_user() like this: * @@ -162,52 +223,6 @@ void dynamic_macro_record_end(keyrecord_t *macro_buffer, keyrecord_t *macro_poin * } */ bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) { - /* Both macros use the same buffer but read/write on different - * ends of it. - * - * Macro1 is written left-to-right starting from the beginning of - * the buffer. - * - * Macro2 is written right-to-left starting from the end of the - * buffer. - * - * ¯o_buffer macro_end - * v v - * +------------------------------------------------------------+ - * |>>>>>> MACRO1 >>>>>> <<<<<<<<<<<<< MACRO2 <<<<<<<<<<<<<| - * +------------------------------------------------------------+ - * ^ ^ - * r_macro_end r_macro_buffer - * - * During the recording when one macro encounters the end of the - * other macro, the recording is stopped. Apart from this, there - * are no arbitrary limits for the macros' length in relation to - * each other: for example one can either have two medium sized - * macros or one long macro and one short macro. Or even one empty - * and one using the whole buffer. - */ - static keyrecord_t macro_buffer[DYNAMIC_MACRO_SIZE]; - - /* Pointer to the first buffer element after the first macro. - * Initially points to the very beginning of the buffer since the - * macro is empty. */ - static keyrecord_t *macro_end = macro_buffer; - - /* The other end of the macro buffer. Serves as the beginning of - * the second macro. */ - static keyrecord_t *const r_macro_buffer = macro_buffer + DYNAMIC_MACRO_SIZE - 1; - - /* Like macro_end but for the second macro. */ - static keyrecord_t *r_macro_end = r_macro_buffer; - - /* A persistent pointer to the current macro position (iterator) - * used during the recording. */ - static keyrecord_t *macro_pointer = NULL; - - /* 0 - no macro is being recorded right now - * 1,2 - either macro 1 or 2 is being recorded */ - static uint8_t macro_id = 0; - if (macro_id == 0) { /* No macro recording in progress. */ if (!record->event.pressed) { @@ -238,15 +253,7 @@ bool process_dynamic_macro(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed ^ (keycode != QK_DYNAMIC_MACRO_RECORD_STOP)) { /* Ignore the initial release * just after the recording * starts for DM_RSTP. */ - switch (macro_id) { - case 1: - dynamic_macro_record_end(macro_buffer, macro_pointer, +1, ¯o_end); - break; - case 2: - dynamic_macro_record_end(r_macro_buffer, macro_pointer, -1, &r_macro_end); - break; - } - macro_id = 0; + dynamic_macro_stop_recording(); } return false; #ifdef DYNAMIC_MACRO_NO_NESTING diff --git a/quantum/process_keycode/process_dynamic_macro.h b/quantum/process_keycode/process_dynamic_macro.h index ab70726897cb..9841254af4f0 100644 --- a/quantum/process_keycode/process_dynamic_macro.h +++ b/quantum/process_keycode/process_dynamic_macro.h @@ -39,3 +39,4 @@ void dynamic_macro_record_start_user(int8_t direction); void dynamic_macro_play_user(int8_t direction); void dynamic_macro_record_key_user(int8_t direction, keyrecord_t *record); void dynamic_macro_record_end_user(int8_t direction); +void dynamic_macro_stop_recording(void); diff --git a/quantum/process_keycode/process_dynamic_tapping_term.c b/quantum/process_keycode/process_dynamic_tapping_term.c deleted file mode 100644 index 146b9fccd726..000000000000 --- a/quantum/process_keycode/process_dynamic_tapping_term.c +++ /dev/null @@ -1,52 +0,0 @@ -/* Copyright 2020 Vladislav Kucheriavykh - * - * 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 . - */ - -#include "quantum.h" -#include "process_dynamic_tapping_term.h" - -#ifndef DYNAMIC_TAPPING_TERM_INCREMENT -# define DYNAMIC_TAPPING_TERM_INCREMENT 5 -#endif - -static void tapping_term_report(void) { -#ifdef SEND_STRING_ENABLE - const char *tapping_term_str = get_u16_str(g_tapping_term, ' '); - // Skip padding spaces - while (*tapping_term_str == ' ') { - tapping_term_str++; - } - send_string(tapping_term_str); -#endif -} - -bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - switch (keycode) { - case QK_DYNAMIC_TAPPING_TERM_PRINT: - tapping_term_report(); - return false; - - case QK_DYNAMIC_TAPPING_TERM_UP: - g_tapping_term += DYNAMIC_TAPPING_TERM_INCREMENT; - return false; - - case QK_DYNAMIC_TAPPING_TERM_DOWN: - g_tapping_term -= DYNAMIC_TAPPING_TERM_INCREMENT; - return false; - } - } - return true; -} diff --git a/quantum/process_keycode/process_dynamic_tapping_term.h b/quantum/process_keycode/process_dynamic_tapping_term.h deleted file mode 100644 index 85e83ee73b0a..000000000000 --- a/quantum/process_keycode/process_dynamic_tapping_term.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2020 Vladislav Kucheriavykh - * - * 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 . - */ - -#pragma once - -#include -#include "action.h" - -#ifndef DYNAMIC_TAPPING_TERM_INCREMENT -# define DYNAMIC_TAPPING_TERM_INCREMENT 5 -#endif - -bool process_dynamic_tapping_term(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_grave_esc.c b/quantum/process_keycode/process_grave_esc.c deleted file mode 100644 index ddf027391d5a..000000000000 --- a/quantum/process_keycode/process_grave_esc.c +++ /dev/null @@ -1,71 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ -#include "process_grave_esc.h" - -/* true if the last press of QK_GRAVE_ESCAPE was shifted (i.e. GUI or SHIFT were pressed), false otherwise. - * Used to ensure that the correct keycode is released if the key is released. - */ -static bool grave_esc_was_shifted = false; - -bool process_grave_esc(uint16_t keycode, keyrecord_t *record) { - if (keycode == QK_GRAVE_ESCAPE) { - const uint8_t mods = get_mods(); - uint8_t shifted = mods & MOD_MASK_SG; - -#ifdef GRAVE_ESC_ALT_OVERRIDE - // if ALT is pressed, ESC is always sent - // this is handy for the cmd+opt+esc shortcut on macOS, among other things. - if (mods & MOD_MASK_ALT) { - shifted = 0; - } -#endif - -#ifdef GRAVE_ESC_CTRL_OVERRIDE - // if CTRL is pressed, ESC is always sent - // this is handy for the ctrl+shift+esc shortcut on windows, among other things. - if (mods & MOD_MASK_CTRL) { - shifted = 0; - } -#endif - -#ifdef GRAVE_ESC_GUI_OVERRIDE - // if GUI is pressed, ESC is always sent - if (mods & MOD_MASK_GUI) { - shifted = 0; - } -#endif - -#ifdef GRAVE_ESC_SHIFT_OVERRIDE - // if SHIFT is pressed, ESC is always sent - if (mods & MOD_MASK_SHIFT) { - shifted = 0; - } -#endif - - if (record->event.pressed) { - grave_esc_was_shifted = shifted; - add_key(shifted ? KC_GRAVE : KC_ESCAPE); - } else { - del_key(grave_esc_was_shifted ? KC_GRAVE : KC_ESCAPE); - } - - send_keyboard_report(); - return false; - } - - // Not a grave keycode so continue processing - return true; -} diff --git a/quantum/process_keycode/process_grave_esc.h b/quantum/process_keycode/process_grave_esc.h deleted file mode 100644 index bbf448376314..000000000000 --- a/quantum/process_keycode/process_grave_esc.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2020 - * - * 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 . - */ -#pragma once - -#include "quantum.h" - -bool process_grave_esc(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_haptic.c b/quantum/process_keycode/process_haptic.c deleted file mode 100644 index 21d4c5ce304c..000000000000 --- a/quantum/process_keycode/process_haptic.c +++ /dev/null @@ -1,147 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ -#include "haptic.h" -#include "process_haptic.h" -#include "quantum_keycodes.h" -#include "action_tapping.h" -#include "usb_device_state.h" - -__attribute__((weak)) bool get_haptic_enabled_key(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { -#ifdef NO_HAPTIC_MOD - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - if (record->tap.count == 0) return false; - break; - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: - if (record->tap.count != TAPPING_TOGGLE) return false; - break; - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: - if (record->tap.count == 0) return false; - break; - case KC_LEFT_CTRL ... KC_RIGHT_GUI: - case QK_MOMENTARY ... QK_MOMENTARY_MAX: - case QK_LAYER_MOD ... QK_LAYER_MOD_MAX: -#endif -#ifdef NO_HAPTIC_ALPHA - case KC_A ... KC_Z: -#endif -#ifdef NO_HAPTIC_PUNCTUATION - case KC_ENTER: - case KC_ESCAPE: - case KC_BACKSPACE: - case KC_SPACE: - case KC_MINUS: - case KC_EQUAL: - case KC_LEFT_BRACKET: - case KC_RIGHT_BRACKET: - case KC_BACKSLASH: - case KC_NONUS_HASH: - case KC_SEMICOLON: - case KC_QUOTE: - case KC_GRAVE: - case KC_COMMA: - case KC_SLASH: - case KC_DOT: - case KC_NONUS_BACKSLASH: -#endif -#ifdef NO_HAPTIC_LOCKKEYS - case KC_CAPS_LOCK: - case KC_SCROLL_LOCK: - case KC_NUM_LOCK: -#endif -#ifdef NO_HAPTIC_NAV - case KC_PRINT_SCREEN: - case KC_PAUSE: - case KC_INSERT: - case KC_DELETE: - case KC_PAGE_DOWN: - case KC_PAGE_UP: - case KC_LEFT: - case KC_UP: - case KC_RIGHT: - case KC_DOWN: - case KC_END: - case KC_HOME: -#endif -#ifdef NO_HAPTIC_NUMERIC - case KC_1 ... KC_0: -#endif - return false; - } - return true; -} - -bool process_haptic(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - switch (keycode) { - case QK_HAPTIC_ON: - haptic_enable(); - break; - case QK_HAPTIC_OFF: - haptic_disable(); - break; - case QK_HAPTIC_TOGGLE: - haptic_toggle(); - break; - case QK_HAPTIC_RESET: - haptic_reset(); - break; - case QK_HAPTIC_FEEDBACK_TOGGLE: - haptic_feedback_toggle(); - break; - case QK_HAPTIC_BUZZ_TOGGLE: - haptic_buzz_toggle(); - break; - case QK_HAPTIC_MODE_NEXT: - haptic_mode_increase(); - break; - case QK_HAPTIC_MODE_PREVIOUS: - haptic_mode_decrease(); - break; - case QK_HAPTIC_DWELL_UP: - haptic_dwell_increase(); - break; - case QK_HAPTIC_DWELL_DOWN: - haptic_dwell_decrease(); - break; - case QK_HAPTIC_CONTINUOUS_TOGGLE: - haptic_toggle_continuous(); - break; - case QK_HAPTIC_CONTINUOUS_UP: - haptic_cont_increase(); - break; - case QK_HAPTIC_CONTINUOUS_DOWN: - haptic_cont_decrease(); - break; - } - } - - if (haptic_get_enable() && ((!HAPTIC_OFF_IN_LOW_POWER) || (usb_device_state == USB_DEVICE_STATE_CONFIGURED))) { - if (record->event.pressed) { - // keypress - if (haptic_get_feedback() < 2 && get_haptic_enabled_key(keycode, record)) { - haptic_play(); - } - } else { - // keyrelease - if (haptic_get_feedback() > 0 && get_haptic_enabled_key(keycode, record)) { - haptic_play(); - } - } - } - - return true; -} diff --git a/quantum/process_keycode/process_haptic.h b/quantum/process_keycode/process_haptic.h deleted file mode 100644 index 6dbb0f014d06..000000000000 --- a/quantum/process_keycode/process_haptic.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ -#pragma once - -#include -#include "action.h" - -bool process_haptic(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_joystick.c b/quantum/process_keycode/process_joystick.c deleted file mode 100644 index 43067b81dbd6..000000000000 --- a/quantum/process_keycode/process_joystick.c +++ /dev/null @@ -1,31 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#include "process_joystick.h" -#include "joystick.h" - -bool process_joystick(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_JOYSTICK ... QK_JOYSTICK_MAX: - if (record->event.pressed) { - register_joystick_button(keycode - QK_JOYSTICK); - } else { - unregister_joystick_button(keycode - QK_JOYSTICK); - } - return false; - } - return true; -} diff --git a/quantum/process_keycode/process_joystick.h b/quantum/process_keycode/process_joystick.h deleted file mode 100644 index 1fb8757708d7..000000000000 --- a/quantum/process_keycode/process_joystick.h +++ /dev/null @@ -1,22 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#pragma once - -#include -#include "quantum.h" - -bool process_joystick(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_key_lock.c b/quantum/process_keycode/process_key_lock.c deleted file mode 100644 index 2542e32ec229..000000000000 --- a/quantum/process_keycode/process_key_lock.c +++ /dev/null @@ -1,139 +0,0 @@ -/* Copyright 2017 Fredric Silberberg - * - * 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 . - */ - -#include -#include -#include "process_key_lock.h" - -#define BV_64(shift) (((uint64_t)1) << (shift)) -#define GET_KEY_ARRAY(code) (((code) < 0x40) ? key_state[0] : ((code) < 0x80) ? key_state[1] : ((code) < 0xC0) ? key_state[2] : key_state[3]) -#define GET_CODE_INDEX(code) (((code) < 0x40) ? (code) : ((code) < 0x80) ? (code)-0x40 : ((code) < 0xC0) ? (code)-0x80 : (code)-0xC0) -#define KEY_STATE(code) (GET_KEY_ARRAY(code) & BV_64(GET_CODE_INDEX(code))) == BV_64(GET_CODE_INDEX(code)) -#define SET_KEY_ARRAY_STATE(code, val) \ - do { \ - switch (code) { \ - case 0x00 ... 0x3F: \ - key_state[0] = (val); \ - break; \ - case 0x40 ... 0x7F: \ - key_state[1] = (val); \ - break; \ - case 0x80 ... 0xBF: \ - key_state[2] = (val); \ - break; \ - case 0xC0 ... 0xFF: \ - key_state[3] = (val); \ - break; \ - } \ - } while (0) -#define SET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code) | BV_64(GET_CODE_INDEX(code)))) -#define UNSET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code)) & ~(BV_64(GET_CODE_INDEX(code)))) -#define IS_STANDARD_KEYCODE(code) ((code) <= 0xFF) - -// Locked key state. This is an array of 256 bits, one for each of the standard keys supported qmk. -uint64_t key_state[4] = {0x0, 0x0, 0x0, 0x0}; -bool watching = false; - -// Translate any OSM keycodes back to their unmasked versions. -static inline uint16_t translate_keycode(uint16_t keycode) { - if (keycode > QK_ONE_SHOT_MOD && keycode <= QK_ONE_SHOT_MOD_MAX) { - return keycode ^ QK_ONE_SHOT_MOD; - } else { - return keycode; - } -} - -void cancel_key_lock(void) { - watching = false; - UNSET_KEY_STATE(0x0); -} - -bool process_key_lock(uint16_t *keycode, keyrecord_t *record) { - // We start by categorizing the keypress event. In the event of a down - // event, there are several possibilities: - // 1. The key is not being locked, and we are not watching for new keys. - // In this case, we bail immediately. This is the common case for down events. - // 2. The key was locked, and we need to unlock it. In this case, we will - // reset the state in our map and return false. When the user releases the - // key, the up event will no longer be masked and the OS will observe the - // released key. - // 3. QK_LOCK was just pressed. In this case, we set up the state machine - // to watch for the next key down event, and finish processing - // 4. The keycode is below 0xFF, and we are watching for new keys. In this case, - // we will send the key down event to the os, and set the key_state for that - // key to mask the up event. - // 5. The keycode is above 0xFF, and we're wathing for new keys. In this case, - // the user pressed a key that we cannot "lock", as it's a series of keys, - // or a macro invocation, or a layer transition, or a custom-defined key, or - // or some other arbitrary code. In this case, we bail immediately, reset - // our watch state, and return true. - // - // In the event of an up event, there are these possibilities: - // 1. The key is not being locked. In this case, we return true and bail - // immediately. This is the common case. - // 2. The key is being locked. In this case, we will mask the up event - // by returning false, so the OS never sees that the key was released - // until the user pressed the key again. - - // We translate any OSM keycodes back to their original keycodes, so that if the key being - // one-shot modded is a standard keycode, we can handle it. This is the only set of special - // keys that we handle - uint16_t translated_keycode = translate_keycode(*keycode); - - if (record->event.pressed) { - // Non-standard keycode, reset and return - if (!(IS_STANDARD_KEYCODE(translated_keycode) || translated_keycode == QK_LOCK)) { - watching = false; - return true; - } - - // If we're already watching, turn off the watch. - if (translated_keycode == QK_LOCK) { - watching = !watching; - return false; - } - - if (IS_STANDARD_KEYCODE(translated_keycode)) { - // We check watching first. This is so that in the following scenario, we continue to - // hold the key: QK_LOCK, KC_F, QK_LOCK, KC_F - // If we checked in reverse order, we'd end up holding the key pressed after the second - // KC_F press is registered, when the user likely meant to hold F - if (watching) { - watching = false; - SET_KEY_STATE(translated_keycode); - // We need to set the keycode passed in to be the translated keycode, in case we - // translated a OSM back to the original keycode. - *keycode = translated_keycode; - // Let the standard keymap send the keycode down event. The up event will be masked. - return true; - } - - if (KEY_STATE(translated_keycode)) { - UNSET_KEY_STATE(translated_keycode); - // The key is already held, stop this process. The up event will be sent when the user - // releases the key. - return false; - } - } - - // Either the key isn't a standard key, or we need to send the down event. Continue standard - // processing - return true; - } else { - // Stop processing if it's a standard key and we're masking up. - return !(IS_STANDARD_KEYCODE(translated_keycode) && KEY_STATE(translated_keycode)); - } -} diff --git a/quantum/process_keycode/process_key_override.c b/quantum/process_keycode/process_key_override.c deleted file mode 100644 index 17e490e67ae3..000000000000 --- a/quantum/process_keycode/process_key_override.c +++ /dev/null @@ -1,520 +0,0 @@ -/* - * Copyright 2021 Jonas Gessner - * - * 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 . - */ - -#include "quantum.h" -#include "report.h" -#include "timer.h" -#include "process_key_override.h" - -#include - -#ifndef KEY_OVERRIDE_REPEAT_DELAY -# define KEY_OVERRIDE_REPEAT_DELAY 500 -#endif - -// For benchmarking the time it takes to call process_key_override on every key press (needs keyboard debugging enabled as well) -// #define BENCH_KEY_OVERRIDE - -// For debug output (needs keyboard debugging enabled as well) -// #define DEBUG_KEY_OVERRIDE - -#ifdef DEBUG_KEY_OVERRIDE -# define key_override_printf dprintf -#else -# define key_override_printf(str, ...) \ - {} -#endif - -// Helpers - -// Private functions implemented elsewhere in qmk/tmk -extern uint8_t extract_mod_bits(uint16_t code); -extern void set_weak_override_mods(uint8_t mods); -extern void clear_weak_override_mods(void); -extern void set_suppressed_override_mods(uint8_t mods); -extern void clear_suppressed_override_mods(void); - -static uint16_t clear_mods_from(uint16_t keycode) { - switch (keycode) { - case QK_MODS ... QK_MODS_MAX: - break; - default: - return keycode; - } - - static const uint16_t all_mods = QK_LCTL | QK_LSFT | QK_LALT | QK_LGUI | QK_RCTL | QK_RSFT | QK_RALT | QK_RGUI; - - return (keycode & ~(all_mods)); -} - -// Internal variables -static const key_override_t *active_override = NULL; -static bool active_override_trigger_is_down = false; - -// Used to keep track of what non-modifier key was last pressed down. We never want to activate an override for a trigger key that is not the last non-mod key that was pressed down. OSes internally completely unregister a key that is held when a different key is held down after. We want to respect this here. -static uint16_t last_key_down = 0; -// When was the last key pressed down? -static uint32_t last_key_down_time = 0; - -// What timestamp are we comparing to when waiting to register a deferred key? -static uint32_t defer_reference_time = 0; -// What delay should pass until deferred key is registered? -static uint32_t defer_delay = 0; - -// Holds the keycode that should be registered at a later time, in order to not get false key presses -static uint16_t deferred_register = 0; - -// TODO: in future maybe save in EEPROM? -static bool enabled = true; - -// Public variables -__attribute__((weak)) const key_override_t **key_overrides = NULL; - -// Forward decls -static const key_override_t *clear_active_override(const bool allow_reregister); - -void key_override_on(void) { - enabled = true; - key_override_printf("Key override ON\n"); -} - -void key_override_off(void) { - enabled = false; - clear_active_override(false); - key_override_printf("Key override OFF\n"); -} - -void key_override_toggle(void) { - if (key_override_is_enabled()) { - key_override_off(); - } else { - key_override_on(); - } -} - -bool key_override_is_enabled(void) { - return enabled; -} - -// Returns whether the modifiers that are pressed are such that the override should activate -static bool key_override_matches_active_modifiers(const key_override_t *override, const uint8_t mods) { - // Check that negative keys pass - if ((override->negative_mod_mask & mods) != 0) { - return false; - } - - // Immediately return true if the override requires no mods down - if (override->trigger_mods == 0) { - return true; - } - - if ((override->options & ko_option_one_mod) != 0) { - // At least one of the trigger modifiers must be down - return (override->trigger_mods & mods) != 0; - } else { - // All trigger modifiers must be down, but each mod can be active on either side (if both sides are specified). - - // Which mods, regardless of side, are required? - uint8_t one_sided_required_mods = (override->trigger_mods & 0b1111) | (override->trigger_mods >> 4); - - // Which of the required modifiers are active? - uint8_t active_required_mods = override->trigger_mods & mods; - - // Move the active requird mods to one side - uint8_t one_sided_active_required_mods = (active_required_mods & 0b1111) | (active_required_mods >> 4); - - // Check that there is a full match between the required one-sided mods and active required one sided mods - return one_sided_active_required_mods == one_sided_required_mods; - } - - return false; -} - -static void schedule_deferred_register(const uint16_t keycode) { - if (timer_elapsed32(last_key_down_time) < KEY_OVERRIDE_REPEAT_DELAY) { - // Defer until KEY_OVERRIDE_REPEAT_DELAY has passed since the trigger key was pressed down. This emulates the behavior as holding down a key x, then holding down shift shortly after. Usually the shifted key X is not immediately produced, but rather a 'key repeat delay' passes before any repeated character is output. - defer_reference_time = last_key_down_time; - defer_delay = KEY_OVERRIDE_REPEAT_DELAY; - } else { - // Wait a very short time when a modifier event triggers the override to avoid false activations when e.g. a modifier is pressed just before a key is released (with the intention of pairing the modifier with a different key), or a modifier is lifted shortly before the trigger key is lifted. Operating systems by default reject modifier-events that happen very close to a non-modifier event. - defer_reference_time = timer_read32(); - defer_delay = 50; // 50ms - } - deferred_register = keycode; -} - -const key_override_t *clear_active_override(const bool allow_reregister) { - if (active_override == NULL) { - return NULL; - } - - key_override_printf("Deactivating override\n"); - - deferred_register = 0; - - // Clear the suppressed mods - clear_suppressed_override_mods(); - - // Unregister the replacement. First remove the weak override mods - clear_weak_override_mods(); - - const key_override_t *const old = active_override; - - const uint8_t mod_free_replacement = clear_mods_from(active_override->replacement); - - bool unregister_replacement = mod_free_replacement != KC_NO && // KC_NO is never registered - mod_free_replacement < SAFE_RANGE; // Custom keycodes are never registered - - // Try firing the custom handler - if (active_override->custom_action != NULL) { - unregister_replacement &= active_override->custom_action(false, active_override->context); - } - - // Then unregister the mod-free replacement key if desired - if (unregister_replacement) { - if (IS_BASIC_KEYCODE(mod_free_replacement)) { - del_key(mod_free_replacement); - } else { - key_override_printf("NOT KEY 1\n"); - send_keyboard_report(); - unregister_code(mod_free_replacement); - } - } - - const uint16_t trigger = active_override->trigger; - - const bool reregister_trigger = allow_reregister && // Check if allowed from caller - (active_override->options & ko_option_no_reregister_trigger) == 0 && // Check if override allows - active_override_trigger_is_down && // Check if trigger is even down - trigger != KC_NO && // KC_NO is never registered - trigger < SAFE_RANGE; // A custom keycode should not be registered - - // Optionally re-register the trigger if it is still down - if (reregister_trigger) { - key_override_printf("Re-registering trigger deferred: %u\n", trigger); - - // This will always be a modifier event, so defer always - schedule_deferred_register(trigger); - } - - send_keyboard_report(); - - active_override = NULL; - active_override_trigger_is_down = false; - - return old; -} - -/** Checks if the key event is an allowed activation event for the provided override. Does not check things like whether the correct mods or correct trigger key is down. */ -static bool check_activation_event(const key_override_t *override, const bool key_down, const bool is_mod) { - ko_option_t options = override->options; - - if ((options & ko_options_all_activations) == 0) { - // No activation option provided at all. This is wrong, but let's assume the default activations (ko_options_all_activations) were meant... - options = ko_options_all_activations; - } - - if (is_mod) { - if (key_down) { - return (options & ko_option_activation_required_mod_down) != 0; - } else { - return (options & ko_option_activation_negative_mod_up) != 0; - } - } else { - if (key_down) { - return (options & ko_option_activation_trigger_down) != 0; - } else { - return false; - } - } -} - -/** Iterates through the list of key overrides and tries activating each, until it finds one that activates or reaches the end of overrides. Returns true if the key action for `keycode` should be sent */ -static bool try_activating_override(const uint16_t keycode, const uint8_t layer, const bool key_down, const bool is_mod, const uint8_t active_mods, bool *activated) { - if (key_overrides == NULL) { - return true; - } - - for (uint8_t i = 0;; i++) { - const key_override_t *const override = key_overrides[i]; - - // End of array - if (override == NULL) { - break; - } - - // Fast, but not full mods check. Most key presses will not have any mods down, and most overrides will require mods. Hence here we filter overrides that require mods to be down while no mods are down - if (active_mods == 0 && override->trigger_mods != 0) { - key_override_printf("Not activating override: Modifiers don't match\n"); - continue; - } - - // Check layer - if ((override->layers & (1 << layer)) == 0) { - key_override_printf("Not activating override: Not set to activate on pressed layer\n"); - continue; - } - - // Check allowed activation events - if (!check_activation_event(override, key_down, is_mod)) { - key_override_printf("Not activating override: Activation event not allowed\n"); - continue; - } - - const bool is_trigger = override->trigger == keycode; - - // Check if trigger lifted. This is a small optimization in order to skip the remaining checks - if (is_trigger && !key_down) { - key_override_printf("Not activating override: Trigger lifted\n"); - continue; - } - - // If the trigger is KC_NO it means 'no key', so only the required modifiers need to be down. - const bool no_trigger = override->trigger == KC_NO; - - // Check if aleady active - if (override == active_override) { - key_override_printf("Not activating override: Alerady actived\n"); - continue; - } - - // Check if enabled - if (override->enabled != NULL && !((*(override->enabled) & 1))) { - key_override_printf("Not activating override: Not enabled\n"); - continue; - } - - // Check mods precisely - if (!key_override_matches_active_modifiers(override, active_mods)) { - key_override_printf("Not activating override: Modifiers don't match\n"); - continue; - } - - // Check if trigger key is down. - const bool trigger_down = is_trigger && key_down; - - // At this point, all requirements for activation are checked, except whether the trigger key is pressed. Now we check if the required trigger is down - // If no trigger key is required, yes. - // If the trigger was just pressed, yes. - // If the last non-mod key that was pressed down is the trigger key, yes. - bool should_activate = no_trigger || trigger_down || last_key_down == override->trigger; - - if (!should_activate) { - key_override_printf("Not activating override. Trigger not down\n"); - continue; - } - - key_override_printf("Activating override\n"); - - clear_active_override(false); - - active_override = override; - active_override_trigger_is_down = true; - - set_suppressed_override_mods(override->suppressed_mods); - - if (!trigger_down && !no_trigger) { - // When activating a key override the trigger is is always unregistered. In the case where the key that newly pressed is not the trigger key, we have to explicitly remove the trigger key from the keyboard report. If the trigger was just pressed down we simply suppress the event which also has the effect of the trigger key not being registered in the keyboard report. - if (IS_BASIC_KEYCODE(override->trigger)) { - del_key(override->trigger); - } else { - unregister_code(override->trigger); - } - } - - const uint16_t mod_free_replacement = clear_mods_from(override->replacement); - - bool register_replacement = mod_free_replacement != KC_NO && // KC_NO is never registered - mod_free_replacement < SAFE_RANGE; // Custom keycodes are never registered - - // Try firing the custom handler - if (override->custom_action != NULL) { - register_replacement &= override->custom_action(true, override->context); - } - - if (register_replacement) { - const uint8_t override_mods = extract_mod_bits(override->replacement); - set_weak_override_mods(override_mods); - - // If this is a modifier event that activates the key override we _always_ defer the actual full activation of the override - if (is_mod) { - key_override_printf("Deferring register replacement key\n"); - schedule_deferred_register(mod_free_replacement); - send_keyboard_report(); - } else { - if (IS_BASIC_KEYCODE(mod_free_replacement)) { - add_key(mod_free_replacement); - } else { - key_override_printf("NOT KEY 2\n"); - send_keyboard_report(); - // On macOS there seems to be a race condition when it comes to the keyboard report and consumer keycodes. It seems the OS may recognize a consumer keycode before an updated keyboard report, even if the keyboard report is actually sent before the consumer key. I assume it is some sort of race condition because it happens infrequently and very irregularly. Waiting for about at least 10ms between sending the keyboard report and sending the consumer code has shown to fix this. - wait_ms(10); - register_code(mod_free_replacement); - } - } - } else { - // If not registering the replacement key send keyboard report to update the unregistered keys. - send_keyboard_report(); - } - - *activated = true; - - // If the trigger is down, suppress the event so that it does not get added to the keyboard report. - return !trigger_down; - } - - *activated = false; - - return true; -} - -void key_override_task(void) { - if (deferred_register == 0) { - return; - } - - if (timer_elapsed32(defer_reference_time) >= defer_delay) { - key_override_printf("Registering deferred key\n"); - register_code16(deferred_register); - deferred_register = 0; - defer_reference_time = 0; - defer_delay = 0; - } -} - -bool process_key_override(const uint16_t keycode, const keyrecord_t *const record) { -#ifdef BENCH_KEY_OVERRIDE - uint16_t start = timer_read(); -#endif - - const bool key_down = record->event.pressed; - const bool is_mod = IS_MODIFIER_KEYCODE(keycode); - - if (key_down) { - switch (keycode) { - case QK_KEY_OVERRIDE_TOGGLE: - key_override_toggle(); - return false; - - case QK_KEY_OVERRIDE_ON: - key_override_on(); - return false; - - case QK_KEY_OVERRIDE_OFF: - key_override_off(); - return false; - - default: - break; - } - } - - if (!enabled) { - return true; - } - - uint8_t effective_mods = get_mods(); - -#ifdef KEY_OVERRIDE_INCLUDE_WEAK_MODS - effective_mods |= get_weak_mods(); -#endif - -#ifndef NO_ACTION_ONESHOT - // Locked one shot mods are added to get_mods(), I think (why??) while oneshot mods are in get_oneshot_mods(). Still OR with get_locked_oneshot_mods because that's where those mods _should_ be saved. - effective_mods |= get_oneshot_locked_mods() | get_oneshot_mods(); -#endif - - if (is_mod) { - // The mods returned from get_mods() will be updated with this new event _after_ this code runs. Hence we manually update the effective mods here to really know the effective mods. - if (key_down) { - effective_mods |= MOD_BIT(keycode); - } else { - effective_mods &= ~MOD_BIT(keycode); - } - } else { - if (key_down) { - last_key_down = keycode; - last_key_down_time = timer_read32(); - deferred_register = 0; - } - - // The last key that was pressed was just released. No more keys are therefore sending input - if (!key_down && keycode == last_key_down) { - last_key_down = 0; - last_key_down_time = 0; - // We also cancel any deferred registers because, again, no keys are sending any input. Only the last key that is pressed creates an input – this key was just lifted. - deferred_register = 0; - } - } - - key_override_printf("key down: %u keycode: %u is mod: %u effective mods: %u\n", key_down, keycode, is_mod, effective_mods); - - bool send_key_action = true; - bool activated = false; - - // Non-mod key up events never activate a key override - if (is_mod || key_down) { - // Get the exact layer that was hit. It will be cached at this point - const uint8_t layer = read_source_layers_cache(record->event.key); - - // Use blocked to ensure the same override is not activated again immediately after it is deactivated - send_key_action = try_activating_override(keycode, layer, key_down, is_mod, effective_mods, &activated); - - if (!send_key_action) { - send_keyboard_report(); - } - } - - if (!activated && active_override != NULL) { - if (is_mod) { - // Check if necessary modifier of current override goes up or a negative mod goes down - if (!key_override_matches_active_modifiers(active_override, effective_mods)) { - key_override_printf("Deactivating override because necessary modifier lifted or negative mod pressed\n"); - clear_active_override(true); - } - } else { - // Check if trigger of current override goes up or if override does not allow additional keys to be down and another key goes down - const bool is_trigger = keycode == active_override->trigger; - bool should_deactivate = false; - - // Check if trigger key lifted - if (is_trigger && !key_down) { - should_deactivate = true; - active_override_trigger_is_down = false; - key_override_printf("Deactivating override because trigger key up\n"); - } - - // Check if another key was pressed - if (key_down && (active_override->options & ko_option_no_unregister_on_other_key_down) == 0) { - should_deactivate = true; - key_override_printf("Deactivating override because another key was pressed\n"); - } - - if (should_deactivate) { - clear_active_override(false); - } - } - } - -#ifdef BENCH_KEY_OVERRIDE - uint16_t elapsed = timer_elapsed(start); - - dprintf("Processing key overrides took: %u ms\n", elapsed); -#endif - - return send_key_action; -} diff --git a/quantum/process_keycode/process_key_override.h b/quantum/process_keycode/process_key_override.h deleted file mode 100644 index fd76f297a807..000000000000 --- a/quantum/process_keycode/process_key_override.h +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright 2021 Jonas Gessner - * - * 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 . - */ - -#pragma once - -#include -#include -#include - -#include "action_layer.h" - -/** - * Key overrides allow you to send a different key-modifier combination or perform a custom action when a certain modifier-key combination is pressed. - * - * For example, you may configure a key override to send the delete key when shift + backspace are pressed together, or that your volume keys become screen brightness keys when holding ctrl. The possibilities are quite vast and the documentation contains a few examples for inspiration. - * - * See the documentation and examples here: https://docs.qmk.fm/#/feature_key_overrides - */ - -/** Bitfield with various options controlling the behavior of a key override. */ -typedef enum { - /** Allow activating when the trigger key is pressed down. */ - ko_option_activation_trigger_down = (1 << 0), - /** Allow activating when a necessary modifier is pressed down. */ - ko_option_activation_required_mod_down = (1 << 1), - /** Allow activating when a negative modifier is released. */ - ko_option_activation_negative_mod_up = (1 << 2), - - ko_options_all_activations = ko_option_activation_negative_mod_up | ko_option_activation_required_mod_down | ko_option_activation_trigger_down, - - /** If set, any of the modifiers in trigger_mods will be enough to activate the override (logical OR of modifiers). If not set, all the modifiers in trigger_mods have to be pressed (logical AND of modifiers). */ - ko_option_one_mod = (1 << 3), - - /** If set, the trigger key will never be registered again after the override is deactivated. */ - ko_option_no_reregister_trigger = (1 << 4), - - /** If set, the override will not deactivate when another key is pressed down. Use only if you really know you need this. */ - ko_option_no_unregister_on_other_key_down = (1 << 5), - - /** The default options used by the ko_make_xxx functions. */ - ko_options_default = ko_options_all_activations, -} ko_option_t; - -/** Defines a single key override */ -typedef struct { - // The non-modifier keycode that triggers the override. This keycode, and the necessary modifiers (trigger_mods) must be pressed to activate this override. Set this to the keycode of the key that should activate the override. Set to KC_NO to require only the necessary modifiers to be pressed and no non-modifier. - uint16_t trigger; - - // Which mods need to be down for activation. If both sides of a modifier are set (e.g. left ctrl and right ctrl) then only one is required to be pressed (e.g. left ctrl suffices). Use the MOD_MASK_XXX and MOD_BIT() macros for this. - uint8_t trigger_mods; - - // This is a BITMASK (!), defining which layers this override applies to. To use this override on layer i set the ith bit (1 << i). - layer_state_t layers; - - // Which modifiers cannot be down. It must hold that (active_mods & negative_mod_mask) == 0, otherwise the key override will not be activated. An active override will be deactivated once this is no longer true. - uint8_t negative_mod_mask; - - // Modifiers to 'suppress' while the override is active. To suppress a modifier means that even though the modifier key is held down, the host OS sees the modifier as not pressed. Can be used to suppress the trigger modifiers, as a trivial example. - uint8_t suppressed_mods; - - // The complex keycode to send as replacement when this override is triggered. This can be a simple keycode, a key-modifier combination (e.g. C(KC_A)), or KC_NO (to register no replacement keycode). Use in combination with suppressed_mods to get the correct modifiers to be sent. - uint16_t replacement; - - // Options controlling the behavior of the override, such as what actions are allowed to activate the override. - ko_option_t options; - - // If not NULL, this function will be called right before the replacement key is registered, along with the provided context and a flag indicating whether the override was activated or deactivated. This function allows you to run some custom actions for specific key overrides. If you return `false`, the replacement key is not registered/unregistered as it would normally. Return `true` to register and unregister the override normally. - bool (*custom_action)(bool activated, void *context); - - // A context that will be passed to the custom action function. - void *context; - - // If this points to false this override will not be used. Set to NULL to always have this override enabled. - bool *enabled; -} key_override_t; - -/** Define this as a null-terminated array of pointers to key overrides. These key overrides will be used by qmk. */ -extern const key_override_t **key_overrides; - -/** Turns key overrides on */ -void key_override_on(void); - -/** Turns key overrides off */ -void key_override_off(void); - -/** Toggles key overrides on */ -void key_override_toggle(void); - -/** Returns whether key overrides are enabled */ -bool key_override_is_enabled(void); - -/** Handling of key overrides and its implemented keycodes */ -bool process_key_override(const uint16_t keycode, const keyrecord_t *const record); - -/** Perform any deferred keys */ -void key_override_task(void); - -/** - * Preferrably use these macros to create key overrides. They fix many of the options to a standard setting that should satisfy most basic use-cases. Only directly create a key_override_t struct when you really need to. - */ - -// clang-format off - -/** - * Convenience initializer to create a basic key override. Activates the override on all layers. - */ -#define ko_make_basic(trigger_mods, trigger_key, replacement_key) \ - ko_make_with_layers(trigger_mods, trigger_key, replacement_key, ~0) - -/** - * Convenience initializer to create a basic key override. Provide a bitmap (of type layer_state_t) with the bits set for each layer on which the override should activate. - */ -#define ko_make_with_layers(trigger_mods, trigger_key, replacement_key, layers) \ - ko_make_with_layers_and_negmods(trigger_mods, trigger_key, replacement_key, layers, 0) - -/** - * Convenience initializer to create a basic key override. Provide a bitmap with the bits set for each layer on which the override should activate. Also provide a negative modifier mask, that is used to define which modifiers may not be pressed. - */ -#define ko_make_with_layers_and_negmods(trigger_mods, trigger_key, replacement_key, layers, negative_mask) \ - ko_make_with_layers_negmods_and_options(trigger_mods, trigger_key, replacement_key, layers, negative_mask, ko_options_default) - - /** - * Convenience initializer to create a basic key override. Provide a bitmap with the bits set for each layer on which the override should activate. Also provide a negative modifier mask, that is used to define which modifiers may not be pressed. Provide options for additional control of the behavior of the override. - */ -#define ko_make_with_layers_negmods_and_options(trigger_mods_, trigger_key, replacement_key, layer_mask, negative_mask, options_) \ - ((const key_override_t){ \ - .trigger_mods = (trigger_mods_), \ - .layers = (layer_mask), \ - .suppressed_mods = (trigger_mods_), \ - .options = (options_), \ - .negative_mod_mask = (negative_mask), \ - .custom_action = NULL, \ - .context = NULL, \ - .trigger = (trigger_key), \ - .replacement = (replacement_key), \ - .enabled = NULL \ - }) - -// clang-format on diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c deleted file mode 100644 index a9823b628503..000000000000 --- a/quantum/process_keycode/process_leader.c +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#include "process_leader.h" -#include "leader.h" - -bool process_leader(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - if (leader_sequence_active() && !leader_sequence_timed_out()) { -#ifndef LEADER_KEY_STRICT_KEY_PROCESSING - if (IS_QK_MOD_TAP(keycode)) { - keycode = QK_MOD_TAP_GET_TAP_KEYCODE(keycode); - } else if (IS_QK_LAYER_TAP(keycode)) { - keycode = QK_LAYER_TAP_GET_TAP_KEYCODE(keycode); - } -#endif - - if (!leader_sequence_add(keycode)) { - leader_end(); - - return true; - } - -#ifdef LEADER_PER_KEY_TIMING - leader_reset_timer(); -#endif - - return false; - } else if (keycode == QK_LEADER) { - leader_start(); - } - } - - return true; -} diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h deleted file mode 100644 index eb0f721f6008..000000000000 --- a/quantum/process_keycode/process_leader.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -bool process_leader(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_magic.c b/quantum/process_keycode/process_magic.c deleted file mode 100644 index 5fafe8550fc4..000000000000 --- a/quantum/process_keycode/process_magic.c +++ /dev/null @@ -1,194 +0,0 @@ -/* Copyright 2019 Jack Humbert - * - * 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 . - */ -#include "process_magic.h" - -#ifdef AUDIO_ENABLE -# ifndef AG_NORM_SONG -# define AG_NORM_SONG SONG(AG_NORM_SOUND) -# endif -# ifndef AG_SWAP_SONG -# define AG_SWAP_SONG SONG(AG_SWAP_SOUND) -# endif -# ifndef CG_NORM_SONG -# define CG_NORM_SONG SONG(AG_NORM_SOUND) -# endif -# ifndef CG_SWAP_SONG -# define CG_SWAP_SONG SONG(AG_SWAP_SOUND) -# endif -float ag_norm_song[][2] = AG_NORM_SONG; -float ag_swap_song[][2] = AG_SWAP_SONG; -float cg_norm_song[][2] = CG_NORM_SONG; -float cg_swap_song[][2] = CG_SWAP_SONG; -#endif - -/** - * MAGIC actions (BOOTMAGIC without the boot) - */ -bool process_magic(uint16_t keycode, keyrecord_t *record) { - // skip anything that isn't a keyup - if (record->event.pressed) { - if (IS_MAGIC_KEYCODE(keycode)) { - /* keymap config */ - keymap_config.raw = eeconfig_read_keymap(); - switch (keycode) { - case QK_MAGIC_SWAP_CONTROL_CAPS_LOCK: - keymap_config.swap_control_capslock = true; - break; - case QK_MAGIC_SWAP_ESCAPE_CAPS_LOCK: - keymap_config.swap_escape_capslock = true; - break; - case QK_MAGIC_CAPS_LOCK_AS_CONTROL_ON: - keymap_config.capslock_to_control = true; - break; - case QK_MAGIC_SWAP_LALT_LGUI: - keymap_config.swap_lalt_lgui = true; - break; - case QK_MAGIC_SWAP_RALT_RGUI: - keymap_config.swap_ralt_rgui = true; - break; - case QK_MAGIC_SWAP_LCTL_LGUI: - keymap_config.swap_lctl_lgui = true; - break; - case QK_MAGIC_SWAP_RCTL_RGUI: - keymap_config.swap_rctl_rgui = true; - break; - case QK_MAGIC_GUI_OFF: - keymap_config.no_gui = true; - break; - case QK_MAGIC_SWAP_GRAVE_ESC: - keymap_config.swap_grave_esc = true; - break; - case QK_MAGIC_SWAP_BACKSLASH_BACKSPACE: - keymap_config.swap_backslash_backspace = true; - break; - case QK_MAGIC_NKRO_ON: - clear_keyboard(); // clear first buffer to prevent stuck keys - keymap_config.nkro = true; - break; - case QK_MAGIC_SWAP_ALT_GUI: - keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = true; -#ifdef AUDIO_ENABLE - PLAY_SONG(ag_swap_song); -#endif - break; - case QK_MAGIC_SWAP_CTL_GUI: - keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = true; -#ifdef AUDIO_ENABLE - PLAY_SONG(cg_swap_song); -#endif - break; - case QK_MAGIC_UNSWAP_CONTROL_CAPS_LOCK: - keymap_config.swap_control_capslock = false; - break; - case QK_MAGIC_UNSWAP_ESCAPE_CAPS_LOCK: - keymap_config.swap_escape_capslock = false; - break; - case QK_MAGIC_CAPS_LOCK_AS_CONTROL_OFF: - keymap_config.capslock_to_control = false; - break; - case QK_MAGIC_UNSWAP_LALT_LGUI: - keymap_config.swap_lalt_lgui = false; - break; - case QK_MAGIC_UNSWAP_RALT_RGUI: - keymap_config.swap_ralt_rgui = false; - break; - case QK_MAGIC_UNSWAP_LCTL_LGUI: - keymap_config.swap_lctl_lgui = false; - break; - case QK_MAGIC_UNSWAP_RCTL_RGUI: - keymap_config.swap_rctl_rgui = false; - break; - case QK_MAGIC_GUI_ON: - keymap_config.no_gui = false; - break; - case QK_MAGIC_UNSWAP_GRAVE_ESC: - keymap_config.swap_grave_esc = false; - break; - case QK_MAGIC_UNSWAP_BACKSLASH_BACKSPACE: - keymap_config.swap_backslash_backspace = false; - break; - case QK_MAGIC_NKRO_OFF: - clear_keyboard(); // clear first buffer to prevent stuck keys - keymap_config.nkro = false; - break; - case QK_MAGIC_UNSWAP_ALT_GUI: - keymap_config.swap_lalt_lgui = keymap_config.swap_ralt_rgui = false; -#ifdef AUDIO_ENABLE - PLAY_SONG(ag_norm_song); -#endif - break; - case QK_MAGIC_UNSWAP_CTL_GUI: - keymap_config.swap_lctl_lgui = keymap_config.swap_rctl_rgui = false; -#ifdef AUDIO_ENABLE - PLAY_SONG(cg_norm_song); -#endif - break; - case QK_MAGIC_TOGGLE_ALT_GUI: - keymap_config.swap_lalt_lgui = !keymap_config.swap_lalt_lgui; - keymap_config.swap_ralt_rgui = keymap_config.swap_lalt_lgui; -#ifdef AUDIO_ENABLE - if (keymap_config.swap_ralt_rgui) { - PLAY_SONG(ag_swap_song); - } else { - PLAY_SONG(ag_norm_song); - } -#endif - break; - case QK_MAGIC_TOGGLE_CTL_GUI: - keymap_config.swap_lctl_lgui = !keymap_config.swap_lctl_lgui; - keymap_config.swap_rctl_rgui = keymap_config.swap_lctl_lgui; -#ifdef AUDIO_ENABLE - if (keymap_config.swap_rctl_rgui) { - PLAY_SONG(cg_swap_song); - } else { - PLAY_SONG(cg_norm_song); - } -#endif - break; - case QK_MAGIC_TOGGLE_BACKSLASH_BACKSPACE: - keymap_config.swap_backslash_backspace = !keymap_config.swap_backslash_backspace; - break; - case QK_MAGIC_TOGGLE_NKRO: - clear_keyboard(); // clear first buffer to prevent stuck keys - keymap_config.nkro = !keymap_config.nkro; - break; - case QK_MAGIC_EE_HANDS_LEFT: - eeconfig_update_handedness(true); - break; - case QK_MAGIC_EE_HANDS_RIGHT: - eeconfig_update_handedness(false); - break; - case QK_MAGIC_TOGGLE_GUI: - keymap_config.no_gui = !keymap_config.no_gui; - break; - case QK_MAGIC_TOGGLE_CONTROL_CAPS_LOCK: - keymap_config.swap_control_capslock = !keymap_config.swap_control_capslock; - break; - case QK_MAGIC_TOGGLE_ESCAPE_CAPS_LOCK: - keymap_config.swap_escape_capslock = !keymap_config.swap_escape_capslock; - break; - } - - eeconfig_update_keymap(keymap_config.raw); - clear_keyboard(); // clear to prevent stuck keys - - return false; - } - } - - // Not a magic keycode so continue processing - return true; -} diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c deleted file mode 100644 index ce62559849a6..000000000000 --- a/quantum/process_keycode/process_midi.c +++ /dev/null @@ -1,276 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ -#include "process_midi.h" - -#ifdef MIDI_ENABLE -# include -# include "midi.h" -# include "qmk_midi.h" - -# ifdef MIDI_BASIC - -void process_midi_basic_noteon(uint8_t note) { - midi_send_noteon(&midi_device, 0, note, 127); -} - -void process_midi_basic_noteoff(uint8_t note) { - midi_send_noteoff(&midi_device, 0, note, 0); -} - -void process_midi_all_notes_off(void) { - midi_send_cc(&midi_device, 0, 0x7B, 0); -} - -# endif // MIDI_BASIC - -# ifdef MIDI_ADVANCED - -# include "timer.h" - -static uint8_t tone_status[2][MIDI_TONE_COUNT]; - -static uint8_t midi_modulation; -static int8_t midi_modulation_step; -static uint16_t midi_modulation_timer; -midi_config_t midi_config; - -inline uint8_t compute_velocity(uint8_t setting) { - return setting * (128 / (MIDI_VELOCITY_MAX - MIDI_VELOCITY_MIN)); -} - -void midi_init(void) { - midi_config.octave = QK_MIDI_OCTAVE_2 - MIDI_OCTAVE_MIN; - midi_config.transpose = 0; - midi_config.velocity = 127; - midi_config.channel = 0; - midi_config.modulation_interval = 8; - - for (uint8_t i = 0; i < MIDI_TONE_COUNT; i++) { - tone_status[0][i] = MIDI_INVALID_NOTE; - tone_status[1][i] = 0; - } - - midi_modulation = 0; - midi_modulation_step = 0; - midi_modulation_timer = 0; -} - -uint8_t midi_compute_note(uint16_t keycode) { - return 12 * midi_config.octave + (keycode - MIDI_TONE_MIN) + midi_config.transpose; -} - -bool process_midi(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case MIDI_TONE_MIN ... MIDI_TONE_MAX: { - uint8_t channel = midi_config.channel; - uint8_t tone = keycode - MIDI_TONE_MIN; - uint8_t velocity = midi_config.velocity; - if (record->event.pressed) { - uint8_t note = midi_compute_note(keycode); - midi_send_noteon(&midi_device, channel, note, velocity); - dprintf("midi noteon channel:%d note:%d velocity:%d\n", channel, note, velocity); - tone_status[1][tone] += 1; - if (tone_status[0][tone] == MIDI_INVALID_NOTE) { - tone_status[0][tone] = note; - } - } else { - uint8_t note = tone_status[0][tone]; - tone_status[1][tone] -= 1; - if (tone_status[1][tone] == 0) { - midi_send_noteoff(&midi_device, channel, note, velocity); - dprintf("midi noteoff channel:%d note:%d velocity:%d\n", channel, note, velocity); - tone_status[0][tone] = MIDI_INVALID_NOTE; - } - } - return false; - } - case MIDI_OCTAVE_MIN ... MIDI_OCTAVE_MAX: - if (record->event.pressed) { - midi_config.octave = keycode - MIDI_OCTAVE_MIN; - dprintf("midi octave %d\n", midi_config.octave); - } - return false; - case QK_MIDI_OCTAVE_DOWN: - if (record->event.pressed && midi_config.octave > 0) { - midi_config.octave--; - dprintf("midi octave %d\n", midi_config.octave); - } - return false; - case QK_MIDI_OCTAVE_UP: - if (record->event.pressed && midi_config.octave < (MIDI_OCTAVE_MAX - MIDI_OCTAVE_MIN)) { - midi_config.octave++; - dprintf("midi octave %d\n", midi_config.octave); - } - return false; - case MIDI_TRANSPOSE_MIN ... MIDI_TRANSPOSE_MAX: - if (record->event.pressed) { - midi_config.transpose = keycode - QK_MIDI_TRANSPOSE_0; - dprintf("midi transpose %d\n", midi_config.transpose); - } - return false; - case QK_MIDI_TRANSPOSE_DOWN: - if (record->event.pressed && midi_config.transpose > (MIDI_TRANSPOSE_MIN - QK_MIDI_TRANSPOSE_0)) { - midi_config.transpose--; - dprintf("midi transpose %d\n", midi_config.transpose); - } - return false; - case QK_MIDI_TRANSPOSE_UP: - if (record->event.pressed && midi_config.transpose < (MIDI_TRANSPOSE_MAX - QK_MIDI_TRANSPOSE_0)) { - const bool positive = midi_config.transpose > 0; - midi_config.transpose++; - if (positive && midi_config.transpose < 0) midi_config.transpose--; - dprintf("midi transpose %d\n", midi_config.transpose); - } - return false; - case MIDI_VELOCITY_MIN ... MIDI_VELOCITY_MAX: - if (record->event.pressed) { - midi_config.velocity = compute_velocity(keycode - MIDI_VELOCITY_MIN); - dprintf("midi velocity %d\n", midi_config.velocity); - } - return false; - case QK_MIDI_VELOCITY_DOWN: - if (record->event.pressed && midi_config.velocity > 0) { - if (midi_config.velocity == 127) { - midi_config.velocity -= 10; - } else if (midi_config.velocity > 12) { - midi_config.velocity -= 13; - } else { - midi_config.velocity = 0; - } - - dprintf("midi velocity %d\n", midi_config.velocity); - } - return false; - case QK_MIDI_VELOCITY_UP: - if (record->event.pressed && midi_config.velocity < 127) { - if (midi_config.velocity < 115) { - midi_config.velocity += 13; - } else { - midi_config.velocity = 127; - } - dprintf("midi velocity %d\n", midi_config.velocity); - } - return false; - case MIDI_CHANNEL_MIN ... MIDI_CHANNEL_MAX: - if (record->event.pressed) { - midi_config.channel = keycode - MIDI_CHANNEL_MIN; - dprintf("midi channel %d\n", midi_config.channel); - } - return false; - case QK_MIDI_CHANNEL_DOWN: - if (record->event.pressed) { - midi_config.channel--; - dprintf("midi channel %d\n", midi_config.channel); - } - return false; - case QK_MIDI_CHANNEL_UP: - if (record->event.pressed) { - midi_config.channel++; - dprintf("midi channel %d\n", midi_config.channel); - } - return false; - case QK_MIDI_ALL_NOTES_OFF: - if (record->event.pressed) { - midi_send_cc(&midi_device, midi_config.channel, 0x7B, 0); - dprintf("midi all notes off\n"); - } - return false; - case QK_MIDI_SUSTAIN: - midi_send_cc(&midi_device, midi_config.channel, 0x40, record->event.pressed ? 127 : 0); - dprintf("midi sustain %d\n", record->event.pressed); - return false; - case QK_MIDI_PORTAMENTO: - midi_send_cc(&midi_device, midi_config.channel, 0x41, record->event.pressed ? 127 : 0); - dprintf("midi portamento %d\n", record->event.pressed); - return false; - case QK_MIDI_SOSTENUTO: - midi_send_cc(&midi_device, midi_config.channel, 0x42, record->event.pressed ? 127 : 0); - dprintf("midi sostenuto %d\n", record->event.pressed); - return false; - case QK_MIDI_SOFT: - midi_send_cc(&midi_device, midi_config.channel, 0x43, record->event.pressed ? 127 : 0); - dprintf("midi soft %d\n", record->event.pressed); - return false; - case QK_MIDI_LEGATO: - midi_send_cc(&midi_device, midi_config.channel, 0x44, record->event.pressed ? 127 : 0); - dprintf("midi legato %d\n", record->event.pressed); - return false; - case QK_MIDI_MODULATION: - midi_modulation_step = record->event.pressed ? 1 : -1; - return false; - case QK_MIDI_MODULATION_SPEED_DOWN: - if (record->event.pressed) { - midi_config.modulation_interval++; - // prevent overflow - if (midi_config.modulation_interval == 0) midi_config.modulation_interval--; - dprintf("midi modulation interval %d\n", midi_config.modulation_interval); - } - return false; - case QK_MIDI_MODULATION_SPEED_UP: - if (record->event.pressed && midi_config.modulation_interval > 0) { - midi_config.modulation_interval--; - dprintf("midi modulation interval %d\n", midi_config.modulation_interval); - } - return false; - case QK_MIDI_PITCH_BEND_DOWN: - if (record->event.pressed) { - midi_send_pitchbend(&midi_device, midi_config.channel, -0x2000); - dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, -0x2000); - } else { - midi_send_pitchbend(&midi_device, midi_config.channel, 0); - dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0); - } - return false; - case QK_MIDI_PITCH_BEND_UP: - if (record->event.pressed) { - midi_send_pitchbend(&midi_device, midi_config.channel, 0x1fff); - dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0x1fff); - } else { - midi_send_pitchbend(&midi_device, midi_config.channel, 0); - dprintf("midi pitchbend channel:%d amount:%d\n", midi_config.channel, 0); - } - return false; - }; - - return true; -} - -# endif // MIDI_ADVANCED - -void midi_task(void) { - midi_device_process(&midi_device); -# ifdef MIDI_ADVANCED - if (timer_elapsed(midi_modulation_timer) < midi_config.modulation_interval) return; - midi_modulation_timer = timer_read(); - - if (midi_modulation_step != 0) { - dprintf("midi modulation %d\n", midi_modulation); - midi_send_cc(&midi_device, midi_config.channel, 0x1, midi_modulation); - - if (midi_modulation_step < 0 && midi_modulation < -midi_modulation_step) { - midi_modulation = 0; - midi_modulation_step = 0; - return; - } - - midi_modulation += midi_modulation_step; - - if (midi_modulation > 127) midi_modulation = 127; - } -# endif -} - -#endif // MIDI_ENABLE diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h deleted file mode 100644 index e528c6ec0cab..000000000000 --- a/quantum/process_keycode/process_midi.h +++ /dev/null @@ -1,54 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -#ifdef MIDI_ENABLE - -# ifdef MIDI_BASIC -void process_midi_basic_noteon(uint8_t note); -void process_midi_basic_noteoff(uint8_t note); -void process_midi_all_notes_off(void); -# endif - -void midi_task(void); - -# ifdef MIDI_ADVANCED -typedef union { - uint32_t raw; - struct { - uint8_t octave : 4; - int8_t transpose : 4; - uint8_t velocity : 7; - uint8_t channel : 4; - uint8_t modulation_interval : 4; - }; -} midi_config_t; - -extern midi_config_t midi_config; - -void midi_init(void); -bool process_midi(uint16_t keycode, keyrecord_t *record); - -# define MIDI_INVALID_NOTE 0xFF -# define MIDI_TONE_COUNT (MIDI_TONE_MAX - MIDI_TONE_MIN + 1) - -uint8_t midi_compute_note(uint16_t keycode); -# endif // MIDI_ADVANCED - -#endif // MIDI_ENABLE diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c deleted file mode 100644 index 7c572079a719..000000000000 --- a/quantum/process_keycode/process_music.c +++ /dev/null @@ -1,326 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ -#include "process_music.h" - -#ifdef AUDIO_ENABLE -# include "process_audio.h" -#endif -#if defined(MIDI_ENABLE) && defined(MIDI_BASIC) -# include "process_midi.h" -#endif - -#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) - -bool music_activated = false; -bool midi_activated = false; -uint8_t music_starting_note = 0x0C; -int music_offset = 7; -uint8_t music_mode = MUSIC_MODE_MAJOR; - -// music sequencer -static bool music_sequence_recording = false; -static bool music_sequence_recorded = false; -static bool music_sequence_playing = false; -static uint8_t music_sequence[16] = {0}; -static uint8_t music_sequence_count = 0; -static uint8_t music_sequence_position = 0; - -static uint16_t music_sequence_timer = 0; -static uint16_t music_sequence_interval = 100; - -# ifdef AUDIO_ENABLE -# ifndef MUSIC_ON_SONG -# define MUSIC_ON_SONG SONG(MUSIC_ON_SOUND) -# endif -# ifndef MUSIC_OFF_SONG -# define MUSIC_OFF_SONG SONG(MUSIC_OFF_SOUND) -# endif -# ifndef MIDI_ON_SONG -# define MIDI_ON_SONG SONG(MUSIC_ON_SOUND) -# endif -# ifndef MIDI_OFF_SONG -# define MIDI_OFF_SONG SONG(MUSIC_OFF_SOUND) -# endif -# ifndef CHROMATIC_SONG -# define CHROMATIC_SONG SONG(CHROMATIC_SOUND) -# endif -# ifndef GUITAR_SONG -# define GUITAR_SONG SONG(GUITAR_SOUND) -# endif -# ifndef VIOLIN_SONG -# define VIOLIN_SONG SONG(VIOLIN_SOUND) -# endif -# ifndef MAJOR_SONG -# define MAJOR_SONG SONG(MAJOR_SOUND) -# endif -float music_mode_songs[NUMBER_OF_MODES][5][2] = {CHROMATIC_SONG, GUITAR_SONG, VIOLIN_SONG, MAJOR_SONG}; -float music_on_song[][2] = MUSIC_ON_SONG; -float music_off_song[][2] = MUSIC_OFF_SONG; -float midi_on_song[][2] = MIDI_ON_SONG; -float midi_off_song[][2] = MIDI_OFF_SONG; -# endif - -static void music_noteon(uint8_t note) { -# ifdef AUDIO_ENABLE - if (music_activated) process_audio_noteon(note); -# endif -# if defined(MIDI_ENABLE) && defined(MIDI_BASIC) - if (midi_activated) process_midi_basic_noteon(note); -# endif -} - -static void music_noteoff(uint8_t note) { -# ifdef AUDIO_ENABLE - if (music_activated) process_audio_noteoff(note); -# endif -# if defined(MIDI_ENABLE) && defined(MIDI_BASIC) - if (midi_activated) process_midi_basic_noteoff(note); -# endif -} - -void music_all_notes_off(void) { -# ifdef AUDIO_ENABLE - if (music_activated) process_audio_all_notes_off(); -# endif -# if defined(MIDI_ENABLE) && defined(MIDI_BASIC) - if (midi_activated) process_midi_all_notes_off(); -# endif -} - -bool process_music(uint16_t keycode, keyrecord_t *record) { - if (keycode == QK_MUSIC_ON && record->event.pressed) { - music_on(); - return false; - } - - if (keycode == QK_MUSIC_OFF && record->event.pressed) { - music_off(); - return false; - } - - if (keycode == QK_MUSIC_TOGGLE && record->event.pressed) { - if (music_activated) { - music_off(); - } else { - music_on(); - } - return false; - } - - if (keycode == QK_MIDI_ON && record->event.pressed) { - midi_on(); - return false; - } - - if (keycode == QK_MIDI_OFF && record->event.pressed) { - midi_off(); - return false; - } - - if (keycode == QK_MIDI_TOGGLE && record->event.pressed) { - if (midi_activated) { - midi_off(); - } else { - midi_on(); - } - return false; - } - - if (keycode == QK_MUSIC_MODE_NEXT && record->event.pressed) { - music_mode_cycle(); - return false; - } - - if (music_activated || midi_activated) { - if (record->event.pressed) { - if (keycode == KC_LEFT_CTRL) { // Start recording - music_all_notes_off(); - music_sequence_recording = true; - music_sequence_recorded = false; - music_sequence_playing = false; - music_sequence_count = 0; - return false; - } - - if (keycode == KC_LEFT_ALT) { // Stop recording/playing - music_all_notes_off(); - if (music_sequence_recording) { // was recording - music_sequence_recorded = true; - } - music_sequence_recording = false; - music_sequence_playing = false; - return false; - } - - if (keycode == KC_LEFT_GUI && music_sequence_recorded) { // Start playing - music_all_notes_off(); - music_sequence_recording = false; - music_sequence_playing = true; - music_sequence_position = 0; - music_sequence_timer = 0; - return false; - } - - if (keycode == KC_UP) { - music_sequence_interval -= 10; - return false; - } - - if (keycode == KC_DOWN) { - music_sequence_interval += 10; - return false; - } - } - - uint8_t note = 36; -# ifdef MUSIC_MAP - if (music_mode == MUSIC_MODE_CHROMATIC) { - note = music_starting_note + music_offset + 36 + music_map[record->event.key.row][record->event.key.col]; - } else { - uint8_t position = music_map[record->event.key.row][record->event.key.col]; - note = music_starting_note + music_offset + 36 + SCALE[position % 7] + (position / 7) * 12; - } -# else - if (music_mode == MUSIC_MODE_CHROMATIC) - note = (music_starting_note + record->event.key.col + music_offset - 3) + 12 * (MATRIX_ROWS - record->event.key.row); - else if (music_mode == MUSIC_MODE_GUITAR) - note = (music_starting_note + record->event.key.col + music_offset + 32) + 5 * (MATRIX_ROWS - record->event.key.row); - else if (music_mode == MUSIC_MODE_VIOLIN) - note = (music_starting_note + record->event.key.col + music_offset + 32) + 7 * (MATRIX_ROWS - record->event.key.row); - else if (music_mode == MUSIC_MODE_MAJOR) - note = (music_starting_note + SCALE[record->event.key.col + music_offset] - 3) + 12 * (MATRIX_ROWS - record->event.key.row); - else - note = music_starting_note; -# endif - - if (record->event.pressed) { - music_noteon(note); - if (music_sequence_recording) { - music_sequence[music_sequence_count] = note; - music_sequence_count++; - } - } else { - music_noteoff(note); - } - - if (music_mask(keycode)) return false; - } - - return true; -} - -bool music_mask(uint16_t keycode) { -# ifdef MUSIC_MASK - return MUSIC_MASK; -# else - return music_mask_kb(keycode); -# endif -} - -__attribute__((weak)) bool music_mask_kb(uint16_t keycode) { - return music_mask_user(keycode); -} - -__attribute__((weak)) bool music_mask_user(uint16_t keycode) { - return keycode < 0xFF; -} - -bool is_music_on(void) { - return (music_activated != 0); -} - -void music_toggle(void) { - if (!music_activated) { - music_on(); - } else { - music_off(); - } -} - -void music_on(void) { - music_activated = 1; -# ifdef AUDIO_ENABLE - PLAY_SONG(music_on_song); -# endif - music_on_user(); -} - -void music_off(void) { - music_all_notes_off(); - music_activated = 0; -# ifdef AUDIO_ENABLE - PLAY_SONG(music_off_song); -# endif -} - -bool is_midi_on(void) { - return (midi_activated != 0); -} - -void midi_toggle(void) { - if (!midi_activated) { - midi_on(); - } else { - midi_off(); - } -} - -void midi_on(void) { - midi_activated = 1; -# ifdef AUDIO_ENABLE - PLAY_SONG(midi_on_song); -# endif - midi_on_user(); -} - -void midi_off(void) { -# if defined(MIDI_ENABLE) && defined(MIDI_BASIC) - process_midi_all_notes_off(); -# endif - midi_activated = 0; -# ifdef AUDIO_ENABLE - PLAY_SONG(midi_off_song); -# endif -} - -void music_mode_cycle(void) { - music_all_notes_off(); - music_mode = (music_mode + 1) % NUMBER_OF_MODES; -# ifdef AUDIO_ENABLE - PLAY_SONG(music_mode_songs[music_mode]); -# endif -} - -void music_task(void) { - if (music_sequence_playing) { - if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { - music_sequence_timer = timer_read(); - uint8_t prev_note = music_sequence[(music_sequence_position - 1 < 0) ? (music_sequence_position - 1 + music_sequence_count) : (music_sequence_position - 1)]; - uint8_t next_note = music_sequence[music_sequence_position]; - music_noteoff(prev_note); - music_noteon(next_note); - music_sequence_position = (music_sequence_position + 1) % music_sequence_count; - } - } -} - -__attribute__((weak)) void music_on_user(void) {} - -__attribute__((weak)) void midi_on_user(void) {} - -__attribute__((weak)) void music_scale_user(void) {} - -#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h deleted file mode 100644 index 83726a05ba9f..000000000000 --- a/quantum/process_keycode/process_music.h +++ /dev/null @@ -1,60 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) - -enum music_modes { MUSIC_MODE_CHROMATIC, MUSIC_MODE_GUITAR, MUSIC_MODE_VIOLIN, MUSIC_MODE_MAJOR, NUMBER_OF_MODES }; - -# ifdef MUSIC_MAP -extern const uint8_t music_map[MATRIX_ROWS][MATRIX_COLS]; -# endif - -bool process_music(uint16_t keycode, keyrecord_t *record); - -bool is_music_on(void); -void music_toggle(void); -void music_on(void); -void music_off(void); - -bool is_midi_on(void); -void midi_toggle(void); -void midi_on(void); -void midi_off(void); - -void music_on_user(void); -void midi_on_user(void); -void music_scale_user(void); -void music_all_notes_off(void); -void music_mode_cycle(void); - -void music_task(void); - -bool music_mask(uint16_t keycode); -bool music_mask_kb(uint16_t keycode); -bool music_mask_user(uint16_t keycode); - -# ifndef SCALE -# define SCALE \ - (int8_t[]) { \ - 0 + (12 * 0), 2 + (12 * 0), 4 + (12 * 0), 5 + (12 * 0), 7 + (12 * 0), 9 + (12 * 0), 11 + (12 * 0), 0 + (12 * 1), 2 + (12 * 1), 4 + (12 * 1), 5 + (12 * 1), 7 + (12 * 1), 9 + (12 * 1), 11 + (12 * 1), 0 + (12 * 2), 2 + (12 * 2), 4 + (12 * 2), 5 + (12 * 2), 7 + (12 * 2), 9 + (12 * 2), 11 + (12 * 2), 0 + (12 * 3), 2 + (12 * 3), 4 + (12 * 3), 5 + (12 * 3), 7 + (12 * 3), 9 + (12 * 3), 11 + (12 * 3), 0 + (12 * 4), 2 + (12 * 4), 4 + (12 * 4), 5 + (12 * 4), 7 + (12 * 4), 9 + (12 * 4), 11 + (12 * 4), \ - } -# endif - -#endif // defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) diff --git a/quantum/process_keycode/process_programmable_button.c b/quantum/process_keycode/process_programmable_button.c deleted file mode 100644 index 03034edb6125..000000000000 --- a/quantum/process_keycode/process_programmable_button.c +++ /dev/null @@ -1,31 +0,0 @@ -/* -Copyright 2021 Thomas Weißschuh - -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 . -*/ - -#include "process_programmable_button.h" -#include "programmable_button.h" - -bool process_programmable_button(uint16_t keycode, keyrecord_t *record) { - if (IS_QK_PROGRAMMABLE_BUTTON(keycode)) { - uint8_t button = keycode - QK_PROGRAMMABLE_BUTTON + 1; - if (record->event.pressed) { - programmable_button_register(button); - } else { - programmable_button_unregister(button); - } - } - return true; -} diff --git a/quantum/process_keycode/process_programmable_button.h b/quantum/process_keycode/process_programmable_button.h deleted file mode 100644 index 47c6ce561440..000000000000 --- a/quantum/process_keycode/process_programmable_button.h +++ /dev/null @@ -1,23 +0,0 @@ -/* -Copyright 2021 Thomas Weißschuh - -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 . -*/ - -#pragma once - -#include -#include "quantum.h" - -bool process_programmable_button(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_repeat_key.c b/quantum/process_keycode/process_repeat_key.c deleted file mode 100644 index f819aa226e91..000000000000 --- a/quantum/process_keycode/process_repeat_key.c +++ /dev/null @@ -1,109 +0,0 @@ -// Copyright 2022-2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "process_repeat_key.h" - -// Default implementation of remember_last_key_user(). -__attribute__((weak)) bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) { - return true; -} - -static bool remember_last_key(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods) { - switch (keycode) { - // Ignore MO, TO, TG, TT, and TL layer switch keys. - case QK_MOMENTARY ... QK_MOMENTARY_MAX: - case QK_TO ... QK_TO_MAX: - case QK_TOGGLE_LAYER ... QK_TOGGLE_LAYER_MAX: - case QK_LAYER_TAP_TOGGLE ... QK_LAYER_TAP_TOGGLE_MAX: - // Ignore mod keys. - case KC_LCTL ... KC_RGUI: - case KC_HYPR: - case KC_MEH: -#ifndef NO_ACTION_ONESHOT // Ignore one-shot keys. - case QK_ONE_SHOT_LAYER ... QK_ONE_SHOT_LAYER_MAX: - case QK_ONE_SHOT_MOD ... QK_ONE_SHOT_MOD_MAX: -#endif // NO_ACTION_ONESHOT -#ifdef TRI_LAYER_ENABLE // Ignore Tri Layer keys. - case QK_TRI_LAYER_LOWER: - case QK_TRI_LAYER_UPPER: -#endif // TRI_LAYER_ENABLE - return false; - - // Ignore hold events on tap-hold keys. -#ifndef NO_ACTION_TAPPING - case QK_MOD_TAP ... QK_MOD_TAP_MAX: -# ifndef NO_ACTION_LAYER - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: -# endif // NO_ACTION_LAYER - if (record->tap.count == 0) { - return false; - } - break; -#endif // NO_ACTION_TAPPING - -#ifdef SWAP_HANDS_ENABLE - case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: - if (IS_SWAP_HANDS_KEYCODE(keycode) || record->tap.count == 0) { - return false; - } - break; -#endif // SWAP_HANDS_ENABLE - - case QK_REPEAT_KEY: -#ifndef NO_ALT_REPEAT_KEY - case QK_ALT_REPEAT_KEY: -#endif // NO_ALT_REPEAT_KEY - return false; - } - - return remember_last_key_user(keycode, record, remembered_mods); -} - -bool process_last_key(uint16_t keycode, keyrecord_t* record) { - if (get_repeat_key_count()) { - return true; - } - - if (record->event.pressed) { - uint8_t remembered_mods = get_mods() | get_weak_mods(); -#ifndef NO_ACTION_ONESHOT - remembered_mods |= get_oneshot_mods(); -#endif // NO_ACTION_ONESHOT - - if (remember_last_key(keycode, record, &remembered_mods)) { - set_last_record(keycode, record); - set_last_mods(remembered_mods); - } - } - - return true; -} - -bool process_repeat_key(uint16_t keycode, keyrecord_t* record) { - if (get_repeat_key_count()) { - return true; - } - - if (keycode == QK_REPEAT_KEY) { - repeat_key_invoke(&record->event); - return false; -#ifndef NO_ALT_REPEAT_KEY - } else if (keycode == QK_ALT_REPEAT_KEY) { - alt_repeat_key_invoke(&record->event); - return false; -#endif // NO_ALT_REPEAT_KEY - } - - return true; -} diff --git a/quantum/process_keycode/process_repeat_key.h b/quantum/process_keycode/process_repeat_key.h deleted file mode 100644 index eddc50f254c9..000000000000 --- a/quantum/process_keycode/process_repeat_key.h +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2022-2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "quantum.h" - -/** - * @brief Process handler for remembering the last key. - * - * @param keycode Keycode registered by matrix press, per keymap - * @param record keyrecord_t structure - * @return true Continue processing keycodes, and send to host - * @return false Stop processing keycodes, and don't send to host - */ -bool process_last_key(uint16_t keycode, keyrecord_t* record); - -/** - * @brief Optional callback defining which keys are remembered. - * - * @param keycode Keycode that was just pressed - * @param record keyrecord_t structure - * @param remembered_mods Mods that will be remembered with this key - * @return true Key is remembered - * @return false Key is ignored - * - * Modifier and layer switch keys are always ignored. For all other keys, this - * callback is called on every key press. Returning true means that the key is - * remembered, false means it is ignored. By default, all non-modifier, - * non-layer switch keys are remembered. - * - * The `remembered_mods` arg represents the mods that will be remembered with - * this key. It can be modified to forget certain mods, for instance to forget - * capitalization when repeating shifted letters: - * - * // Forget Shift on letter keys. - * if (KC_A <= keycode && keycode <= KC_Z && (*remembered_mods & ~MOD_MASK_SHIFT) == 0) { - * *remembered_mods = 0; - * } - */ -bool remember_last_key_user(uint16_t keycode, keyrecord_t* record, uint8_t* remembered_mods); - -/** - * @brief Process handler for Repeat Key feature. - * - * @param keycode Keycode registered by matrix press, per keymap - * @param record keyrecord_t structure - * @return true Continue processing keycodes, and send to host - * @return false Stop processing keycodes, and don't send to host - */ -bool process_repeat_key(uint16_t keycode, keyrecord_t* record); diff --git a/quantum/process_keycode/process_rgb.c b/quantum/process_keycode/process_rgb.c deleted file mode 100644 index dae129786e22..000000000000 --- a/quantum/process_keycode/process_rgb.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#include "process_rgb.h" - -typedef void (*rgb_func_pointer)(void); - -/** - * Wrapper for inc/dec rgb keycode - * - * noinline to optimise for firmware size not speed (not in hot path) - */ -#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)) -static void __attribute__((noinline)) handleKeycodeRGB(const uint8_t is_shifted, const rgb_func_pointer inc_func, const rgb_func_pointer dec_func) { - if (is_shifted) { - dec_func(); - } else { - inc_func(); - } -} -#endif - -/** - * Wrapper for animation mode - * - if not in animation family -> jump to that animation - * - otherwise -> wrap round animation speed - * - * noinline to optimise for firmware size not speed (not in hot path) - */ -static void __attribute__((noinline, unused)) handleKeycodeRGBMode(const uint8_t start, const uint8_t end) { - if ((start <= rgblight_get_mode()) && (rgblight_get_mode() < end)) { - rgblight_step(); - } else { - rgblight_mode(start); - } -} - -/** - * Handle keycodes for both rgblight and rgbmatrix - */ -bool process_rgb(const uint16_t keycode, const keyrecord_t *record) { - // need to trigger on key-up for edge-case issue -#ifndef RGB_TRIGGER_ON_KEYDOWN - if (!record->event.pressed) { -#else - if (record->event.pressed) { -#endif -#if (defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES)) || (defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES)) - uint8_t shifted = get_mods() & MOD_MASK_SHIFT; -#endif - switch (keycode) { - case RGB_TOG: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - rgblight_toggle(); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - rgb_matrix_toggle(); -#endif - return false; - case RGB_MODE_FORWARD: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_step, rgblight_step_reverse); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_step, rgb_matrix_step_reverse); -#endif - return false; - case RGB_MODE_REVERSE: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_step_reverse, rgblight_step); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_step_reverse, rgb_matrix_step); -#endif - return false; - case RGB_HUI: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_increase_hue, rgblight_decrease_hue); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_increase_hue, rgb_matrix_decrease_hue); -#endif - return false; - case RGB_HUD: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_decrease_hue, rgblight_increase_hue); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_decrease_hue, rgb_matrix_increase_hue); -#endif - return false; - case RGB_SAI: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_increase_sat, rgblight_decrease_sat); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_increase_sat, rgb_matrix_decrease_sat); -#endif - return false; - case RGB_SAD: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_decrease_sat, rgblight_increase_sat); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_decrease_sat, rgb_matrix_increase_sat); -#endif - return false; - case RGB_VAI: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_increase_val, rgblight_decrease_val); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_increase_val, rgb_matrix_decrease_val); -#endif - return false; - case RGB_VAD: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_decrease_val, rgblight_increase_val); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_decrease_val, rgb_matrix_increase_val); -#endif - return false; - case RGB_SPI: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_increase_speed, rgblight_decrease_speed); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_increase_speed, rgb_matrix_decrease_speed); -#endif - return false; - case RGB_SPD: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgblight_decrease_speed, rgblight_increase_speed); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - handleKeycodeRGB(shifted, rgb_matrix_decrease_speed, rgb_matrix_increase_speed); -#endif - return false; - case RGB_MODE_PLAIN: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) - rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) - rgb_matrix_mode(RGB_MATRIX_SOLID_COLOR); -#endif - return false; - case RGB_MODE_BREATHE: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_BREATHING) - handleKeycodeRGBMode(RGBLIGHT_MODE_BREATHING, RGBLIGHT_MODE_BREATHING_end); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_BREATHING) - rgb_matrix_mode(RGB_MATRIX_BREATHING); -#endif - return false; - case RGB_MODE_RAINBOW: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) - handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_MOOD, RGBLIGHT_MODE_RAINBOW_MOOD_end); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT) - rgb_matrix_mode(RGB_MATRIX_CYCLE_LEFT_RIGHT); -#endif - return false; - case RGB_MODE_SWIRL: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) - handleKeycodeRGBMode(RGBLIGHT_MODE_RAINBOW_SWIRL, RGBLIGHT_MODE_RAINBOW_SWIRL_end); -#endif -#if defined(RGB_MATRIX_ENABLE) && !defined(RGB_MATRIX_DISABLE_KEYCODES) && defined(ENABLE_RGB_MATRIX_CYCLE_PINWHEEL) - rgb_matrix_mode(RGB_MATRIX_CYCLE_PINWHEEL); -#endif - return false; - case RGB_MODE_SNAKE: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_SNAKE) - handleKeycodeRGBMode(RGBLIGHT_MODE_SNAKE, RGBLIGHT_MODE_SNAKE_end); -#endif - return false; - case RGB_MODE_KNIGHT: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_KNIGHT) - handleKeycodeRGBMode(RGBLIGHT_MODE_KNIGHT, RGBLIGHT_MODE_KNIGHT_end); -#endif - return false; - case RGB_MODE_XMAS: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_CHRISTMAS) - rgblight_mode(RGBLIGHT_MODE_CHRISTMAS); -#endif - return false; - case RGB_MODE_GRADIENT: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_STATIC_GRADIENT) - handleKeycodeRGBMode(RGBLIGHT_MODE_STATIC_GRADIENT, RGBLIGHT_MODE_STATIC_GRADIENT_end); -#endif - return false; - case RGB_MODE_RGBTEST: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_RGB_TEST) - rgblight_mode(RGBLIGHT_MODE_RGB_TEST); -#endif - return false; - case RGB_MODE_TWINKLE: -#if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_DISABLE_KEYCODES) && defined(RGBLIGHT_EFFECT_TWINKLE) - handleKeycodeRGBMode(RGBLIGHT_MODE_TWINKLE, RGBLIGHT_MODE_TWINKLE_end); -#endif - return false; - } - } - - return true; -} diff --git a/quantum/process_keycode/process_rgb.h b/quantum/process_keycode/process_rgb.h deleted file mode 100644 index 26aca46896bc..000000000000 --- a/quantum/process_keycode/process_rgb.h +++ /dev/null @@ -1,20 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ -#pragma once - -#include "quantum.h" - -bool process_rgb(const uint16_t keycode, const keyrecord_t *record); diff --git a/quantum/process_keycode/process_secure.c b/quantum/process_keycode/process_secure.c deleted file mode 100644 index 894051fb3363..000000000000 --- a/quantum/process_keycode/process_secure.c +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2022 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "secure.h" -#include "process_secure.h" -#include "quantum_keycodes.h" - -bool preprocess_secure(uint16_t keycode, keyrecord_t *record) { - if (secure_is_unlocking()) { - // !pressed will trigger on any already held keys (such as layer keys), - // and cause the request secure check to prematurely fail. - if (record->event.pressed) { - secure_keypress_event(record->event.key.row, record->event.key.col); - } - - // Normal keypresses should be disabled until the sequence is completed - return false; - } - - return true; -} - -bool process_secure(uint16_t keycode, keyrecord_t *record) { -#ifndef SECURE_DISABLE_KEYCODES - if (!record->event.pressed) { - if (keycode == QK_SECURE_LOCK) { - secure_lock(); - return false; - } - if (keycode == QK_SECURE_UNLOCK) { - secure_unlock(); - return false; - } - if (keycode == QK_SECURE_TOGGLE) { - secure_is_locked() ? secure_unlock() : secure_lock(); - return false; - } - if (keycode == QK_SECURE_REQUEST) { - secure_request_unlock(); - return false; - } - } -#endif - return true; -} diff --git a/quantum/process_keycode/process_secure.h b/quantum/process_keycode/process_secure.h deleted file mode 100644 index 2814264b92f5..000000000000 --- a/quantum/process_keycode/process_secure.h +++ /dev/null @@ -1,15 +0,0 @@ -// Copyright 2022 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include "action.h" - -/** \brief Intercept keycodes and detect unlock sequences - */ -bool preprocess_secure(uint16_t keycode, keyrecord_t *record); - -/** \brief Handle any secure specific keycodes - */ -bool process_secure(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_sequencer.c b/quantum/process_keycode/process_sequencer.c deleted file mode 100644 index 6391d1ba9d5e..000000000000 --- a/quantum/process_keycode/process_sequencer.c +++ /dev/null @@ -1,62 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#include "process_sequencer.h" - -bool process_sequencer(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - switch (keycode) { - case QK_SEQUENCER_ON: - sequencer_on(); - return false; - case QK_SEQUENCER_OFF: - sequencer_off(); - return false; - case QK_SEQUENCER_TOGGLE: - sequencer_toggle(); - return false; - case QK_SEQUENCER_TEMPO_DOWN: - sequencer_decrease_tempo(); - return false; - case QK_SEQUENCER_TEMPO_UP: - sequencer_increase_tempo(); - return false; - case QK_SEQUENCER_RESOLUTION_DOWN: - sequencer_decrease_resolution(); - return false; - case QK_SEQUENCER_RESOLUTION_UP: - sequencer_increase_resolution(); - return false; - case QK_SEQUENCER_STEPS_ALL: - sequencer_set_all_steps_on(); - return false; - case QK_SEQUENCER_STEPS_CLEAR: - sequencer_set_all_steps_off(); - return false; - case SEQUENCER_STEP_MIN ... SEQUENCER_STEP_MAX: - sequencer_toggle_step(keycode - SEQUENCER_STEP_MIN); - return false; - case SEQUENCER_RESOLUTION_MIN ... SEQUENCER_RESOLUTION_MAX: - sequencer_set_resolution(keycode - SEQUENCER_RESOLUTION_MIN); - return false; - case SEQUENCER_TRACK_MIN ... SEQUENCER_TRACK_MAX: - sequencer_toggle_single_active_track(keycode - SEQUENCER_TRACK_MIN); - return false; - } - } - - return true; -} diff --git a/quantum/process_keycode/process_sequencer.h b/quantum/process_keycode/process_sequencer.h deleted file mode 100644 index 2b85f24299ed..000000000000 --- a/quantum/process_keycode/process_sequencer.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -bool process_sequencer(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_space_cadet.c b/quantum/process_keycode/process_space_cadet.c deleted file mode 100644 index 3109ea17114a..000000000000 --- a/quantum/process_keycode/process_space_cadet.c +++ /dev/null @@ -1,161 +0,0 @@ -/* Copyright 2019 Jack Humbert - * - * 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 . - */ -#include "process_space_cadet.h" -#include "action_tapping.h" - -// ********** OBSOLETE DEFINES, STOP USING! (pls?) ********** -// Shift / paren setup -#ifndef LSPO_KEY -# define LSPO_KEY KC_9 -#endif -#ifndef RSPC_KEY -# define RSPC_KEY KC_0 -#endif - -// Shift / Enter setup -#ifndef SFTENT_KEY -# define SFTENT_KEY KC_ENTER -#endif - -#ifdef DISABLE_SPACE_CADET_MODIFIER -# ifndef LSPO_MOD -# define LSPO_MOD KC_TRANSPARENT -# endif -# ifndef RSPC_MOD -# define RSPC_MOD KC_TRANSPARENT -# endif -#else -# ifndef LSPO_MOD -# define LSPO_MOD KC_LEFT_SHIFT -# endif -# ifndef RSPC_MOD -# define RSPC_MOD KC_RIGHT_SHIFT -# endif -#endif -// ********************************************************** - -// Shift / paren setup -#ifndef LSPO_KEYS -# define LSPO_KEYS KC_LEFT_SHIFT, LSPO_MOD, LSPO_KEY -#endif -#ifndef RSPC_KEYS -# define RSPC_KEYS KC_RIGHT_SHIFT, RSPC_MOD, RSPC_KEY -#endif - -// Control / paren setup -#ifndef LCPO_KEYS -# define LCPO_KEYS KC_LEFT_CTRL, KC_LEFT_SHIFT, KC_9 -#endif -#ifndef RCPC_KEYS -# define RCPC_KEYS KC_RIGHT_CTRL, KC_RIGHT_SHIFT, KC_0 -#endif - -// Alt / paren setup -#ifndef LAPO_KEYS -# define LAPO_KEYS KC_LEFT_ALT, KC_LEFT_SHIFT, KC_9 -#endif -#ifndef RAPC_KEYS -# define RAPC_KEYS KC_RIGHT_ALT, KC_RIGHT_SHIFT, KC_0 -#endif - -// Shift / Enter setup -#ifndef SFTENT_KEYS -# define SFTENT_KEYS KC_RIGHT_SHIFT, KC_TRANSPARENT, SFTENT_KEY -#endif - -static uint8_t sc_last = 0; -static uint16_t sc_timer = 0; -#ifdef SPACE_CADET_MODIFIER_CARRYOVER -static uint8_t sc_mods = 0; -#endif - -void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode) { - if (record->event.pressed) { - sc_last = holdMod; - sc_timer = timer_read(); -#ifdef SPACE_CADET_MODIFIER_CARRYOVER - sc_mods = get_mods(); -#endif - if (IS_MODIFIER_KEYCODE(holdMod)) { - register_mods(MOD_BIT(holdMod)); - } - } else { - if (sc_last == holdMod && timer_elapsed(sc_timer) < GET_TAPPING_TERM(sc_keycode, record)) { - if (holdMod != tapMod) { - if (IS_MODIFIER_KEYCODE(holdMod)) { - unregister_mods(MOD_BIT(holdMod)); - } - if (IS_MODIFIER_KEYCODE(tapMod)) { - register_mods(MOD_BIT(tapMod)); - } - } -#ifdef SPACE_CADET_MODIFIER_CARRYOVER - set_weak_mods(sc_mods); -#endif - tap_code(keycode); -#ifdef SPACE_CADET_MODIFIER_CARRYOVER - clear_weak_mods(); -#endif - if (IS_MODIFIER_KEYCODE(tapMod)) { - unregister_mods(MOD_BIT(tapMod)); - } - } else { - if (IS_MODIFIER_KEYCODE(holdMod)) { - unregister_mods(MOD_BIT(holdMod)); - } - } - } -} - -bool process_space_cadet(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_SPACE_CADET_LEFT_SHIFT_PARENTHESIS_OPEN: { - perform_space_cadet(record, keycode, LSPO_KEYS); - return false; - } - case QK_SPACE_CADET_RIGHT_SHIFT_PARENTHESIS_CLOSE: { - perform_space_cadet(record, keycode, RSPC_KEYS); - return false; - } - case QK_SPACE_CADET_LEFT_CTRL_PARENTHESIS_OPEN: { - perform_space_cadet(record, keycode, LCPO_KEYS); - return false; - } - case QK_SPACE_CADET_RIGHT_CTRL_PARENTHESIS_CLOSE: { - perform_space_cadet(record, keycode, RCPC_KEYS); - return false; - } - case QK_SPACE_CADET_LEFT_ALT_PARENTHESIS_OPEN: { - perform_space_cadet(record, keycode, LAPO_KEYS); - return false; - } - case QK_SPACE_CADET_RIGHT_ALT_PARENTHESIS_CLOSE: { - perform_space_cadet(record, keycode, RAPC_KEYS); - return false; - } - case QK_SPACE_CADET_RIGHT_SHIFT_ENTER: { - perform_space_cadet(record, keycode, SFTENT_KEYS); - return false; - } - default: { - if (record->event.pressed) { - sc_last = 0; - } - break; - } - } - return true; -} diff --git a/quantum/process_keycode/process_space_cadet.h b/quantum/process_keycode/process_space_cadet.h deleted file mode 100644 index fcb70f3b4369..000000000000 --- a/quantum/process_keycode/process_space_cadet.h +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright 2019 Jack Humbert - * - * 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 . - */ -#pragma once - -#include "quantum.h" - -void perform_space_cadet(keyrecord_t *record, uint16_t sc_keycode, uint8_t holdMod, uint8_t tapMod, uint8_t keycode); -bool process_space_cadet(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_steno.c b/quantum/process_keycode/process_steno.c deleted file mode 100644 index d5ad61ba8581..000000000000 --- a/quantum/process_keycode/process_steno.c +++ /dev/null @@ -1,249 +0,0 @@ -/* Copyright 2017, 2022 Joseph Wasson, Vladislav Kucheriavykh - * - * 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 . - */ -#include "process_steno.h" -#include "quantum_keycodes.h" -#include "keymap_steno.h" -#include -#ifdef VIRTSER_ENABLE -# include "virtser.h" -#endif -#ifdef STENO_ENABLE_ALL -# include "eeprom.h" -#endif - -// All steno keys that have been pressed to form this chord, -// stored in MAX_STROKE_SIZE groups of 8-bit arrays. -static uint8_t chord[MAX_STROKE_SIZE] = {0}; -// The number of physical keys actually being held down. -// This is not always equal to the number of 1 bits in `chord` because it is possible to -// simultaneously press down four keys, then release three of those four keys and then press yet -// another key while the fourth finger is still holding down its key. -// At the end of this scenario given as an example, `chord` would have five bits set to 1 but -// `n_pressed_keys` would be set to 2 because there are only two keys currently being pressed down. -static int8_t n_pressed_keys = 0; - -#ifdef STENO_ENABLE_ALL -static steno_mode_t mode; -#elif defined(STENO_ENABLE_GEMINI) -static const steno_mode_t mode = STENO_MODE_GEMINI; -#elif defined(STENO_ENABLE_BOLT) -static const steno_mode_t mode = STENO_MODE_BOLT; -#endif - -static inline void steno_clear_chord(void) { - memset(chord, 0, sizeof(chord)); -} - -#ifdef STENO_ENABLE_GEMINI - -# ifdef VIRTSER_ENABLE -void send_steno_chord_gemini(void) { - // Set MSB to 1 to indicate the start of packet - chord[0] |= 0x80; - for (uint8_t i = 0; i < GEMINI_STROKE_SIZE; ++i) { - virtser_send(chord[i]); - } -} -# else -# pragma message "VIRTSER_ENABLE = yes is required for Gemini PR to work properly out of the box!" -# endif // VIRTSER_ENABLE - -/** - * @precondition: `key` is pressed - */ -bool add_gemini_key_to_chord(uint8_t key) { - // Although each group of the packet is 8 bits long, the MSB is reserved - // to indicate whether that byte is the first byte of the packet (MSB=1) - // or one of the remaining five bytes of the packet (MSB=0). - // As a consequence, only 7 out of the 8 bits are left to be used as a bit array - // for the steno keys of that group. - const int group_idx = key / 7; - const int intra_group_idx = key - group_idx * 7; - // The 0th steno key of the group has bit=0b01000000, the 1st has bit=0b00100000, etc. - const uint8_t bit = 1 << (6 - intra_group_idx); - chord[group_idx] |= bit; - return false; -} -#endif // STENO_ENABLE_GEMINI - -#ifdef STENO_ENABLE_BOLT - -# define TXB_GRP0 0b00000000 -# define TXB_GRP1 0b01000000 -# define TXB_GRP2 0b10000000 -# define TXB_GRP3 0b11000000 -# define TXB_GRPMASK 0b11000000 - -# define TXB_GET_GROUP(code) ((code & TXB_GRPMASK) >> 6) - -static const uint8_t boltmap[64] PROGMEM = {TXB_NUL, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_S_L, TXB_S_L, TXB_T_L, TXB_K_L, TXB_P_L, TXB_W_L, TXB_H_L, TXB_R_L, TXB_A_L, TXB_O_L, TXB_STR, TXB_STR, TXB_NUL, TXB_NUL, TXB_NUL, TXB_STR, TXB_STR, TXB_E_R, TXB_U_R, TXB_F_R, TXB_R_R, TXB_P_R, TXB_B_R, TXB_L_R, TXB_G_R, TXB_T_R, TXB_S_R, TXB_D_R, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_NUM, TXB_Z_R}; - -# ifdef VIRTSER_ENABLE -static void send_steno_chord_bolt(void) { - for (uint8_t i = 0; i < BOLT_STROKE_SIZE; ++i) { - // TX Bolt uses variable length packets where each byte corresponds to a bit array of certain keys. - // If a user chorded the keys of the first group with keys of the last group, for example, there - // would be bytes of 0x00 in `chord` for the middle groups which we mustn't send. - if (chord[i]) { - virtser_send(chord[i]); - } - } - // Sending a null packet is not always necessary, but it is simpler and more reliable - // to unconditionally send it every time instead of keeping track of more states and - // creating more branches in the execution of the program. - virtser_send(0); -} -# else -# pragma message "VIRTSER_ENABLE = yes is required for TX Bolt to work properly out of the box!" -# endif // VIRTSER_ENABLE - -/** - * @precondition: `key` is pressed - */ -static bool add_bolt_key_to_chord(uint8_t key) { - uint8_t boltcode = pgm_read_byte(boltmap + key); - chord[TXB_GET_GROUP(boltcode)] |= boltcode; - return false; -} -#endif // STENO_ENABLE_BOLT - -#ifdef STENO_COMBINEDMAP -/* Used to look up when pressing the middle row key to combine two consonant or vowel keys */ -static const uint16_t combinedmap_first[] PROGMEM = {STN_S1, STN_TL, STN_PL, STN_HL, STN_FR, STN_PR, STN_LR, STN_TR, STN_DR, STN_A, STN_E}; -static const uint16_t combinedmap_second[] PROGMEM = {STN_S2, STN_KL, STN_WL, STN_RL, STN_RR, STN_BR, STN_GR, STN_SR, STN_ZR, STN_O, STN_U}; -#endif - -#ifdef STENO_ENABLE_ALL -void steno_init(void) { - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - mode = eeprom_read_byte(EECONFIG_STENOMODE); -} - -void steno_set_mode(steno_mode_t new_mode) { - steno_clear_chord(); - mode = new_mode; - eeprom_update_byte(EECONFIG_STENOMODE, mode); -} -#endif // STENO_ENABLE_ALL - -/* override to intercept chords right before they get sent. - * return zero to suppress normal sending behavior. - */ -__attribute__((weak)) bool send_steno_chord_user(steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE]) { - return true; -} - -__attribute__((weak)) bool post_process_steno_user(uint16_t keycode, keyrecord_t *record, steno_mode_t mode, uint8_t chord[MAX_STROKE_SIZE], int8_t n_pressed_keys) { - return true; -} - -__attribute__((weak)) bool process_steno_user(uint16_t keycode, keyrecord_t *record) { - return true; -} - -bool process_steno(uint16_t keycode, keyrecord_t *record) { - if (keycode < QK_STENO || keycode > QK_STENO_MAX) { - return true; // Not a steno key, pass it further along the chain - /* - * Clearing or sending the chord state is not necessary as we intentionally ignore whatever - * normal keyboard keys the user may have tapped while chording steno keys. - */ - } - if (IS_NOEVENT(record->event)) { - return true; - } - if (!process_steno_user(keycode, record)) { - return false; // User fully processed the steno key themselves - } - switch (keycode) { -#ifdef STENO_ENABLE_ALL - case QK_STENO_BOLT: - if (record->event.pressed) { - steno_set_mode(STENO_MODE_BOLT); - } - return false; - - case QK_STENO_GEMINI: - if (record->event.pressed) { - steno_set_mode(STENO_MODE_GEMINI); - } - return false; -#endif // STENO_ENABLE_ALL - -#ifdef STENO_COMBINEDMAP - case QK_STENO_COMB ... QK_STENO_COMB_MAX: { - bool first_result = process_steno(combinedmap_first[keycode - QK_STENO_COMB], record); - bool second_result = process_steno(combinedmap_second[keycode - QK_STENO_COMB], record); - return first_result && second_result; - } -#endif // STENO_COMBINEDMAP - case STN__MIN ... STN__MAX: - if (record->event.pressed) { - n_pressed_keys++; - switch (mode) { -#ifdef STENO_ENABLE_BOLT - case STENO_MODE_BOLT: - add_bolt_key_to_chord(keycode - QK_STENO); - break; -#endif // STENO_ENABLE_BOLT -#ifdef STENO_ENABLE_GEMINI - case STENO_MODE_GEMINI: - add_gemini_key_to_chord(keycode - QK_STENO); - break; -#endif // STENO_ENABLE_GEMINI - default: - return false; - } - if (!post_process_steno_user(keycode, record, mode, chord, n_pressed_keys)) { - return false; - } - } else { // is released - n_pressed_keys--; - if (!post_process_steno_user(keycode, record, mode, chord, n_pressed_keys)) { - return false; - } - if (n_pressed_keys > 0) { - // User hasn't released all keys yet, - // so the chord cannot be sent - return false; - } - n_pressed_keys = 0; - if (!send_steno_chord_user(mode, chord)) { - steno_clear_chord(); - return false; - } - switch (mode) { -#if defined(STENO_ENABLE_BOLT) && defined(VIRTSER_ENABLE) - case STENO_MODE_BOLT: - send_steno_chord_bolt(); - break; -#endif // STENO_ENABLE_BOLT && VIRTSER_ENABLE -#if defined(STENO_ENABLE_GEMINI) && defined(VIRTSER_ENABLE) - case STENO_MODE_GEMINI: - send_steno_chord_gemini(); - break; -#endif // STENO_ENABLE_GEMINI && VIRTSER_ENABLE - default: - break; - } - steno_clear_chord(); - } - break; - } - return false; -} diff --git a/quantum/process_keycode/process_steno.h b/quantum/process_keycode/process_steno.h deleted file mode 100644 index 68d6097b9b78..000000000000 --- a/quantum/process_keycode/process_steno.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Copyright 2017 Joseph Wasson - * - * 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 . - */ - -#pragma once - -#include "quantum.h" - -#define BOLT_STROKE_SIZE 4 -#define GEMINI_STROKE_SIZE 6 - -#ifdef STENO_ENABLE_GEMINI -# define MAX_STROKE_SIZE GEMINI_STROKE_SIZE -#else -# define MAX_STROKE_SIZE BOLT_STROKE_SIZE -#endif - -typedef enum { - STENO_MODE_GEMINI, - STENO_MODE_BOLT, -} steno_mode_t; - -bool process_steno(uint16_t keycode, keyrecord_t *record); -#ifdef STENO_ENABLE_ALL -void steno_init(void); -void steno_set_mode(steno_mode_t mode); -#endif // STENO_ENABLE_ALL diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c deleted file mode 100644 index 706f5cddbb1b..000000000000 --- a/quantum/process_keycode/process_tap_dance.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ -#include "quantum.h" - -static uint16_t active_td; -static uint16_t last_tap_time; - -void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data) { - tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data; - - if (state->count == 2) { - register_code16(pair->kc2); - state->finished = true; - } -} - -void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data) { - tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data; - - register_code16(pair->kc1); -} - -void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data) { - tap_dance_pair_t *pair = (tap_dance_pair_t *)user_data; - - if (state->count == 1) { - wait_ms(TAP_CODE_DELAY); - unregister_code16(pair->kc1); - } else if (state->count == 2) { - unregister_code16(pair->kc2); - } -} - -void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data) { - tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data; - - if (state->count == 2) { - layer_move(pair->layer); - state->finished = true; - } -} - -void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data) { - tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data; - - if (state->count == 1) { - register_code16(pair->kc); - } else if (state->count == 2) { - pair->layer_function(pair->layer); - } -} - -void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data) { - tap_dance_dual_role_t *pair = (tap_dance_dual_role_t *)user_data; - - if (state->count == 1) { - wait_ms(TAP_CODE_DELAY); - unregister_code16(pair->kc); - } -} - -static inline void _process_tap_dance_action_fn(tap_dance_state_t *state, void *user_data, tap_dance_user_fn_t fn) { - if (fn) { - fn(state, user_data); - } -} - -static inline void process_tap_dance_action_on_each_tap(tap_dance_action_t *action) { - action->state.count++; - action->state.weak_mods = get_mods(); - action->state.weak_mods |= get_weak_mods(); -#ifndef NO_ACTION_ONESHOT - action->state.oneshot_mods = get_oneshot_mods(); -#endif - _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_each_tap); -} - -static inline void process_tap_dance_action_on_reset(tap_dance_action_t *action) { - _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_reset); - del_weak_mods(action->state.weak_mods); -#ifndef NO_ACTION_ONESHOT - del_mods(action->state.oneshot_mods); -#endif - send_keyboard_report(); - action->state = (const tap_dance_state_t){0}; -} - -static inline void process_tap_dance_action_on_dance_finished(tap_dance_action_t *action) { - if (!action->state.finished) { - action->state.finished = true; - add_weak_mods(action->state.weak_mods); -#ifndef NO_ACTION_ONESHOT - add_mods(action->state.oneshot_mods); -#endif - send_keyboard_report(); - _process_tap_dance_action_fn(&action->state, action->user_data, action->fn.on_dance_finished); - } - active_td = 0; - if (!action->state.pressed) { - // There will not be a key release event, so reset now. - process_tap_dance_action_on_reset(action); - } -} - -bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record) { - tap_dance_action_t *action; - - if (!record->event.pressed) return false; - - if (!active_td || keycode == active_td) return false; - - action = &tap_dance_actions[TD_INDEX(active_td)]; - action->state.interrupted = true; - action->state.interrupting_keycode = keycode; - process_tap_dance_action_on_dance_finished(action); - - // Tap dance actions can leave some weak mods active (e.g., if the tap dance is mapped to a keycode with - // modifiers), but these weak mods should not affect the keypress which interrupted the tap dance. - clear_weak_mods(); - - // Signal that a tap dance has been finished due to being interrupted, - // therefore the keymap lookup for the currently processed event needs to - // be repeated with the current layer state that might have been updated by - // the finished tap dance. - return true; -} - -bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { - tap_dance_action_t *action; - - switch (keycode) { - case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: - action = &tap_dance_actions[TD_INDEX(keycode)]; - - action->state.pressed = record->event.pressed; - if (record->event.pressed) { - last_tap_time = timer_read(); - process_tap_dance_action_on_each_tap(action); - active_td = action->state.finished ? 0 : keycode; - } else { - if (action->state.finished) { - process_tap_dance_action_on_reset(action); - } - } - - break; - } - - return true; -} - -void tap_dance_task(void) { - tap_dance_action_t *action; - - if (!active_td || timer_elapsed(last_tap_time) <= GET_TAPPING_TERM(active_td, &(keyrecord_t){})) return; - - action = &tap_dance_actions[TD_INDEX(active_td)]; - if (!action->state.interrupted) { - process_tap_dance_action_on_dance_finished(action); - } -} - -void reset_tap_dance(tap_dance_state_t *state) { - active_td = 0; - process_tap_dance_action_on_reset((tap_dance_action_t *)state); -} diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h deleted file mode 100644 index 5cb6d9202c6b..000000000000 --- a/quantum/process_keycode/process_tap_dance.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#ifdef TAP_DANCE_ENABLE - -# include -# include - -typedef struct { - uint16_t interrupting_keycode; - uint8_t count; - uint8_t weak_mods; -# ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; -# endif - bool pressed : 1; - bool finished : 1; - bool interrupted : 1; -} tap_dance_state_t; - -typedef void (*tap_dance_user_fn_t)(tap_dance_state_t *state, void *user_data); - -typedef struct { - tap_dance_state_t state; - struct { - tap_dance_user_fn_t on_each_tap; - tap_dance_user_fn_t on_dance_finished; - tap_dance_user_fn_t on_reset; - } fn; - void *user_data; -} tap_dance_action_t; - -typedef struct { - uint16_t kc1; - uint16_t kc2; -} tap_dance_pair_t; - -typedef struct { - uint16_t kc; - uint8_t layer; - void (*layer_function)(uint8_t); -} tap_dance_dual_role_t; - -# define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) \ - { .fn = {tap_dance_pair_on_each_tap, tap_dance_pair_finished, tap_dance_pair_reset}, .user_data = (void *)&((tap_dance_pair_t){kc1, kc2}), } - -# define ACTION_TAP_DANCE_LAYER_MOVE(kc, layer) \ - { .fn = {tap_dance_dual_role_on_each_tap, tap_dance_dual_role_finished, tap_dance_dual_role_reset}, .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_move}), } - -# define ACTION_TAP_DANCE_LAYER_TOGGLE(kc, layer) \ - { .fn = {NULL, tap_dance_dual_role_finished, tap_dance_dual_role_reset}, .user_data = (void *)&((tap_dance_dual_role_t){kc, layer, layer_invert}), } - -# define ACTION_TAP_DANCE_FN(user_fn) \ - { .fn = {NULL, user_fn, NULL}, .user_data = NULL, } - -# define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset) \ - { .fn = {user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset}, .user_data = NULL, } - -# define TD(n) (QK_TAP_DANCE | TD_INDEX(n)) -# define TD_INDEX(code) ((code)&0xFF) -# define TAP_DANCE_KEYCODE(state) TD(((tap_dance_action_t *)state) - tap_dance_actions) - -extern tap_dance_action_t tap_dance_actions[]; - -void reset_tap_dance(tap_dance_state_t *state); - -/* To be used internally */ - -bool preprocess_tap_dance(uint16_t keycode, keyrecord_t *record); -bool process_tap_dance(uint16_t keycode, keyrecord_t *record); -void tap_dance_task(void); - -void tap_dance_pair_on_each_tap(tap_dance_state_t *state, void *user_data); -void tap_dance_pair_finished(tap_dance_state_t *state, void *user_data); -void tap_dance_pair_reset(tap_dance_state_t *state, void *user_data); - -void tap_dance_dual_role_on_each_tap(tap_dance_state_t *state, void *user_data); -void tap_dance_dual_role_finished(tap_dance_state_t *state, void *user_data); -void tap_dance_dual_role_reset(tap_dance_state_t *state, void *user_data); - -#else - -# define TD(n) KC_NO - -#endif diff --git a/quantum/process_keycode/process_tri_layer.c b/quantum/process_keycode/process_tri_layer.c deleted file mode 100644 index 1e681b9a1c2e..000000000000 --- a/quantum/process_keycode/process_tri_layer.c +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "process_tri_layer.h" -#include "tri_layer.h" -#include "action_layer.h" - -bool process_tri_layer(uint16_t keycode, keyrecord_t *record) { - switch (keycode) { - case QK_TRI_LAYER_LOWER: - if (record->event.pressed) { - layer_on(get_tri_layer_lower_layer()); - update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); - } else { - layer_off(get_tri_layer_lower_layer()); - update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); - } - return false; - case QK_TRI_LAYER_UPPER: - if (record->event.pressed) { - layer_on(get_tri_layer_upper_layer()); - update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); - } else { - layer_off(get_tri_layer_upper_layer()); - update_tri_layer(get_tri_layer_lower_layer(), get_tri_layer_upper_layer(), get_tri_layer_adjust_layer()); - } - return false; - } - return true; -} diff --git a/quantum/process_keycode/process_tri_layer.h b/quantum/process_keycode/process_tri_layer.h deleted file mode 100644 index 9c4e3df1c2f4..000000000000 --- a/quantum/process_keycode/process_tri_layer.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "action.h" - -/** - * @brief Handles tri layer behavior - * - * @param keycode the keycode - * @param record the key record structure - * @return true continue handling keycodes - * @return false stop handling keycodes - */ -bool process_tri_layer(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_ucis.c b/quantum/process_keycode/process_ucis.c deleted file mode 100644 index 3aa09d5948f2..000000000000 --- a/quantum/process_keycode/process_ucis.c +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#include "process_ucis.h" -#include "unicode.h" -#include "keycode.h" -#include "wait.h" - -ucis_state_t ucis_state; - -void ucis_start(void) { - ucis_state.count = 0; - ucis_state.in_progress = true; - - ucis_start_user(); -} - -__attribute__((weak)) void ucis_start_user(void) { - register_unicode(0x2328); // ⌨ -} - -__attribute__((weak)) void ucis_success(uint8_t symbol_index) {} - -static bool is_uni_seq(char *seq) { - uint8_t i; - for (i = 0; seq[i]; i++) { - uint16_t keycode; - if ('1' <= seq[i] && seq[i] <= '0') { - keycode = seq[i] - '1' + KC_1; - } else { - keycode = seq[i] - 'a' + KC_A; - } - if (i > ucis_state.count || ucis_state.codes[i] != keycode) { - return false; - } - } - return ucis_state.codes[i] == KC_ENTER || ucis_state.codes[i] == KC_SPACE; -} - -__attribute__((weak)) void ucis_symbol_fallback(void) { - for (uint8_t i = 0; i < ucis_state.count - 1; i++) { - tap_code(ucis_state.codes[i]); - } -} - -__attribute__((weak)) void ucis_cancel(void) {} - -void register_ucis(const uint32_t *code_points) { - for (int i = 0; i < UCIS_MAX_CODE_POINTS && code_points[i]; i++) { - register_unicode(code_points[i]); - } -} - -bool process_ucis(uint16_t keycode, keyrecord_t *record) { - if (!ucis_state.in_progress || !record->event.pressed) { - return true; - } - - bool special = keycode == KC_SPACE || keycode == KC_ENTER || keycode == KC_ESCAPE || keycode == KC_BACKSPACE; - if (ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && !special) { - return false; - } - - ucis_state.codes[ucis_state.count] = keycode; - ucis_state.count++; - - switch (keycode) { - case KC_BACKSPACE: - if (ucis_state.count >= 2) { - ucis_state.count -= 2; - return true; - } else { - ucis_state.count--; - return false; - } - - case KC_SPACE: - case KC_ENTER: - case KC_ESCAPE: - for (uint8_t i = 0; i < ucis_state.count; i++) { - tap_code(KC_BACKSPACE); - } - - if (keycode == KC_ESCAPE) { - ucis_state.in_progress = false; - ucis_cancel(); - return false; - } - - uint8_t i; - bool symbol_found = false; - for (i = 0; ucis_symbol_table[i].symbol; i++) { - if (is_uni_seq(ucis_symbol_table[i].symbol)) { - symbol_found = true; - register_ucis(ucis_symbol_table[i].code_points); - break; - } - } - if (symbol_found) { - ucis_success(i); - } else { - ucis_symbol_fallback(); - } - - ucis_state.in_progress = false; - return false; - - default: - return true; - } -} diff --git a/quantum/process_keycode/process_ucis.h b/quantum/process_keycode/process_ucis.h deleted file mode 100644 index 54eb9413d41b..000000000000 --- a/quantum/process_keycode/process_ucis.h +++ /dev/null @@ -1,65 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include -#include - -#include "action.h" - -#ifndef UCIS_MAX_SYMBOL_LENGTH -# define UCIS_MAX_SYMBOL_LENGTH 32 -#endif -#ifndef UCIS_MAX_CODE_POINTS -# define UCIS_MAX_CODE_POINTS 3 -#endif - -typedef struct { - char * symbol; - uint32_t code_points[UCIS_MAX_CODE_POINTS]; -} ucis_symbol_t; - -typedef struct { - uint8_t count; - uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; - bool in_progress : 1; -} ucis_state_t; - -extern ucis_state_t ucis_state; - -// clang-format off - -#define UCIS_TABLE(...) \ - { \ - __VA_ARGS__, \ - { NULL, {} } \ - } -#define UCIS_SYM(name, ...) \ - { name, {__VA_ARGS__} } - -// clang-format on - -extern const ucis_symbol_t ucis_symbol_table[]; - -void ucis_start(void); -void ucis_start_user(void); -void ucis_symbol_fallback(void); -void ucis_success(uint8_t symbol_index); - -void register_ucis(const uint32_t *code_points); - -bool process_ucis(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c deleted file mode 100644 index 1ec76245a342..000000000000 --- a/quantum/process_keycode/process_unicode.c +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#include "process_unicode.h" -#include "unicode.h" -#include "quantum_keycodes.h" - -bool process_unicode(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - if (keycode >= QK_UNICODE && keycode <= QK_UNICODE_MAX) { - register_unicode(QK_UNICODE_GET_CODE_POINT(keycode)); - } - } - return true; -} diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h deleted file mode 100644 index 341bc8d861dc..000000000000 --- a/quantum/process_keycode/process_unicode.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2016 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include -#include - -#include "action.h" - -bool process_unicode(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_unicode_common.c b/quantum/process_keycode/process_unicode_common.c deleted file mode 100644 index a0b901002763..000000000000 --- a/quantum/process_keycode/process_unicode_common.c +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#include "process_unicode_common.h" -#include "unicode.h" -#include "action_util.h" -#include "keycode.h" - -#if defined(UNICODE_ENABLE) -# include "process_unicode.h" -#elif defined(UNICODEMAP_ENABLE) -# include "process_unicodemap.h" -#elif defined(UCIS_ENABLE) -# include "process_ucis.h" -#endif - -bool process_unicode_common(uint16_t keycode, keyrecord_t *record) { - if (record->event.pressed) { - bool shifted = get_mods() & MOD_MASK_SHIFT; - switch (keycode) { - case QK_UNICODE_MODE_NEXT: - cycle_unicode_input_mode(shifted ? -1 : +1); - break; - case QK_UNICODE_MODE_PREVIOUS: - cycle_unicode_input_mode(shifted ? +1 : -1); - break; - case QK_UNICODE_MODE_MACOS: - set_unicode_input_mode(UNICODE_MODE_MACOS); - break; - case QK_UNICODE_MODE_LINUX: - set_unicode_input_mode(UNICODE_MODE_LINUX); - break; - case QK_UNICODE_MODE_WINDOWS: - set_unicode_input_mode(UNICODE_MODE_WINDOWS); - break; - case QK_UNICODE_MODE_BSD: - set_unicode_input_mode(UNICODE_MODE_BSD); - break; - case QK_UNICODE_MODE_WINCOMPOSE: - set_unicode_input_mode(UNICODE_MODE_WINCOMPOSE); - break; - case QK_UNICODE_MODE_EMACS: - set_unicode_input_mode(UNICODE_MODE_EMACS); - break; - } - } - -#if defined(UNICODE_ENABLE) - return process_unicode(keycode, record); -#elif defined(UNICODEMAP_ENABLE) - return process_unicodemap(keycode, record); -#elif defined(UCIS_ENABLE) - return process_ucis(keycode, record); -#else - return true; -#endif -} diff --git a/quantum/process_keycode/process_unicode_common.h b/quantum/process_keycode/process_unicode_common.h deleted file mode 100644 index fd09a41818f9..000000000000 --- a/quantum/process_keycode/process_unicode_common.h +++ /dev/null @@ -1,24 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include -#include - -#include "action.h" - -bool process_unicode_common(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/process_keycode/process_unicodemap.c b/quantum/process_keycode/process_unicodemap.c deleted file mode 100644 index 195c093e6e5d..000000000000 --- a/quantum/process_keycode/process_unicodemap.c +++ /dev/null @@ -1,55 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#include "process_unicodemap.h" -#include "unicode.h" -#include "quantum_keycodes.h" -#include "keycode.h" -#include "action_util.h" -#include "host.h" - -__attribute__((weak)) uint16_t unicodemap_index(uint16_t keycode) { - if (keycode >= QK_UNICODEMAP_PAIR) { - // Keycode is a pair: extract index based on Shift / Caps Lock state - uint16_t index; - - uint8_t mods = get_mods() | get_weak_mods(); -#ifndef NO_ACTION_ONESHOT - mods |= get_oneshot_mods(); -#endif - - bool shift = mods & MOD_MASK_SHIFT; - bool caps = host_keyboard_led_state().caps_lock; - if (shift ^ caps) { - index = QK_UNICODEMAP_PAIR_GET_SHIFTED_INDEX(keycode); - } else { - index = QK_UNICODEMAP_PAIR_GET_UNSHIFTED_INDEX(keycode); - } - - return index; - } else { - // Keycode is a regular index - return QK_UNICODEMAP_GET_INDEX(keycode); - } -} - -bool process_unicodemap(uint16_t keycode, keyrecord_t *record) { - if (keycode >= QK_UNICODEMAP && keycode <= QK_UNICODEMAP_PAIR_MAX && record->event.pressed) { - uint32_t code_point = pgm_read_dword(unicode_map + unicodemap_index(keycode)); - register_unicode(code_point); - } - return true; -} diff --git a/quantum/process_keycode/process_unicodemap.h b/quantum/process_keycode/process_unicodemap.h deleted file mode 100644 index 5a3aeb000062..000000000000 --- a/quantum/process_keycode/process_unicodemap.h +++ /dev/null @@ -1,28 +0,0 @@ -/* Copyright 2017 Jack Humbert - * - * 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 . - */ - -#pragma once - -#include -#include - -#include "action.h" -#include "progmem.h" - -extern const uint32_t unicode_map[] PROGMEM; - -uint16_t unicodemap_index(uint16_t keycode); -bool process_unicodemap(uint16_t keycode, keyrecord_t *record); diff --git a/quantum/programmable_button.c b/quantum/programmable_button.c deleted file mode 100644 index b6c9ad318992..000000000000 --- a/quantum/programmable_button.c +++ /dev/null @@ -1,62 +0,0 @@ -/* -Copyright 2021 Thomas Weißschuh - -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 . -*/ - -#include "programmable_button.h" -#include "host.h" - -#define REPORT_BIT(index) (((uint32_t)1) << (index - 1)) - -static uint32_t programmable_button_report = 0; - -void programmable_button_clear(void) { - programmable_button_report = 0; - programmable_button_flush(); -} - -void programmable_button_add(uint8_t index) { - programmable_button_report |= REPORT_BIT(index); -} - -void programmable_button_remove(uint8_t index) { - programmable_button_report &= ~REPORT_BIT(index); -} - -void programmable_button_register(uint8_t index) { - programmable_button_add(index); - programmable_button_flush(); -} - -void programmable_button_unregister(uint8_t index) { - programmable_button_remove(index); - programmable_button_flush(); -} - -bool programmable_button_is_on(uint8_t index) { - return !!(programmable_button_report & REPORT_BIT(index)); -} - -void programmable_button_flush(void) { - host_programmable_button_send(programmable_button_report); -} - -uint32_t programmable_button_get_report(void) { - return programmable_button_report; -} - -void programmable_button_set_report(uint32_t report) { - programmable_button_report = report; -} diff --git a/quantum/programmable_button.h b/quantum/programmable_button.h deleted file mode 100644 index 4c2cd534fe80..000000000000 --- a/quantum/programmable_button.h +++ /dev/null @@ -1,91 +0,0 @@ -/* -Copyright 2021 Thomas Weißschuh - -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 . -*/ - -#pragma once - -#include -#include - -/** - * \file - * - * \defgroup programmable_button HID Programmable Buttons - * \{ - */ - -/** - * \brief Clear the programmable button report. - */ -void programmable_button_clear(void); - -/** - * \brief Set the state of a button. - * - * \param index The index of the button to press, from 0 to 31. - */ -void programmable_button_add(uint8_t index); - -/** - * \brief Reset the state of a button. - * - * \param index The index of the button to release, from 0 to 31. - */ -void programmable_button_remove(uint8_t index); - -/** - * \brief Set the state of a button, and flush the report. - * - * \param index The index of the button to press, from 0 to 31. - */ -void programmable_button_register(uint8_t index); - -/** - * \brief Reset the state of a button, and flush the report. - * - * \param index The index of the button to release, from 0 to 31. - */ -void programmable_button_unregister(uint8_t index); - -/** - * \brief Get the state of a button. - * - * \param index The index of the button to check, from 0 to 31. - * - * \return `true` if the button is pressed. - */ -bool programmable_button_is_on(uint8_t index); - -/** - * \brief Send the programmable button report to the host. - */ -void programmable_button_flush(void); - -/** - * \brief Get the programmable button report. - * - * \return The bitmask of programmable button states. - */ -uint32_t programmable_button_get_report(void); - -/** - * \brief Set the programmable button report. - * - * \param report A bitmask of programmable button states. - */ -void programmable_button_set_report(uint32_t report); - -/** \} */ diff --git a/quantum/quantum.c b/quantum/quantum.c deleted file mode 100644 index fe3e85720ddf..000000000000 --- a/quantum/quantum.c +++ /dev/null @@ -1,604 +0,0 @@ -/* Copyright 2016-2017 Jack Humbert - * - * 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 . - */ - -#include "quantum.h" - -#ifdef BLUETOOTH_ENABLE -# include "outputselect.h" -#endif - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef MIDI_ENABLE -# include "process_midi.h" -#endif - -#ifdef VELOCIKEY_ENABLE -# include "velocikey.h" -#endif - -#ifdef HAPTIC_ENABLE -# include "haptic.h" -#endif - -#ifdef AUDIO_ENABLE -# ifndef GOODBYE_SONG -# define GOODBYE_SONG SONG(GOODBYE_SOUND) -# endif -float goodbye_song[][2] = GOODBYE_SONG; -# ifdef DEFAULT_LAYER_SONGS -float default_layer_songs[][16][2] = DEFAULT_LAYER_SONGS; -# endif -#endif - -uint8_t extract_mod_bits(uint16_t code) { - switch (code) { - case QK_MODS ... QK_MODS_MAX: - break; - default: - return 0; - } - - uint8_t mods_to_send = 0; - - if (code & QK_RMODS_MIN) { // Right mod flag is set - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_RIGHT_CTRL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_RIGHT_SHIFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_RIGHT_ALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_RIGHT_GUI); - } else { - if (code & QK_LCTL) mods_to_send |= MOD_BIT(KC_LEFT_CTRL); - if (code & QK_LSFT) mods_to_send |= MOD_BIT(KC_LEFT_SHIFT); - if (code & QK_LALT) mods_to_send |= MOD_BIT(KC_LEFT_ALT); - if (code & QK_LGUI) mods_to_send |= MOD_BIT(KC_LEFT_GUI); - } - - return mods_to_send; -} - -void do_code16(uint16_t code, void (*f)(uint8_t)) { - f(extract_mod_bits(code)); -} - -__attribute__((weak)) void register_code16(uint16_t code) { - if (IS_MODIFIER_KEYCODE(code) || code == KC_NO) { - do_code16(code, register_mods); - } else { - do_code16(code, register_weak_mods); - } - register_code(code); -} - -__attribute__((weak)) void unregister_code16(uint16_t code) { - unregister_code(code); - if (IS_MODIFIER_KEYCODE(code) || code == KC_NO) { - do_code16(code, unregister_mods); - } else { - do_code16(code, unregister_weak_mods); - } -} - -/** \brief Tap a keycode with a delay. - * - * \param code The modded keycode to tap. - * \param delay The amount of time in milliseconds to leave the keycode registered, before unregistering it. - */ -__attribute__((weak)) void tap_code16_delay(uint16_t code, uint16_t delay) { - register_code16(code); - for (uint16_t i = delay; i > 0; i--) { - wait_ms(1); - } - unregister_code16(code); -} - -/** \brief Tap a keycode with the default delay. - * - * \param code The modded keycode to tap. If `code` is `KC_CAPS_LOCK`, the delay will be `TAP_HOLD_CAPS_DELAY`, otherwise `TAP_CODE_DELAY`, if defined. - */ -__attribute__((weak)) void tap_code16(uint16_t code) { - tap_code16_delay(code, code == KC_CAPS_LOCK ? TAP_HOLD_CAPS_DELAY : TAP_CODE_DELAY); -} - -__attribute__((weak)) bool pre_process_record_kb(uint16_t keycode, keyrecord_t *record) { - return pre_process_record_user(keycode, record); -} - -__attribute__((weak)) bool pre_process_record_user(uint16_t keycode, keyrecord_t *record) { - return true; -} - -__attribute__((weak)) bool process_action_kb(keyrecord_t *record) { - return true; -} - -__attribute__((weak)) bool process_record_kb(uint16_t keycode, keyrecord_t *record) { - return process_record_user(keycode, record); -} - -__attribute__((weak)) bool process_record_user(uint16_t keycode, keyrecord_t *record) { - return true; -} - -__attribute__((weak)) void post_process_record_kb(uint16_t keycode, keyrecord_t *record) { - post_process_record_user(keycode, record); -} - -__attribute__((weak)) void post_process_record_user(uint16_t keycode, keyrecord_t *record) {} - -void shutdown_quantum(void) { - clear_keyboard(); -#if defined(MIDI_ENABLE) && defined(MIDI_BASIC) - process_midi_all_notes_off(); -#endif -#ifdef AUDIO_ENABLE -# ifndef NO_MUSIC_MODE - music_all_notes_off(); -# endif - uint16_t timer_start = timer_read(); - PLAY_SONG(goodbye_song); - shutdown_user(); - while (timer_elapsed(timer_start) < 250) - wait_ms(1); - stop_all_notes(); -#else - shutdown_user(); - wait_ms(250); -#endif -#ifdef HAPTIC_ENABLE - haptic_shutdown(); -#endif -} - -void reset_keyboard(void) { - shutdown_quantum(); - bootloader_jump(); -} - -void soft_reset_keyboard(void) { - shutdown_quantum(); - mcu_reset(); -} - -/* Convert record into usable keycode via the contained event. */ -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache) { -#if defined(COMBO_ENABLE) || defined(REPEAT_KEY_ENABLE) - if (record->keycode) { - return record->keycode; - } -#endif - return get_event_keycode(record->event, update_layer_cache); -} - -/* Convert event into usable keycode. Checks the layer cache to ensure that it - * retains the correct keycode after a layer change, if the key is still pressed. - * "update_layer_cache" is to ensure that it only updates the layer cache when - * appropriate, otherwise, it will update it and cause layer tap (and other keys) - * from triggering properly. - */ -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache) { -#if !defined(NO_ACTION_LAYER) && !defined(STRICT_LAYER_RELEASE) - /* TODO: Use store_or_get_action() or a similar function. */ - if (!disable_action_cache) { - uint8_t layer; - - if (event.pressed && update_layer_cache) { - layer = layer_switch_get_layer(event.key); - update_source_layers_cache(event.key, layer); - } else { - layer = read_source_layers_cache(event.key); - } - return keymap_key_to_keycode(layer, event.key); - } else -#endif - return keymap_key_to_keycode(layer_switch_get_layer(event.key), event.key); -} - -/* Get keycode, and then process pre tapping functionality */ -bool pre_process_record_quantum(keyrecord_t *record) { - uint16_t keycode = get_record_keycode(record, true); - return pre_process_record_kb(keycode, record) && -#ifdef COMBO_ENABLE - process_combo(keycode, record) && -#endif - true; -} - -/* Get keycode, and then call keyboard function */ -void post_process_record_quantum(keyrecord_t *record) { - uint16_t keycode = get_record_keycode(record, false); - post_process_record_kb(keycode, record); -} - -/* Core keycode function, hands off handling to other functions, - then processes internal quantum keycodes, and then processes - ACTIONs. */ -bool process_record_quantum(keyrecord_t *record) { - uint16_t keycode = get_record_keycode(record, true); - - // This is how you use actions here - // if (keycode == QK_LEADER) { - // action_t action; - // action.code = ACTION_DEFAULT_LAYER_SET(0); - // process_action(record, action); - // return false; - // } - -#if defined(SECURE_ENABLE) - if (!preprocess_secure(keycode, record)) { - return false; - } -#endif - -#ifdef TAP_DANCE_ENABLE - if (preprocess_tap_dance(keycode, record)) { - // The tap dance might have updated the layer state, therefore the - // result of the keycode lookup might change. - keycode = get_record_keycode(record, true); - } -#endif - -#ifdef VELOCIKEY_ENABLE - if (velocikey_enabled() && record->event.pressed) { - velocikey_accelerate(); - } -#endif - -#ifdef WPM_ENABLE - if (record->event.pressed) { - update_wpm(keycode); - } -#endif - - if (!( -#if defined(KEY_LOCK_ENABLE) - // Must run first to be able to mask key_up events. - process_key_lock(&keycode, record) && -#endif -#if defined(DYNAMIC_MACRO_ENABLE) && !defined(DYNAMIC_MACRO_USER_CALL) - // Must run asap to ensure all keypresses are recorded. - process_dynamic_macro(keycode, record) && -#endif -#ifdef REPEAT_KEY_ENABLE - process_last_key(keycode, record) && process_repeat_key(keycode, record) && -#endif -#if defined(AUDIO_ENABLE) && defined(AUDIO_CLICKY) - process_clicky(keycode, record) && -#endif -#ifdef HAPTIC_ENABLE - process_haptic(keycode, record) && -#endif -#if defined(VIA_ENABLE) - process_record_via(keycode, record) && -#endif -#if defined(POINTING_DEVICE_ENABLE) && defined(POINTING_DEVICE_AUTO_MOUSE_ENABLE) - process_auto_mouse(keycode, record) && -#endif - process_record_kb(keycode, record) && -#if defined(SECURE_ENABLE) - process_secure(keycode, record) && -#endif -#if defined(SEQUENCER_ENABLE) - process_sequencer(keycode, record) && -#endif -#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) - process_midi(keycode, record) && -#endif -#ifdef AUDIO_ENABLE - process_audio(keycode, record) && -#endif -#if defined(BACKLIGHT_ENABLE) || defined(LED_MATRIX_ENABLE) - process_backlight(keycode, record) && -#endif -#ifdef STENO_ENABLE - process_steno(keycode, record) && -#endif -#if (defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC))) && !defined(NO_MUSIC_MODE) - process_music(keycode, record) && -#endif -#ifdef KEY_OVERRIDE_ENABLE - process_key_override(keycode, record) && -#endif -#ifdef TAP_DANCE_ENABLE - process_tap_dance(keycode, record) && -#endif -#ifdef CAPS_WORD_ENABLE - process_caps_word(keycode, record) && -#endif -#if defined(UNICODE_COMMON_ENABLE) - process_unicode_common(keycode, record) && -#endif -#ifdef LEADER_ENABLE - process_leader(keycode, record) && -#endif -#ifdef AUTO_SHIFT_ENABLE - process_auto_shift(keycode, record) && -#endif -#ifdef DYNAMIC_TAPPING_TERM_ENABLE - process_dynamic_tapping_term(keycode, record) && -#endif -#ifdef SPACE_CADET_ENABLE - process_space_cadet(keycode, record) && -#endif -#ifdef MAGIC_KEYCODE_ENABLE - process_magic(keycode, record) && -#endif -#ifdef GRAVE_ESC_ENABLE - process_grave_esc(keycode, record) && -#endif -#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) - process_rgb(keycode, record) && -#endif -#ifdef JOYSTICK_ENABLE - process_joystick(keycode, record) && -#endif -#ifdef PROGRAMMABLE_BUTTON_ENABLE - process_programmable_button(keycode, record) && -#endif -#ifdef AUTOCORRECT_ENABLE - process_autocorrect(keycode, record) && -#endif -#ifdef TRI_LAYER_ENABLE - process_tri_layer(keycode, record) && -#endif - true)) { - return false; - } - - if (record->event.pressed) { - switch (keycode) { -#ifndef NO_RESET - case QK_BOOTLOADER: - reset_keyboard(); - return false; - case QK_REBOOT: - soft_reset_keyboard(); - return false; -#endif -#ifndef NO_DEBUG - case QK_DEBUG_TOGGLE: - debug_enable ^= 1; - if (debug_enable) { - print("DEBUG: enabled.\n"); - } else { - print("DEBUG: disabled.\n"); - } -#endif - return false; - case QK_CLEAR_EEPROM: -#ifdef NO_RESET - eeconfig_init(); -#else - eeconfig_disable(); - soft_reset_keyboard(); -#endif - return false; -#ifdef VELOCIKEY_ENABLE - case QK_VELOCIKEY_TOGGLE: - velocikey_toggle(); - return false; -#endif -#ifdef BLUETOOTH_ENABLE - case QK_OUTPUT_AUTO: - set_output(OUTPUT_AUTO); - return false; - case QK_OUTPUT_USB: - set_output(OUTPUT_USB); - return false; - case QK_OUTPUT_BLUETOOTH: - set_output(OUTPUT_BLUETOOTH); - return false; -#endif -#ifndef NO_ACTION_ONESHOT - case QK_ONE_SHOT_TOGGLE: - oneshot_toggle(); - break; - case QK_ONE_SHOT_ON: - oneshot_enable(); - break; - case QK_ONE_SHOT_OFF: - oneshot_disable(); - break; -#endif -#ifdef ENABLE_COMPILE_KEYCODE - case QK_MAKE: // Compiles the firmware, and adds the flash command based on keyboard bootloader - { -# ifdef NO_ACTION_ONESHOT - const uint8_t temp_mod = mod_config(get_mods()); -# else - const uint8_t temp_mod = mod_config(get_mods() | get_oneshot_mods()); - clear_oneshot_mods(); -# endif - clear_mods(); - - SEND_STRING_DELAY("qmk", TAP_CODE_DELAY); - if (temp_mod & MOD_MASK_SHIFT) { // if shift is held, flash rather than compile - SEND_STRING_DELAY(" flash ", TAP_CODE_DELAY); - } else { - SEND_STRING_DELAY(" compile ", TAP_CODE_DELAY); - } -# if defined(CONVERTER_ENABLED) - SEND_STRING_DELAY("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP " -e CONVERT_TO=" CONVERTER_TARGET SS_TAP(X_ENTER), TAP_CODE_DELAY); -# else - SEND_STRING_DELAY("-kb " QMK_KEYBOARD " -km " QMK_KEYMAP SS_TAP(X_ENTER), TAP_CODE_DELAY); -# endif - if (temp_mod & MOD_MASK_SHIFT && temp_mod & MOD_MASK_CTRL) { - reset_keyboard(); - } - } -#endif - } - } - - return process_action_kb(record); -} - -void set_single_persistent_default_layer(uint8_t default_layer) { -#if defined(AUDIO_ENABLE) && defined(DEFAULT_LAYER_SONGS) - PLAY_SONG(default_layer_songs[default_layer]); -#endif - eeconfig_update_default_layer((layer_state_t)1 << default_layer); - default_layer_set((layer_state_t)1 << default_layer); -} - -//------------------------------------------------------------------------------ -// Override these functions in your keymap file to play different tunes on -// different events such as startup and bootloader jump - -__attribute__((weak)) void startup_user(void) {} - -__attribute__((weak)) void shutdown_user(void) {} - -void suspend_power_down_quantum(void) { - suspend_power_down_kb(); -#ifndef NO_SUSPEND_POWER_DOWN -// Turn off backlight -# ifdef BACKLIGHT_ENABLE - backlight_level_noeeprom(0); -# endif - -# ifdef LED_MATRIX_ENABLE - led_matrix_task(); -# endif -# ifdef RGB_MATRIX_ENABLE - rgb_matrix_task(); -# endif - - // Turn off LED indicators - led_suspend(); - -// Turn off audio -# ifdef AUDIO_ENABLE - stop_all_notes(); -# endif - -// Turn off underglow -# if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) - rgblight_suspend(); -# endif - -# if defined(LED_MATRIX_ENABLE) - led_matrix_set_suspend_state(true); -# endif -# if defined(RGB_MATRIX_ENABLE) - rgb_matrix_set_suspend_state(true); -# endif - -# ifdef OLED_ENABLE - oled_off(); -# endif -# ifdef ST7565_ENABLE - st7565_off(); -# endif -# if defined(POINTING_DEVICE_ENABLE) - // run to ensure scanning occurs while suspended - pointing_device_task(); -# endif -#endif -} - -__attribute__((weak)) void suspend_wakeup_init_quantum(void) { -// Turn on backlight -#ifdef BACKLIGHT_ENABLE - backlight_init(); -#endif - - // Restore LED indicators - led_wakeup(); - -// Wake up underglow -#if defined(RGBLIGHT_SLEEP) && defined(RGBLIGHT_ENABLE) - rgblight_wakeup(); -#endif - -#if defined(LED_MATRIX_ENABLE) - led_matrix_set_suspend_state(false); -#endif -#if defined(RGB_MATRIX_ENABLE) - rgb_matrix_set_suspend_state(false); -#endif - suspend_wakeup_init_kb(); -} - -/** \brief converts unsigned integers into char arrays - * - * Takes an unsigned integer and converts that value into an equivalent char array - * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros. - */ - -const char *get_numeric_str(char *buf, size_t buf_len, uint32_t curr_num, char curr_pad) { - buf[buf_len - 1] = '\0'; - for (size_t i = 0; i < buf_len - 1; ++i) { - char c = '0' + curr_num % 10; - buf[buf_len - 2 - i] = (c == '0' && i == 0) ? '0' : (curr_num > 0 ? c : curr_pad); - curr_num /= 10; - } - return buf; -} - -/** \brief converts uint8_t into char array - * - * Takes an uint8_t, and uses an internal static buffer to render that value into a char array - * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros. - * - * NOTE: Subsequent invocations will reuse the same static buffer and overwrite the previous - * contents. Use the result immediately, instead of caching it. - */ -const char *get_u8_str(uint8_t curr_num, char curr_pad) { - static char buf[4] = {0}; - static uint8_t last_num = 0xFF; - static char last_pad = '\0'; - if (last_num == curr_num && last_pad == curr_pad) { - return buf; - } - last_num = curr_num; - last_pad = curr_pad; - return get_numeric_str(buf, sizeof(buf), curr_num, curr_pad); -} - -/** \brief converts uint16_t into char array - * - * Takes an uint16_t, and uses an internal static buffer to render that value into a char array - * A padding character may be specified, ' ' for leading spaces, '0' for leading zeros. - * - * NOTE: Subsequent invocations will reuse the same static buffer and overwrite the previous - * contents. Use the result immediately, instead of caching it. - */ -const char *get_u16_str(uint16_t curr_num, char curr_pad) { - static char buf[6] = {0}; - static uint16_t last_num = 0xFF; - static char last_pad = '\0'; - if (last_num == curr_num && last_pad == curr_pad) { - return buf; - } - last_num = curr_num; - last_pad = curr_pad; - return get_numeric_str(buf, sizeof(buf), curr_num, curr_pad); -} - -#if defined(SECURE_ENABLE) -void secure_hook_quantum(secure_status_t secure_status) { - // If keys are being held when this is triggered, they may not be released properly - // this can result in stuck keys, mods and layers. To prevent that, manually - // clear these, when it is triggered. - - if (secure_status == SECURE_PENDING) { - clear_keyboard(); - layer_clear(); - } -} -#endif diff --git a/quantum/quantum.h b/quantum/quantum.h deleted file mode 100644 index 31a1a63a7acb..000000000000 --- a/quantum/quantum.h +++ /dev/null @@ -1,291 +0,0 @@ -/* Copyright 2016-2018 Erez Zukerman, Jack Humbert, Yiancar - * - * 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 . - */ -#pragma once - -#include "platform_deps.h" -#include "wait.h" -#include "matrix.h" -#include "keyboard.h" - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif - -#ifdef LED_MATRIX_ENABLE -# include "led_matrix.h" -#endif - -#if defined(RGBLIGHT_ENABLE) -# include "rgblight.h" -#endif - -#ifdef RGB_MATRIX_ENABLE -# include "rgb_matrix.h" -#endif - -#include "keymap_common.h" -#include "quantum_keycodes.h" -#include "keycode_config.h" -#include "action_layer.h" -#include "eeconfig.h" -#include "bootloader.h" -#include "bootmagic.h" -#include "timer.h" -#include "sync_timer.h" -#include "gpio.h" -#include "atomic_util.h" -#include "host.h" -#include "led.h" -#include "action_util.h" -#include "action_tapping.h" -#include "print.h" -#include "debug.h" -#include "suspend.h" -#include -#include - -#ifdef DEFERRED_EXEC_ENABLE -# include "deferred_exec.h" -#endif - -extern layer_state_t default_layer_state; - -#ifndef NO_ACTION_LAYER -extern layer_state_t layer_state; -#endif - -#if defined(SEQUENCER_ENABLE) -# include "sequencer.h" -# include "process_sequencer.h" -#endif - -#if defined(MIDI_ENABLE) && defined(MIDI_ADVANCED) -# include "process_midi.h" -#endif - -#ifdef AUDIO_ENABLE -# include "audio.h" -# include "process_audio.h" -# include "song_list.h" -# ifdef AUDIO_CLICKY -# include "process_clicky.h" -# endif -#endif - -#ifdef STENO_ENABLE -# include "process_steno.h" -#endif - -#if defined(AUDIO_ENABLE) || (defined(MIDI_ENABLE) && defined(MIDI_BASIC)) -# include "process_music.h" -#endif - -#if defined(BACKLIGHT_ENABLE) || defined(LED_MATRIX_ENABLE) -# include "process_backlight.h" -#endif - -#ifdef LEADER_ENABLE -# include "leader.h" -# include "process_leader.h" -#endif - -#ifdef UNICODE_ENABLE -# include "process_unicode.h" -#endif - -#ifdef UCIS_ENABLE -# include "process_ucis.h" -#endif - -#ifdef UNICODEMAP_ENABLE -# include "process_unicodemap.h" -#endif - -#ifdef UNICODE_COMMON_ENABLE -# include "unicode.h" -# include "process_unicode_common.h" -#endif - -#ifdef KEY_OVERRIDE_ENABLE -# include "process_key_override.h" -#endif - -#ifdef TAP_DANCE_ENABLE -# include "process_tap_dance.h" -#endif - -#ifdef AUTO_SHIFT_ENABLE -# include "process_auto_shift.h" -#endif - -#ifdef DYNAMIC_TAPPING_TERM_ENABLE -# include "process_dynamic_tapping_term.h" -#endif - -#ifdef COMBO_ENABLE -# include "process_combo.h" -#endif - -#ifdef KEY_LOCK_ENABLE -# include "process_key_lock.h" -#endif - -#ifdef SPACE_CADET_ENABLE -# include "process_space_cadet.h" -#endif - -#ifdef MAGIC_KEYCODE_ENABLE -# include "process_magic.h" -#endif - -#ifdef JOYSTICK_ENABLE -# include "process_joystick.h" -#endif - -#ifdef PROGRAMMABLE_BUTTON_ENABLE -# include "process_programmable_button.h" -#endif - -#ifdef GRAVE_ESC_ENABLE -# include "process_grave_esc.h" -#endif - -#if defined(RGBLIGHT_ENABLE) || defined(RGB_MATRIX_ENABLE) -# include "process_rgb.h" -#endif - -#ifdef HD44780_ENABLE -# include "hd44780.h" -#endif - -#ifdef SEND_STRING_ENABLE -# include "send_string.h" -#endif - -#ifdef HAPTIC_ENABLE -# include "haptic.h" -# include "process_haptic.h" -#endif - -#ifdef OLED_ENABLE -# include "oled_driver.h" -#endif - -#ifdef ST7565_ENABLE -# include "st7565.h" -#endif - -#ifdef QUANTUM_PAINTER_ENABLE -# include "qp.h" -#endif - -#ifdef DIP_SWITCH_ENABLE -# include "dip_switch.h" -#endif - -#ifdef DYNAMIC_MACRO_ENABLE -# include "process_dynamic_macro.h" -#endif - -#ifdef SECURE_ENABLE -# include "secure.h" -# include "process_secure.h" -#endif - -#ifdef DYNAMIC_KEYMAP_ENABLE -# include "dynamic_keymap.h" -#endif - -#ifdef JOYSTICK_ENABLE -# include "joystick.h" -#endif - -#ifdef DIGITIZER_ENABLE -# include "digitizer.h" -#endif - -#ifdef VIA_ENABLE -# include "via.h" -#endif - -#ifdef WPM_ENABLE -# include "wpm.h" -#endif - -#ifdef USBPD_ENABLE -# include "usbpd.h" -#endif - -#ifdef ENCODER_ENABLE -# include "encoder.h" -#endif - -#ifdef POINTING_DEVICE_ENABLE -# include "pointing_device.h" -#endif - -#ifdef CAPS_WORD_ENABLE -# include "caps_word.h" -# include "process_caps_word.h" -#endif - -#ifdef AUTOCORRECT_ENABLE -# include "process_autocorrect.h" -#endif - -#ifdef TRI_LAYER_ENABLE -# include "tri_layer.h" -# include "process_tri_layer.h" -#endif - -#ifdef REPEAT_KEY_ENABLE -# include "repeat_key.h" -# include "process_repeat_key.h" -#endif - -void set_single_persistent_default_layer(uint8_t default_layer); - -#define IS_LAYER_ON(layer) layer_state_is(layer) -#define IS_LAYER_OFF(layer) !layer_state_is(layer) - -#define IS_LAYER_ON_STATE(state, layer) layer_state_cmp(state, layer) -#define IS_LAYER_OFF_STATE(state, layer) !layer_state_cmp(state, layer) - -uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache); -uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache); -bool pre_process_record_quantum(keyrecord_t *record); -bool pre_process_record_kb(uint16_t keycode, keyrecord_t *record); -bool pre_process_record_user(uint16_t keycode, keyrecord_t *record); -bool process_action_kb(keyrecord_t *record); -bool process_record_kb(uint16_t keycode, keyrecord_t *record); -bool process_record_user(uint16_t keycode, keyrecord_t *record); -void post_process_record_kb(uint16_t keycode, keyrecord_t *record); -void post_process_record_user(uint16_t keycode, keyrecord_t *record); - -void reset_keyboard(void); -void soft_reset_keyboard(void); - -void startup_user(void); -void shutdown_user(void); - -void register_code16(uint16_t code); -void unregister_code16(uint16_t code); -void tap_code16(uint16_t code); -void tap_code16_delay(uint16_t code, uint16_t delay); - -const char *get_numeric_str(char *buf, size_t buf_len, uint32_t curr_num, char curr_pad); -const char *get_u8_str(uint8_t curr_num, char curr_pad); -const char *get_u16_str(uint16_t curr_num, char curr_pad); diff --git a/quantum/quantum_keycodes.h b/quantum/quantum_keycodes.h index f931b7e4c70a..d3249bd45559 100644 --- a/quantum/quantum_keycodes.h +++ b/quantum/quantum_keycodes.h @@ -179,10 +179,10 @@ #define QK_UNICODE_GET_CODE_POINT(kc) ((kc)&0x7FFF) // UNICODEMAP_ENABLE - Allows Unicode input up to 0x10FFFF, requires unicode_map -#define X(i) (QK_UNICODEMAP | ((i)&0x3FFF)) +#define UM(i) (QK_UNICODEMAP | ((i)&0x3FFF)) #define QK_UNICODEMAP_GET_INDEX(kc) ((kc)&0x3FFF) -#define XP(i, j) (QK_UNICODEMAP_PAIR | ((i)&0x7F) | (((j)&0x7F) << 7)) // 127 max i and j +#define UP(i, j) (QK_UNICODEMAP_PAIR | ((i)&0x7F) | (((j)&0x7F) << 7)) // 127 max i and j #define QK_UNICODEMAP_PAIR_GET_UNSHIFTED_INDEX(kc) ((kc)&0x7F) #define QK_UNICODEMAP_PAIR_GET_SHIFTED_INDEX(kc) (((kc) >> 7) & 0x7F) diff --git a/quantum/quantum_keycodes_legacy.h b/quantum/quantum_keycodes_legacy.h index 120c98bc6283..ad078cdad5ce 100644 --- a/quantum/quantum_keycodes_legacy.h +++ b/quantum/quantum_keycodes_legacy.h @@ -53,3 +53,6 @@ #define GUI_ON QK_MAGIC_GUI_ON #define GUI_OFF QK_MAGIC_GUI_OFF #define GUI_TOG QK_MAGIC_TOGGLE_GUI + +#define X(i) UM(i) +#define XP(i, j) UM(i, j) diff --git a/quantum/raw_hid.h b/quantum/raw_hid.h deleted file mode 100644 index 6d60ab2bffc1..000000000000 --- a/quantum/raw_hid.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -void raw_hid_receive(uint8_t *data, uint8_t length); - -void raw_hid_send(uint8_t *data, uint8_t length); diff --git a/quantum/repeat_key.c b/quantum/repeat_key.c deleted file mode 100644 index 0689c6d45476..000000000000 --- a/quantum/repeat_key.c +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2022-2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include "repeat_key.h" - -// Variables saving the state of the last key press. -static keyrecord_t last_record = {0}; -static uint8_t last_mods = 0; -// Signed count of the number of times the last key has been repeated or -// alternate repeated: it is 0 when a key is pressed normally, positive when -// repeated, and negative when alternate repeated. -static int8_t last_repeat_count = 0; -// The repeat_count, but set to 0 outside of repeat_key_invoke() so that it is -// nonzero only while a repeated key is being processed. -static int8_t processing_repeat_count = 0; - -uint16_t get_last_keycode(void) { - return last_record.keycode; -} - -uint8_t get_last_mods(void) { - return last_mods; -} - -void set_last_keycode(uint16_t keycode) { - set_last_record(keycode, &(keyrecord_t){ -#ifndef NO_ACTION_TAPPING - .tap.interrupted = false, - .tap.count = 1, -#endif - }); -} - -void set_last_mods(uint8_t mods) { - last_mods = mods; -} - -void set_last_record(uint16_t keycode, keyrecord_t* record) { - last_record = *record; - last_record.keycode = keycode; - last_repeat_count = 0; -} - -/** @brief Updates `last_repeat_count` in direction `dir`. */ -static void update_last_repeat_count(int8_t dir) { - if (dir * last_repeat_count < 0) { - last_repeat_count = dir; - } else if (dir * last_repeat_count < 127) { - last_repeat_count += dir; - } -} - -int8_t get_repeat_key_count(void) { - return processing_repeat_count; -} - -void repeat_key_invoke(const keyevent_t* event) { - // It is possible (e.g. in rolled presses) that the last key changes while - // the Repeat Key is pressed. To prevent stuck keys, it is important to - // remember separately what key record was processed on press so that the - // the corresponding record is generated on release. - static keyrecord_t registered_record = {0}; - static int8_t registered_repeat_count = 0; - // Since this function calls process_record(), it may recursively call - // itself. We return early if `processing_repeat_count` is nonzero to - // prevent infinite recursion. - if (processing_repeat_count || !last_record.keycode) { - return; - } - - if (event->pressed) { - update_last_repeat_count(1); - // On press, apply the last mods state, stacking on top of current mods. - register_weak_mods(last_mods); - registered_record = last_record; - registered_repeat_count = last_repeat_count; - } - - // Generate a keyrecord and plumb it into the event pipeline. - registered_record.event = *event; - processing_repeat_count = registered_repeat_count; - process_record(®istered_record); - processing_repeat_count = 0; - - // On release, restore the mods state. - if (!event->pressed) { - unregister_weak_mods(last_mods); - } -} - -#ifndef NO_ALT_REPEAT_KEY -/** - * @brief Find alternate keycode from a table of opposing keycode pairs. - * @param table Array of pairs of basic keycodes, declared as PROGMEM. - * @param table_size_bytes The size of the table in bytes. - * @param target The basic keycode to find. - * @return The alternate basic keycode, or KC_NO if none was found. - * - * @note The table keycodes and target must be basic keycodes. - * - * This helper is used several times below to define alternate keys. Given a - * table of pairs of basic keycodes, the function finds the pair containing - * `target` and returns the other keycode in the pair. - */ -static uint8_t find_alt_keycode(const uint8_t (*table)[2], uint8_t table_size_bytes, uint8_t target) { - const uint8_t* keycodes = (const uint8_t*)table; - for (uint8_t i = 0; i < table_size_bytes; ++i) { - if (target == pgm_read_byte(keycodes + i)) { - // Xor (i ^ 1) the index to get the other element in the pair. - return pgm_read_byte(keycodes + (i ^ 1)); - } - } - return KC_NO; -} - -uint16_t get_alt_repeat_key_keycode(void) { - uint16_t keycode = last_record.keycode; - uint8_t mods = last_mods; - - // Call the user callback first to give it a chance to override the default - // alternate key definitions that follow. - uint16_t alt_keycode = get_alt_repeat_key_keycode_user(keycode, mods); - - if (alt_keycode != KC_TRANSPARENT) { - return alt_keycode; - } - - // Convert 8-bit mods to the 5-bit format used in keycodes. This is lossy: - // if left and right handed mods were mixed, they all become right handed. - mods = ((mods & 0xf0) ? /* set right hand bit */ 0x10 : 0) - // Combine right and left hand mods. - | (((mods >> 4) | mods) & 0xf); - - switch (keycode) { - case QK_MODS ... QK_MODS_MAX: // Unpack modifier + basic key. - mods |= QK_MODS_GET_MODS(keycode); - keycode = QK_MODS_GET_BASIC_KEYCODE(keycode); - break; - -# ifndef NO_ACTION_TAPPING - case QK_MOD_TAP ... QK_MOD_TAP_MAX: - keycode = QK_MOD_TAP_GET_TAP_KEYCODE(keycode); - break; -# ifndef NO_ACTION_LAYER - case QK_LAYER_TAP ... QK_LAYER_TAP_MAX: - keycode = QK_LAYER_TAP_GET_TAP_KEYCODE(keycode); - break; -# endif // NO_ACTION_LAYER -# endif // NO_ACTION_TAPPING - -# ifdef SWAP_HANDS_ENABLE - case QK_SWAP_HANDS ... QK_SWAP_HANDS_MAX: - if (IS_SWAP_HANDS_KEYCODE(keycode)) { - return KC_NO; - } - keycode = QK_SWAP_HANDS_GET_TAP_KEYCODE(keycode); - break; -# endif // SWAP_HANDS_ENABLE - } - - if (IS_QK_BASIC(keycode)) { - if ((mods & (MOD_LCTL | MOD_LALT | MOD_LGUI))) { - // The last key was pressed with a modifier other than Shift. - // The following maps - // mod + F <-> mod + B - // and a few others, supporting several core hotkeys used in - // Emacs, Vim, less, and other programs. - // clang-format off - static const uint8_t pairs[][2] PROGMEM = { - {KC_F , KC_B }, // Forward / Backward. - {KC_D , KC_U }, // Down / Up. - {KC_N , KC_P }, // Next / Previous. - {KC_A , KC_E }, // Home / End. - {KC_O , KC_I }, // Older / Newer in Vim jump list. - }; - // clang-format on - alt_keycode = find_alt_keycode(pairs, sizeof(pairs), keycode); - } else { - // The last key was pressed with no mods or only Shift. The - // following map a few more Vim hotkeys. - // clang-format off - static const uint8_t pairs[][2] PROGMEM = { - {KC_J , KC_K }, // Down / Up. - {KC_H , KC_L }, // Left / Right. - // These two lines map W and E to B, and B to W. - {KC_W , KC_B }, // Forward / Backward by word. - {KC_E , KC_B }, // Forward / Backward by word. - }; - // clang-format on - alt_keycode = find_alt_keycode(pairs, sizeof(pairs), keycode); - } - - if (!alt_keycode) { - // The following key pairs are considered with any mods. - // clang-format off - static const uint8_t pairs[][2] PROGMEM = { - {KC_LEFT, KC_RGHT}, // Left / Right Arrow. - {KC_UP , KC_DOWN}, // Up / Down Arrow. - {KC_HOME, KC_END }, // Home / End. - {KC_PGUP, KC_PGDN}, // Page Up / Page Down. - {KC_BSPC, KC_DEL }, // Backspace / Delete. - {KC_LBRC, KC_RBRC}, // Brackets [ ] and { }. -#ifdef EXTRAKEY_ENABLE - {KC_WBAK, KC_WFWD}, // Browser Back / Forward. - {KC_MNXT, KC_MPRV}, // Next / Previous Media Track. - {KC_MFFD, KC_MRWD}, // Fast Forward / Rewind Media. - {KC_VOLU, KC_VOLD}, // Volume Up / Down. - {KC_BRIU, KC_BRID}, // Brightness Up / Down. -#endif // EXTRAKEY_ENABLE -#ifdef MOUSEKEY_ENABLE - {KC_MS_L, KC_MS_R}, // Mouse Cursor Left / Right. - {KC_MS_U, KC_MS_D}, // Mouse Cursor Up / Down. - {KC_WH_L, KC_WH_R}, // Mouse Wheel Left / Right. - {KC_WH_U, KC_WH_D}, // Mouse Wheel Up / Down. -#endif // MOUSEKEY_ENABLE - }; - // clang-format on - alt_keycode = find_alt_keycode(pairs, sizeof(pairs), keycode); - } - - if (alt_keycode) { - // Combine basic keycode with mods. - return (mods << 8) | alt_keycode; - } - } - - return KC_NO; // No alternate key found. -} - -void alt_repeat_key_invoke(const keyevent_t* event) { - static keyrecord_t registered_record = {0}; - static int8_t registered_repeat_count = 0; - // Since this function calls process_record(), it may recursively call - // itself. We return early if `processing_repeat_count` is nonzero to - // prevent infinite recursion. - if (processing_repeat_count) { - return; - } - - if (event->pressed) { - registered_record = (keyrecord_t){ -# ifndef NO_ACTION_TAPPING - .tap.interrupted = false, - .tap.count = 0, -# endif - .keycode = get_alt_repeat_key_keycode(), - }; - } - - // Early return if there is no alternate key defined. - if (!registered_record.keycode) { - return; - } - - if (event->pressed) { - update_last_repeat_count(-1); - registered_repeat_count = last_repeat_count; - } - - // Generate a keyrecord and plumb it into the event pipeline. - registered_record.event = *event; - processing_repeat_count = registered_repeat_count; - process_record(®istered_record); - processing_repeat_count = 0; -} - -// Default implementation of get_alt_repeat_key_keycode_user(). -__attribute__((weak)) uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods) { - return KC_TRANSPARENT; -} -#endif // NO_ALT_REPEAT_KEY diff --git a/quantum/repeat_key.h b/quantum/repeat_key.h deleted file mode 100644 index 06e83645295c..000000000000 --- a/quantum/repeat_key.h +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2022-2023 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#pragma once - -#include "quantum.h" - -uint16_t get_last_keycode(void); /**< Keycode of the last key. */ -uint8_t get_last_mods(void); /**< Mods active with the last key. */ -void set_last_keycode(uint16_t keycode); /**< Sets the last key. */ -void set_last_mods(uint8_t mods); /**< Sets the last mods. */ - -/** @brief Gets the record for the last key. */ -keyrecord_t* get_last_record(void); - -/** @brief Sets keycode and record info for the last key. */ -void set_last_record(uint16_t keycode, keyrecord_t* record); - -/** - * @brief Signed count of times the key has been repeated or alternate repeated. - * - * @note The count is nonzero only while a repeated or alternate-repeated key is - * being processed. - * - * When a key is pressed normally, the count is 0. When the Repeat Key is used - * to repeat a key, the count is 1 on the first repeat, 2 on the second repeat, - * and continuing up to 127. - * - * Negative counts are used similarly for alternate repeating. When the - * Alternate Repeat Key is used, the count is -1 on the first alternate repeat, - * -2 on the second, continuing down to -127. - */ -int8_t get_repeat_key_count(void); - -/** - * @brief Calls `process_record()` on a generated record repeating the last key. - * @param event Event information in the generated record. - */ -void repeat_key_invoke(const keyevent_t* event); - -#ifndef NO_ALT_REPEAT_KEY - -/** - * @brief Keycode to be used for alternate repeating. - * - * Alternate Repeat performs this keycode based on the last eligible pressed key - * and mods, get_last_keycode() and get_last_mods(). For example, when the last - * key was KC_UP, this function returns KC_DOWN. The function returns KC_NO if - * the last key doesn't have a defined alternate. - */ -uint16_t get_alt_repeat_key_keycode(void); - -/** - * @brief Calls `process_record()` to alternate repeat the last key. - * @param event Event information in the generated record. - */ -void alt_repeat_key_invoke(const keyevent_t* event); - -/** - * @brief Optional user callback to define additional alternate keys. - * - * When `get_alt_repeat_key_keycode()` is called, it first calls this callback. - * It should return a keycode representing the "alternate" of the given keycode - * and mods. Returning KC_NO defers to the default definitions in - * `get_alt_repeat_key_keycode()`. - */ -uint16_t get_alt_repeat_key_keycode_user(uint16_t keycode, uint8_t mods); - -#endif // NO_ALT_REPEAT_KEY diff --git a/quantum/rgb_matrix/animations/alpha_mods_anim.h b/quantum/rgb_matrix/animations/alpha_mods_anim.h deleted file mode 100644 index 59b8381d6984..000000000000 --- a/quantum/rgb_matrix/animations/alpha_mods_anim.h +++ /dev/null @@ -1,26 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_ALPHAS_MODS -RGB_MATRIX_EFFECT(ALPHAS_MODS) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -// alphas = color1, mods = color2 -bool ALPHAS_MODS(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - HSV hsv = rgb_matrix_config.hsv; - RGB rgb1 = rgb_matrix_hsv_to_rgb(hsv); - hsv.h += rgb_matrix_config.speed; - RGB rgb2 = rgb_matrix_hsv_to_rgb(hsv); - - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - if (HAS_FLAGS(g_led_config.flags[i], LED_FLAG_MODIFIER)) { - rgb_matrix_set_color(i, rgb2.r, rgb2.g, rgb2.b); - } else { - rgb_matrix_set_color(i, rgb1.r, rgb1.g, rgb1.b); - } - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_ALPHAS_MODS diff --git a/quantum/rgb_matrix/animations/breathing_anim.h b/quantum/rgb_matrix/animations/breathing_anim.h deleted file mode 100644 index e9a3c96e1bb8..000000000000 --- a/quantum/rgb_matrix/animations/breathing_anim.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BREATHING -RGB_MATRIX_EFFECT(BREATHING) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -bool BREATHING(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - HSV hsv = rgb_matrix_config.hsv; - uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8); - hsv.v = scale8(abs8(sin8(time) - 128) * 2, hsv.v); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BREATHING diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h deleted file mode 100644 index 06aa8b5ed5f4..000000000000 --- a/quantum/rgb_matrix/animations/colorband_pinwheel_sat_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT -RGB_MATRIX_EFFECT(BAND_PINWHEEL_SAT) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_PINWHEEL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) { - hsv.s = scale8(hsv.s - time - atan2_8(dy, dx) * 3, hsv.s); - return hsv; -} - -bool BAND_PINWHEEL_SAT(effect_params_t* params) { - return effect_runner_dx_dy(params, &BAND_PINWHEEL_SAT_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_PINWHEEL_SAT diff --git a/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h b/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h deleted file mode 100644 index bcbc31949814..000000000000 --- a/quantum/rgb_matrix/animations/colorband_pinwheel_val_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL -RGB_MATRIX_EFFECT(BAND_PINWHEEL_VAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_PINWHEEL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) { - hsv.v = scale8(hsv.v - time - atan2_8(dy, dx) * 3, hsv.v); - return hsv; -} - -bool BAND_PINWHEEL_VAL(effect_params_t* params) { - return effect_runner_dx_dy(params, &BAND_PINWHEEL_VAL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_PINWHEEL_VAL diff --git a/quantum/rgb_matrix/animations/colorband_sat_anim.h b/quantum/rgb_matrix/animations/colorband_sat_anim.h deleted file mode 100644 index cb0897ad3e9a..000000000000 --- a/quantum/rgb_matrix/animations/colorband_sat_anim.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_SAT -RGB_MATRIX_EFFECT(BAND_SAT) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_SAT_math(HSV hsv, uint8_t i, uint8_t time) { - int16_t s = hsv.s - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8; - hsv.s = scale8(s < 0 ? 0 : s, hsv.s); - return hsv; -} - -bool BAND_SAT(effect_params_t* params) { - return effect_runner_i(params, &BAND_SAT_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_SAT diff --git a/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h deleted file mode 100644 index d26eb378558a..000000000000 --- a/quantum/rgb_matrix/animations/colorband_spiral_sat_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT -RGB_MATRIX_EFFECT(BAND_SPIRAL_SAT) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_SPIRAL_SAT_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - hsv.s = scale8(hsv.s + dist - time - atan2_8(dy, dx), hsv.s); - return hsv; -} - -bool BAND_SPIRAL_SAT(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_SAT_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_SPIRAL_SAT diff --git a/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h b/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h deleted file mode 100644 index 3ae34bb6f097..000000000000 --- a/quantum/rgb_matrix/animations/colorband_spiral_val_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL -RGB_MATRIX_EFFECT(BAND_SPIRAL_VAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_SPIRAL_VAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - hsv.v = scale8(hsv.v + dist - time - atan2_8(dy, dx), hsv.v); - return hsv; -} - -bool BAND_SPIRAL_VAL(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &BAND_SPIRAL_VAL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_SPIRAL_VAL diff --git a/quantum/rgb_matrix/animations/colorband_val_anim.h b/quantum/rgb_matrix/animations/colorband_val_anim.h deleted file mode 100644 index 69c29f53a355..000000000000 --- a/quantum/rgb_matrix/animations/colorband_val_anim.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_BAND_VAL -RGB_MATRIX_EFFECT(BAND_VAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV BAND_VAL_math(HSV hsv, uint8_t i, uint8_t time) { - int16_t v = hsv.v - abs(scale8(g_led_config.point[i].x, 228) + 28 - time) * 8; - hsv.v = scale8(v < 0 ? 0 : v, hsv.v); - return hsv; -} - -bool BAND_VAL(effect_params_t* params) { - return effect_runner_i(params, &BAND_VAL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_BAND_VAL diff --git a/quantum/rgb_matrix/animations/cycle_all_anim.h b/quantum/rgb_matrix/animations/cycle_all_anim.h deleted file mode 100644 index d8c7220d95e7..000000000000 --- a/quantum/rgb_matrix/animations/cycle_all_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_ALL -RGB_MATRIX_EFFECT(CYCLE_ALL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_ALL_math(HSV hsv, uint8_t i, uint8_t time) { - hsv.h = time; - return hsv; -} - -bool CYCLE_ALL(effect_params_t* params) { - return effect_runner_i(params, &CYCLE_ALL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_ALL diff --git a/quantum/rgb_matrix/animations/cycle_left_right_anim.h b/quantum/rgb_matrix/animations/cycle_left_right_anim.h deleted file mode 100644 index 84c2127aff9a..000000000000 --- a/quantum/rgb_matrix/animations/cycle_left_right_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT -RGB_MATRIX_EFFECT(CYCLE_LEFT_RIGHT) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_LEFT_RIGHT_math(HSV hsv, uint8_t i, uint8_t time) { - hsv.h = g_led_config.point[i].x - time; - return hsv; -} - -bool CYCLE_LEFT_RIGHT(effect_params_t* params) { - return effect_runner_i(params, &CYCLE_LEFT_RIGHT_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT diff --git a/quantum/rgb_matrix/animations/cycle_out_in_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_anim.h deleted file mode 100644 index 9513fe959344..000000000000 --- a/quantum/rgb_matrix/animations/cycle_out_in_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN -RGB_MATRIX_EFFECT(CYCLE_OUT_IN) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_OUT_IN_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - hsv.h = 3 * dist / 2 + time; - return hsv; -} - -bool CYCLE_OUT_IN(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &CYCLE_OUT_IN_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_OUT_IN diff --git a/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h b/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h deleted file mode 100644 index 3cca45f27a57..000000000000 --- a/quantum/rgb_matrix/animations/cycle_out_in_dual_anim.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL -RGB_MATRIX_EFFECT(CYCLE_OUT_IN_DUAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_OUT_IN_DUAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) { - dx = (k_rgb_matrix_center.x / 2) - abs8(dx); - uint8_t dist = sqrt16(dx * dx + dy * dy); - hsv.h = 3 * dist + time; - return hsv; -} - -bool CYCLE_OUT_IN_DUAL(effect_params_t* params) { - return effect_runner_dx_dy(params, &CYCLE_OUT_IN_DUAL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_OUT_IN_DUAL diff --git a/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h b/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h deleted file mode 100644 index de5993992cbe..000000000000 --- a/quantum/rgb_matrix/animations/cycle_pinwheel_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_PINWHEEL -RGB_MATRIX_EFFECT(CYCLE_PINWHEEL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_PINWHEEL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t time) { - hsv.h = atan2_8(dy, dx) + time; - return hsv; -} - -bool CYCLE_PINWHEEL(effect_params_t* params) { - return effect_runner_dx_dy(params, &CYCLE_PINWHEEL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_PINWHEEL diff --git a/quantum/rgb_matrix/animations/cycle_spiral_anim.h b/quantum/rgb_matrix/animations/cycle_spiral_anim.h deleted file mode 100644 index 904450179eb1..000000000000 --- a/quantum/rgb_matrix/animations/cycle_spiral_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_SPIRAL -RGB_MATRIX_EFFECT(CYCLE_SPIRAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_SPIRAL_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time) { - hsv.h = dist - time - atan2_8(dy, dx); - return hsv; -} - -bool CYCLE_SPIRAL(effect_params_t* params) { - return effect_runner_dx_dy_dist(params, &CYCLE_SPIRAL_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_SPIRAL diff --git a/quantum/rgb_matrix/animations/cycle_up_down_anim.h b/quantum/rgb_matrix/animations/cycle_up_down_anim.h deleted file mode 100644 index dce05fecff0c..000000000000 --- a/quantum/rgb_matrix/animations/cycle_up_down_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_CYCLE_UP_DOWN -RGB_MATRIX_EFFECT(CYCLE_UP_DOWN) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV CYCLE_UP_DOWN_math(HSV hsv, uint8_t i, uint8_t time) { - hsv.h = g_led_config.point[i].y - time; - return hsv; -} - -bool CYCLE_UP_DOWN(effect_params_t* params) { - return effect_runner_i(params, &CYCLE_UP_DOWN_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_CYCLE_UP_DOWN diff --git a/quantum/rgb_matrix/animations/digital_rain_anim.h b/quantum/rgb_matrix/animations/digital_rain_anim.h deleted file mode 100644 index 7d3b22f697a1..000000000000 --- a/quantum/rgb_matrix/animations/digital_rain_anim.h +++ /dev/null @@ -1,83 +0,0 @@ -#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_DIGITAL_RAIN) -RGB_MATRIX_EFFECT(DIGITAL_RAIN) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -# ifndef RGB_DIGITAL_RAIN_DROPS -// lower the number for denser effect/wider keyboard -# define RGB_DIGITAL_RAIN_DROPS 24 -# endif - -bool DIGITAL_RAIN(effect_params_t* params) { - // algorithm ported from https://github.com/tremby/Kaleidoscope-LEDEffect-DigitalRain - const uint8_t drop_ticks = 28; - const uint8_t pure_green_intensity = (((uint16_t)rgb_matrix_config.hsv.v) * 3) >> 2; - const uint8_t max_brightness_boost = (((uint16_t)rgb_matrix_config.hsv.v) * 3) >> 2; - const uint8_t max_intensity = rgb_matrix_config.hsv.v; - const uint8_t decay_ticks = 0xff / max_intensity; - - static uint8_t drop = 0; - static uint8_t decay = 0; - - if (params->init) { - rgb_matrix_set_color_all(0, 0, 0); - memset(g_rgb_frame_buffer, 0, sizeof(g_rgb_frame_buffer)); - drop = 0; - } - - decay++; - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - for (uint8_t row = 0; row < MATRIX_ROWS; row++) { - if (row == 0 && drop == 0 && rand() < RAND_MAX / RGB_DIGITAL_RAIN_DROPS) { - // top row, pixels have just fallen and we're - // making a new rain drop in this column - g_rgb_frame_buffer[row][col] = max_intensity; - } else if (g_rgb_frame_buffer[row][col] > 0 && g_rgb_frame_buffer[row][col] < max_intensity) { - // neither fully bright nor dark, decay it - if (decay == decay_ticks) { - g_rgb_frame_buffer[row][col]--; - } - } - // set the pixel colour - uint8_t led[LED_HITS_TO_REMEMBER]; - uint8_t led_count = rgb_matrix_map_row_column_to_led(row, col, led); - - // TODO: multiple leds are supported mapped to the same row/column - if (led_count > 0) { - if (g_rgb_frame_buffer[row][col] > pure_green_intensity) { - const uint8_t boost = (uint8_t)((uint16_t)max_brightness_boost * (g_rgb_frame_buffer[row][col] - pure_green_intensity) / (max_intensity - pure_green_intensity)); - rgb_matrix_set_color(led[0], boost, max_intensity, boost); - } else { - const uint8_t green = (uint8_t)((uint16_t)max_intensity * g_rgb_frame_buffer[row][col] / pure_green_intensity); - rgb_matrix_set_color(led[0], 0, green, 0); - } - } - } - } - if (decay == decay_ticks) { - decay = 0; - } - - if (++drop > drop_ticks) { - // reset drop timer - drop = 0; - for (uint8_t row = MATRIX_ROWS - 1; row > 0; row--) { - for (uint8_t col = 0; col < MATRIX_COLS; col++) { - // if ths is on the bottom row and bright allow decay - if (row == MATRIX_ROWS - 1 && g_rgb_frame_buffer[row][col] == max_intensity) { - g_rgb_frame_buffer[row][col]--; - } - // check if the pixel above is bright - if (g_rgb_frame_buffer[row - 1][col] >= max_intensity) { // Note: can be larger than max_intensity if val was recently decreased - // allow old bright pixel to decay - g_rgb_frame_buffer[row - 1][col] = max_intensity - 1; - // make this pixel bright - g_rgb_frame_buffer[row][col] = max_intensity; - } - } - } - } - return false; -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && !defined(ENABLE_RGB_MATRIX_DIGITAL_RAIN) diff --git a/quantum/rgb_matrix/animations/dual_beacon_anim.h b/quantum/rgb_matrix/animations/dual_beacon_anim.h deleted file mode 100644 index 5585015b8694..000000000000 --- a/quantum/rgb_matrix/animations/dual_beacon_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_DUAL_BEACON -RGB_MATRIX_EFFECT(DUAL_BEACON) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV DUAL_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { - hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * sin) / 128; - return hsv; -} - -bool DUAL_BEACON(effect_params_t* params) { - return effect_runner_sin_cos_i(params, &DUAL_BEACON_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_DUAL_BEACON diff --git a/quantum/rgb_matrix/animations/gradient_left_right_anim.h b/quantum/rgb_matrix/animations/gradient_left_right_anim.h deleted file mode 100644 index ebb06f59f278..000000000000 --- a/quantum/rgb_matrix/animations/gradient_left_right_anim.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT -RGB_MATRIX_EFFECT(GRADIENT_LEFT_RIGHT) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -bool GRADIENT_LEFT_RIGHT(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - HSV hsv = rgb_matrix_config.hsv; - uint8_t scale = scale8(64, rgb_matrix_config.speed); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - // The x range will be 0..224, map this to 0..7 - // Relies on hue being 8-bit and wrapping - hsv.h = rgb_matrix_config.hsv.h + (scale * g_led_config.point[i].x >> 5); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_GRADIENT_LEFT_RIGHT diff --git a/quantum/rgb_matrix/animations/gradient_up_down_anim.h b/quantum/rgb_matrix/animations/gradient_up_down_anim.h deleted file mode 100644 index febc3919a888..000000000000 --- a/quantum/rgb_matrix/animations/gradient_up_down_anim.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN -RGB_MATRIX_EFFECT(GRADIENT_UP_DOWN) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -bool GRADIENT_UP_DOWN(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - HSV hsv = rgb_matrix_config.hsv; - uint8_t scale = scale8(64, rgb_matrix_config.speed); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - // The y range will be 0..64, map this to 0..4 - // Relies on hue being 8-bit and wrapping - hsv.h = rgb_matrix_config.hsv.h + scale * (g_led_config.point[i].y >> 4); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_GRADIENT_UP_DOWN diff --git a/quantum/rgb_matrix/animations/hue_breathing_anim.h b/quantum/rgb_matrix/animations/hue_breathing_anim.h deleted file mode 100644 index 853776283298..000000000000 --- a/quantum/rgb_matrix/animations/hue_breathing_anim.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_HUE_BREATHING -RGB_MATRIX_EFFECT(HUE_BREATHING) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -// Change huedelta to adjust range of hue change. 0-255. -// Hue Breathing - All LED's light up -bool HUE_BREATHING(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - uint8_t huedelta = 12; - HSV hsv = rgb_matrix_config.hsv; - uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 8); - hsv.h = hsv.h + scale8(abs8(sin8(time) - 128) * 2, huedelta); - RGB rgb = hsv_to_rgb(hsv); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // DISABLE_RGB_HUE_BREATHING diff --git a/quantum/rgb_matrix/animations/hue_pendulum_anim.h b/quantum/rgb_matrix/animations/hue_pendulum_anim.h deleted file mode 100644 index 7d8cbcdfb243..000000000000 --- a/quantum/rgb_matrix/animations/hue_pendulum_anim.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_HUE_PENDULUM -RGB_MATRIX_EFFECT(HUE_PENDULUM) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -// Change huedelta to adjust range of hue change. 0-255. -// Looks better with a low value and slow speed for subtle change. -// Hue Pendulum - color changes in a wave to the right before reversing direction -static HSV HUE_PENDULUM_math(HSV hsv, uint8_t i, uint8_t time) { - uint8_t huedelta = 12; - hsv.h = hsv.h + scale8(abs8(sin8(time) + (g_led_config.point[i].x) - 128) * 2, huedelta); - return hsv; -} - -bool HUE_PENDULUM(effect_params_t* params) { - return effect_runner_i(params, &HUE_PENDULUM_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // DISABLE_RGB_HUE_PENDULUM diff --git a/quantum/rgb_matrix/animations/hue_wave_anim.h b/quantum/rgb_matrix/animations/hue_wave_anim.h deleted file mode 100644 index 81aa7e139e9a..000000000000 --- a/quantum/rgb_matrix/animations/hue_wave_anim.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_HUE_WAVE -RGB_MATRIX_EFFECT(HUE_WAVE) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -// Change huedelta to adjust range of hue change. 0-255. -// Looks better with a low value and slow speed for subtle change. -// Hue Wave - color changes in a wave to the right -static HSV HUE_WAVE_math(HSV hsv, uint8_t i, uint8_t time) { - uint8_t huedelta = 24; - hsv.h = hsv.h + scale8(abs8(g_led_config.point[i].x - time), huedelta); - return hsv; -} - -bool HUE_WAVE(effect_params_t* params) { - return effect_runner_i(params, &HUE_WAVE_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // DISABLE_RGB_HUE_WAVE diff --git a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h b/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h deleted file mode 100644 index 6bde60053bf5..000000000000 --- a/quantum/rgb_matrix/animations/jellybean_raindrops_anim.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS -RGB_MATRIX_EFFECT(JELLYBEAN_RAINDROPS) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static void jellybean_raindrops_set_color(int i, effect_params_t* params) { - if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return; - HSV hsv = {random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v}; - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); -} - -bool JELLYBEAN_RAINDROPS(effect_params_t* params) { - if (!params->init) { - // Change one LED every tick, make sure speed is not 0 - if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 5 == 0) { - jellybean_raindrops_set_color(random8_max(RGB_MATRIX_LED_COUNT), params); - } - return false; - } - - RGB_MATRIX_USE_LIMITS(led_min, led_max); - for (int i = led_min; i < led_max; i++) { - jellybean_raindrops_set_color(i, params); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_JELLYBEAN_RAINDROPS diff --git a/quantum/rgb_matrix/animations/pixel_flow_anim.h b/quantum/rgb_matrix/animations/pixel_flow_anim.h deleted file mode 100644 index 27567b4f3a53..000000000000 --- a/quantum/rgb_matrix/animations/pixel_flow_anim.h +++ /dev/null @@ -1,51 +0,0 @@ -// Copyright 2022 @filterpaper -// SPDX-License-Identifier: GPL-2.0+ - -#ifdef ENABLE_RGB_MATRIX_PIXEL_FLOW -RGB_MATRIX_EFFECT(PIXEL_FLOW) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static bool PIXEL_FLOW(effect_params_t* params) { - // LED state array - static RGB led[RGB_MATRIX_LED_COUNT]; - - static uint32_t wait_timer = 0; - if (wait_timer > g_rgb_timer) { - return false; - } - - inline uint32_t interval(void) { - return 3000 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); - } - - if (params->init) { - // Clear LEDs and fill the state array - rgb_matrix_set_color_all(0, 0, 0); - for (uint8_t j = 0; j < RGB_MATRIX_LED_COUNT; ++j) { - led[j] = (random8() & 2) ? (RGB){0, 0, 0} : hsv_to_rgb((HSV){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v}); - } - } - - RGB_MATRIX_USE_LIMITS(led_min, led_max); - // Light LEDs based on state array - for (uint8_t i = led_min; i < led_max; ++i) { - RGB_MATRIX_TEST_LED_FLAGS(); - rgb_matrix_set_color(i, led[i].r, led[i].g, led[i].b); - } - - if (!rgb_matrix_check_finished_leds(led_max)) { - // Shift LED state forward - for (uint8_t j = 0; j < led_max - 1; ++j) { - led[j] = led[j + 1]; - } - // Fill last LED - led[led_max - 1] = (random8() & 2) ? (RGB){0, 0, 0} : hsv_to_rgb((HSV){random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v}); - // Set pulse timer - wait_timer = g_rgb_timer + interval(); - } - - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_PIXEL_FLOW diff --git a/quantum/rgb_matrix/animations/pixel_fractal_anim.h b/quantum/rgb_matrix/animations/pixel_fractal_anim.h deleted file mode 100644 index 875b4ceb3dc0..000000000000 --- a/quantum/rgb_matrix/animations/pixel_fractal_anim.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (C) 2022 @filterpaper -// SPDX-License-Identifier: GPL-2.0-or-later -// Inspired by 4x12 fractal from @GEIGEIGEIST - -#ifdef ENABLE_RGB_MATRIX_PIXEL_FRACTAL -RGB_MATRIX_EFFECT(PIXEL_FRACTAL) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static bool PIXEL_FRACTAL(effect_params_t* params) { -# define MID_COL MATRIX_COLS / 2 - static bool led[MATRIX_ROWS][MID_COL]; - static uint32_t wait_timer = 0; - - inline uint32_t interval(void) { - return 3000 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); - } - - if (params->init) { - rgb_matrix_set_color_all(0, 0, 0); - } - - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - if (g_rgb_timer > wait_timer) { - RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv); - for (uint8_t h = 0; h < MATRIX_ROWS; ++h) { - // Light and copy columns outward - for (uint8_t l = 0; l < MID_COL - 1; ++l) { - if (led[h][l]) { - rgb_matrix_set_color(g_led_config.matrix_co[h][l], rgb.r, rgb.g, rgb.b); - rgb_matrix_set_color(g_led_config.matrix_co[h][MATRIX_COLS - 1 - l], rgb.r, rgb.g, rgb.b); - } else { - rgb_matrix_set_color(g_led_config.matrix_co[h][l], 0, 0, 0); - rgb_matrix_set_color(g_led_config.matrix_co[h][MATRIX_COLS - 1 - l], 0, 0, 0); - } - led[h][l] = led[h][l + 1]; - } - - // Light both middle columns - if (led[h][MID_COL - 1]) { - rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], rgb.r, rgb.g, rgb.b); - rgb_matrix_set_color(g_led_config.matrix_co[h][MATRIX_COLS - MID_COL], rgb.r, rgb.g, rgb.b); - } else { - rgb_matrix_set_color(g_led_config.matrix_co[h][MID_COL - 1], 0, 0, 0); - rgb_matrix_set_color(g_led_config.matrix_co[h][MATRIX_COLS - MID_COL], 0, 0, 0); - } - - // Generate new random fractal column - led[h][MID_COL - 1] = (random8() & 3) ? false : true; - } - - wait_timer = g_rgb_timer + interval(); - } - - return rgb_matrix_check_finished_leds(led_max); -} -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_PIXEL_FRACTAL diff --git a/quantum/rgb_matrix/animations/pixel_rain_anim.h b/quantum/rgb_matrix/animations/pixel_rain_anim.h deleted file mode 100644 index 9d63f451e278..000000000000 --- a/quantum/rgb_matrix/animations/pixel_rain_anim.h +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright 2022 @filterpaper -// SPDX-License-Identifier: GPL-2.0+ - -#ifdef ENABLE_RGB_MATRIX_PIXEL_RAIN -RGB_MATRIX_EFFECT(PIXEL_RAIN) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static bool PIXEL_RAIN(effect_params_t* params) { - static uint32_t wait_timer = 0; - - inline uint32_t interval(void) { - return 500 / scale16by8(qadd8(rgb_matrix_config.speed, 16), 16); - } - - inline void rain_pixel(uint8_t led_index) { - if (!HAS_ANY_FLAGS(g_led_config.flags[led_index], params->flags)) { - return; - } - if (random8() & 2) { - rgb_matrix_set_color(led_index, 0, 0, 0); - } else { - HSV hsv = {random8(), random8_min_max(127, 255), rgb_matrix_config.hsv.v}; - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(led_index, rgb.r, rgb.g, rgb.b); - } - wait_timer = g_rgb_timer + interval(); - } - - RGB_MATRIX_USE_LIMITS(led_min, led_max); - if (g_rgb_timer > wait_timer) { - rain_pixel(random8_max(RGB_MATRIX_LED_COUNT)); - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_PIXEL_RAIN diff --git a/quantum/rgb_matrix/animations/rainbow_beacon_anim.h b/quantum/rgb_matrix/animations/rainbow_beacon_anim.h deleted file mode 100644 index bdcca5530fd4..000000000000 --- a/quantum/rgb_matrix/animations/rainbow_beacon_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_RAINBOW_BEACON -RGB_MATRIX_EFFECT(RAINBOW_BEACON) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV RAINBOW_BEACON_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { - hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 2 * cos + (g_led_config.point[i].x - k_rgb_matrix_center.x) * 2 * sin) / 128; - return hsv; -} - -bool RAINBOW_BEACON(effect_params_t* params) { - return effect_runner_sin_cos_i(params, &RAINBOW_BEACON_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_RAINBOW_BEACON diff --git a/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h b/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h deleted file mode 100644 index f7b8f6c2f324..000000000000 --- a/quantum/rgb_matrix/animations/rainbow_moving_chevron_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON -RGB_MATRIX_EFFECT(RAINBOW_MOVING_CHEVRON) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV RAINBOW_MOVING_CHEVRON_math(HSV hsv, uint8_t i, uint8_t time) { - hsv.h += abs8(g_led_config.point[i].y - k_rgb_matrix_center.y) + (g_led_config.point[i].x - time); - return hsv; -} - -bool RAINBOW_MOVING_CHEVRON(effect_params_t* params) { - return effect_runner_i(params, &RAINBOW_MOVING_CHEVRON_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_RAINBOW_MOVING_CHEVRON diff --git a/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h b/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h deleted file mode 100644 index 91e31ea8cc0f..000000000000 --- a/quantum/rgb_matrix/animations/rainbow_pinwheels_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS -RGB_MATRIX_EFFECT(RAINBOW_PINWHEELS) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV RAINBOW_PINWHEELS_math(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time) { - hsv.h += ((g_led_config.point[i].y - k_rgb_matrix_center.y) * 3 * cos + (56 - abs8(g_led_config.point[i].x - k_rgb_matrix_center.x)) * 3 * sin) / 128; - return hsv; -} - -bool RAINBOW_PINWHEELS(effect_params_t* params) { - return effect_runner_sin_cos_i(params, &RAINBOW_PINWHEELS_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_RAINBOW_PINWHEELS diff --git a/quantum/rgb_matrix/animations/raindrops_anim.h b/quantum/rgb_matrix/animations/raindrops_anim.h deleted file mode 100644 index e8e1f6de0439..000000000000 --- a/quantum/rgb_matrix/animations/raindrops_anim.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef ENABLE_RGB_MATRIX_RAINDROPS -RGB_MATRIX_EFFECT(RAINDROPS) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static void raindrops_set_color(int i, effect_params_t* params) { - if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) return; - HSV hsv = {0, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v}; - - // Take the shortest path between hues - int16_t deltaH = ((rgb_matrix_config.hsv.h + 180) % 360 - rgb_matrix_config.hsv.h) / 4; - if (deltaH > 127) { - deltaH -= 256; - } else if (deltaH < -127) { - deltaH += 256; - } - - hsv.h = rgb_matrix_config.hsv.h + (deltaH * (random8() & 0x03)); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); -} - -bool RAINDROPS(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - if (!params->init) { - // Change one LED every tick, make sure speed is not 0 - if (scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 16)) % 10 == 0) { - raindrops_set_color(random8_max(RGB_MATRIX_LED_COUNT), params); - } - } else { - for (int i = led_min; i < led_max; i++) { - raindrops_set_color(i, params); - } - } - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // ENABLE_RGB_MATRIX_RAINDROPS diff --git a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc b/quantum/rgb_matrix/animations/rgb_matrix_effects.inc deleted file mode 100644 index ac7bac428d1e..000000000000 --- a/quantum/rgb_matrix/animations/rgb_matrix_effects.inc +++ /dev/null @@ -1,40 +0,0 @@ -// Add your new core rgb matrix effect here, order determines enum order -#include "solid_color_anim.h" -#include "alpha_mods_anim.h" -#include "gradient_up_down_anim.h" -#include "gradient_left_right_anim.h" -#include "breathing_anim.h" -#include "colorband_sat_anim.h" -#include "colorband_val_anim.h" -#include "colorband_pinwheel_sat_anim.h" -#include "colorband_pinwheel_val_anim.h" -#include "colorband_spiral_sat_anim.h" -#include "colorband_spiral_val_anim.h" -#include "cycle_all_anim.h" -#include "cycle_left_right_anim.h" -#include "cycle_up_down_anim.h" -#include "rainbow_moving_chevron_anim.h" -#include "cycle_out_in_anim.h" -#include "cycle_out_in_dual_anim.h" -#include "cycle_pinwheel_anim.h" -#include "cycle_spiral_anim.h" -#include "dual_beacon_anim.h" -#include "rainbow_beacon_anim.h" -#include "rainbow_pinwheels_anim.h" -#include "raindrops_anim.h" -#include "jellybean_raindrops_anim.h" -#include "hue_breathing_anim.h" -#include "hue_pendulum_anim.h" -#include "hue_wave_anim.h" -#include "pixel_rain_anim.h" -#include "pixel_flow_anim.h" -#include "pixel_fractal_anim.h" -#include "typing_heatmap_anim.h" -#include "digital_rain_anim.h" -#include "solid_reactive_simple_anim.h" -#include "solid_reactive_anim.h" -#include "solid_reactive_wide.h" -#include "solid_reactive_cross.h" -#include "solid_reactive_nexus.h" -#include "splash_anim.h" -#include "solid_splash_anim.h" diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h deleted file mode 100644 index 2ad0f22c287d..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -typedef HSV (*dx_dy_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t time); - -bool effect_runner_dx_dy(effect_params_t* params, dx_dy_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x; - int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y; - RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, time)); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h b/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h deleted file mode 100644 index bcae7c79b6b8..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_dx_dy_dist.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -typedef HSV (*dx_dy_dist_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint8_t time); - -bool effect_runner_dx_dy_dist(effect_params_t* params, dx_dy_dist_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 2); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - int16_t dx = g_led_config.point[i].x - k_rgb_matrix_center.x; - int16_t dy = g_led_config.point[i].y - k_rgb_matrix_center.y; - uint8_t dist = sqrt16(dx * dx + dy * dy); - RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, dx, dy, dist, time)); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_i.h deleted file mode 100644 index b4de2992b64a..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_i.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -typedef HSV (*i_f)(HSV hsv, uint8_t i, uint8_t time); - -bool effect_runner_i(effect_params_t* params, i_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t time = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed / 4, 1)); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, i, time)); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h deleted file mode 100644 index f9584d707191..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - -typedef HSV (*reactive_f)(HSV hsv, uint16_t offset); - -bool effect_runner_reactive(effect_params_t* params, reactive_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint16_t max_tick = 65535 / qadd8(rgb_matrix_config.speed, 1); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - uint16_t tick = max_tick; - // Reverse search to find most recent key hit - for (int8_t j = g_last_hit_tracker.count - 1; j >= 0; j--) { - if (g_last_hit_tracker.index[j] == i && g_last_hit_tracker.tick[j] < tick) { - tick = g_last_hit_tracker.tick[j]; - break; - } - } - - uint16_t offset = scale16by8(tick, qadd8(rgb_matrix_config.speed, 1)); - RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, offset)); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h b/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h deleted file mode 100644 index 41020eb47f82..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_reactive_splash.h +++ /dev/null @@ -1,29 +0,0 @@ -#pragma once - -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - -typedef HSV (*reactive_splash_f)(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick); - -bool effect_runner_reactive_splash(uint8_t start, effect_params_t* params, reactive_splash_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint8_t count = g_last_hit_tracker.count; - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - HSV hsv = rgb_matrix_config.hsv; - hsv.v = 0; - for (uint8_t j = start; j < count; j++) { - int16_t dx = g_led_config.point[i].x - g_last_hit_tracker.x[j]; - int16_t dy = g_led_config.point[i].y - g_last_hit_tracker.y[j]; - uint8_t dist = sqrt16(dx * dx + dy * dy); - uint16_t tick = scale16by8(g_last_hit_tracker.tick[j], qadd8(rgb_matrix_config.speed, 1)); - hsv = effect_func(hsv, dx, dy, dist, tick); - } - hsv.v = scale8(hsv.v, rgb_matrix_config.hsv.v); - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h b/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h deleted file mode 100644 index 7776491d5125..000000000000 --- a/quantum/rgb_matrix/animations/runners/effect_runner_sin_cos_i.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -typedef HSV (*sin_cos_i_f)(HSV hsv, int8_t sin, int8_t cos, uint8_t i, uint8_t time); - -bool effect_runner_sin_cos_i(effect_params_t* params, sin_cos_i_f effect_func) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - uint16_t time = scale16by8(g_rgb_timer, rgb_matrix_config.speed / 4); - int8_t cos_value = cos8(time) - 128; - int8_t sin_value = sin8(time) - 128; - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - RGB rgb = rgb_matrix_hsv_to_rgb(effect_func(rgb_matrix_config.hsv, cos_value, sin_value, i, time)); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} diff --git a/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc b/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc deleted file mode 100644 index c09022bb0fad..000000000000 --- a/quantum/rgb_matrix/animations/runners/rgb_matrix_runners.inc +++ /dev/null @@ -1,6 +0,0 @@ -#include "effect_runner_dx_dy_dist.h" -#include "effect_runner_dx_dy.h" -#include "effect_runner_i.h" -#include "effect_runner_sin_cos_i.h" -#include "effect_runner_reactive.h" -#include "effect_runner_reactive_splash.h" diff --git a/quantum/rgb_matrix/animations/solid_color_anim.h b/quantum/rgb_matrix/animations/solid_color_anim.h deleted file mode 100644 index c8762dcbc2ef..000000000000 --- a/quantum/rgb_matrix/animations/solid_color_anim.h +++ /dev/null @@ -1,15 +0,0 @@ -RGB_MATRIX_EFFECT(SOLID_COLOR) -#ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -bool SOLID_COLOR(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - RGB rgb = rgb_matrix_hsv_to_rgb(rgb_matrix_config.hsv); - for (uint8_t i = led_min; i < led_max; i++) { - RGB_MATRIX_TEST_LED_FLAGS(); - rgb_matrix_set_color(i, rgb.r, rgb.g, rgb.b); - } - return rgb_matrix_check_finished_leds(led_max); -} - -#endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS diff --git a/quantum/rgb_matrix/animations/solid_reactive_anim.h b/quantum/rgb_matrix/animations/solid_reactive_anim.h deleted file mode 100644 index edf604135031..000000000000 --- a/quantum/rgb_matrix/animations/solid_reactive_anim.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE -RGB_MATRIX_EFFECT(SOLID_REACTIVE) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV SOLID_REACTIVE_math(HSV hsv, uint16_t offset) { -# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE - hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4); -# endif - hsv.h += qsub8(130, offset); - return hsv; -} - -bool SOLID_REACTIVE(effect_params_t* params) { - return effect_runner_reactive(params, &SOLID_REACTIVE_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // ENABLE_RGB_MATRIX_SOLID_REACTIVE -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/solid_reactive_cross.h b/quantum/rgb_matrix/animations/solid_reactive_cross.h deleted file mode 100644 index a18d6b03dd6b..000000000000 --- a/quantum/rgb_matrix/animations/solid_reactive_cross.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS) - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS -RGB_MATRIX_EFFECT(SOLID_REACTIVE_CROSS) -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS -RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTICROSS) -# endif - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV SOLID_REACTIVE_CROSS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick + dist; - dx = dx < 0 ? dx * -1 : dx; - dy = dy < 0 ? dy * -1 : dy; - dx = dx * 16 > 255 ? 255 : dx * 16; - dy = dy * 16 > 255 ? 255 : dy * 16; - effect += dx > dy ? dy : dx; - if (effect > 255) effect = 255; -# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE - hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4); -# endif - hsv.v = qadd8(hsv.v, 255 - effect); - return hsv; -} - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS -bool SOLID_REACTIVE_CROSS(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_CROSS_math); -} -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS -bool SOLID_REACTIVE_MULTICROSS(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_CROSS_math); -} -# endif - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // !defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_CROSS) || defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTICROSS) -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/solid_reactive_nexus.h b/quantum/rgb_matrix/animations/solid_reactive_nexus.h deleted file mode 100644 index 53cc008616de..000000000000 --- a/quantum/rgb_matrix/animations/solid_reactive_nexus.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS) - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS -RGB_MATRIX_EFFECT(SOLID_REACTIVE_NEXUS) -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS -RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTINEXUS) -# endif - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV SOLID_REACTIVE_NEXUS_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick - dist; - if (effect > 255) effect = 255; - if (dist > 72) effect = 255; - if ((dx > 8 || dx < -8) && (dy > 8 || dy < -8)) effect = 255; -# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE - hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4) + dy / 4; -# else - hsv.h = rgb_matrix_config.hsv.h + dy / 4; -# endif - hsv.v = qadd8(hsv.v, 255 - effect); - return hsv; -} - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS -bool SOLID_REACTIVE_NEXUS(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_NEXUS_math); -} -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS -bool SOLID_REACTIVE_MULTINEXUS(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_NEXUS_math); -} -# endif - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // !defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_NEXUS) || !defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTINEXUS) -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h b/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h deleted file mode 100644 index 7f4e48747a6c..000000000000 --- a/quantum/rgb_matrix/animations/solid_reactive_simple_anim.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE -RGB_MATRIX_EFFECT(SOLID_REACTIVE_SIMPLE) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV SOLID_REACTIVE_SIMPLE_math(HSV hsv, uint16_t offset) { -# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE - hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4); -# endif - hsv.v = scale8(255 - offset, hsv.v); - return hsv; -} - -bool SOLID_REACTIVE_SIMPLE(effect_params_t* params) { - return effect_runner_reactive(params, &SOLID_REACTIVE_SIMPLE_math); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // ENABLE_RGB_MATRIX_SOLID_REACTIVE_SIMPLE -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/solid_reactive_wide.h b/quantum/rgb_matrix/animations/solid_reactive_wide.h deleted file mode 100644 index feca1266483d..000000000000 --- a/quantum/rgb_matrix/animations/solid_reactive_wide.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE) - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE -RGB_MATRIX_EFFECT(SOLID_REACTIVE_WIDE) -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE -RGB_MATRIX_EFFECT(SOLID_REACTIVE_MULTIWIDE) -# endif - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -static HSV SOLID_REACTIVE_WIDE_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick + dist * 5; - if (effect > 255) effect = 255; -# ifdef RGB_MATRIX_SOLID_REACTIVE_GRADIENT_MODE - hsv.h = scale16by8(g_rgb_timer, qadd8(rgb_matrix_config.speed, 8) >> 4); -# endif - hsv.v = qadd8(hsv.v, 255 - effect); - return hsv; -} - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE -bool SOLID_REACTIVE_WIDE(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_REACTIVE_WIDE_math); -} -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE -bool SOLID_REACTIVE_MULTIWIDE(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_REACTIVE_WIDE_math); -} -# endif - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // !defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_WIDE) || !defined(ENABLE_RGB_MATRIX_SOLID_REACTIVE_MULTIWIDE) -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/solid_splash_anim.h b/quantum/rgb_matrix/animations/solid_splash_anim.h deleted file mode 100644 index 77d6f8c5eb0c..000000000000 --- a/quantum/rgb_matrix/animations/solid_splash_anim.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_RGB_MATRIX_SOLID_SPLASH) || defined(ENABLE_RGB_MATRIX_SOLID_MULTISPLASH) - -# ifdef ENABLE_RGB_MATRIX_SOLID_SPLASH -RGB_MATRIX_EFFECT(SOLID_SPLASH) -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH -RGB_MATRIX_EFFECT(SOLID_MULTISPLASH) -# endif - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -HSV SOLID_SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick - dist; - if (effect > 255) effect = 255; - hsv.v = qadd8(hsv.v, 255 - effect); - return hsv; -} - -# ifdef ENABLE_RGB_MATRIX_SOLID_SPLASH -bool SOLID_SPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SOLID_SPLASH_math); -} -# endif - -# ifdef ENABLE_RGB_MATRIX_SOLID_MULTISPLASH -bool SOLID_MULTISPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SOLID_SPLASH_math); -} -# endif - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // !defined(ENABLE_RGB_MATRIX_SPLASH) && !defined(ENABLE_RGB_MATRIX_MULTISPLASH) -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/splash_anim.h b/quantum/rgb_matrix/animations/splash_anim.h deleted file mode 100644 index 06459e1b0a2e..000000000000 --- a/quantum/rgb_matrix/animations/splash_anim.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -# if defined(ENABLE_RGB_MATRIX_SPLASH) || defined(ENABLE_RGB_MATRIX_MULTISPLASH) - -# ifdef ENABLE_RGB_MATRIX_SPLASH -RGB_MATRIX_EFFECT(SPLASH) -# endif - -# ifdef ENABLE_RGB_MATRIX_MULTISPLASH -RGB_MATRIX_EFFECT(MULTISPLASH) -# endif - -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -HSV SPLASH_math(HSV hsv, int16_t dx, int16_t dy, uint8_t dist, uint16_t tick) { - uint16_t effect = tick - dist; - if (effect > 255) effect = 255; - hsv.h += effect; - hsv.v = qadd8(hsv.v, 255 - effect); - return hsv; -} - -# ifdef ENABLE_RGB_MATRIX_SPLASH -bool SPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(qsub8(g_last_hit_tracker.count, 1), params, &SPLASH_math); -} -# endif - -# ifdef ENABLE_RGB_MATRIX_MULTISPLASH -bool MULTISPLASH(effect_params_t* params) { - return effect_runner_reactive_splash(0, params, &SPLASH_math); -} -# endif - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# endif // !defined(ENABLE_RGB_MATRIX_SPLASH) || !defined(ENABLE_RGB_MATRIX_MULTISPLASH) -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED diff --git a/quantum/rgb_matrix/animations/typing_heatmap_anim.h b/quantum/rgb_matrix/animations/typing_heatmap_anim.h deleted file mode 100644 index d09bdc463171..000000000000 --- a/quantum/rgb_matrix/animations/typing_heatmap_anim.h +++ /dev/null @@ -1,100 +0,0 @@ -#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP) -RGB_MATRIX_EFFECT(TYPING_HEATMAP) -# ifdef RGB_MATRIX_CUSTOM_EFFECT_IMPLS -# ifndef RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP -# define RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP 32 -# endif - -# ifndef RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS -# define RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS 25 -# endif - -# ifndef RGB_MATRIX_TYPING_HEATMAP_SPREAD -# define RGB_MATRIX_TYPING_HEATMAP_SPREAD 40 -# endif - -# ifndef RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT -# define RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT 16 -# endif -void process_rgb_matrix_typing_heatmap(uint8_t row, uint8_t col) { -# ifdef RGB_MATRIX_TYPING_HEATMAP_SLIM - // Limit effect to pressed keys - g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP); -# else - if (g_led_config.matrix_co[row][col] == NO_LED) { // skip as pressed key doesn't have an led position - return; - } - for (uint8_t i_row = 0; i_row < MATRIX_ROWS; i_row++) { - for (uint8_t i_col = 0; i_col < MATRIX_COLS; i_col++) { - if (g_led_config.matrix_co[i_row][i_col] == NO_LED) { // skip as target key doesn't have an led position - continue; - } - if (i_row == row && i_col == col) { - g_rgb_frame_buffer[row][col] = qadd8(g_rgb_frame_buffer[row][col], RGB_MATRIX_TYPING_HEATMAP_INCREASE_STEP); - } else { -# define LED_DISTANCE(led_a, led_b) sqrt16(((int16_t)(led_a.x - led_b.x) * (int16_t)(led_a.x - led_b.x)) + ((int16_t)(led_a.y - led_b.y) * (int16_t)(led_a.y - led_b.y))) - uint8_t distance = LED_DISTANCE(g_led_config.point[g_led_config.matrix_co[row][col]], g_led_config.point[g_led_config.matrix_co[i_row][i_col]]); -# undef LED_DISTANCE - if (distance <= RGB_MATRIX_TYPING_HEATMAP_SPREAD) { - uint8_t amount = qsub8(RGB_MATRIX_TYPING_HEATMAP_SPREAD, distance); - if (amount > RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT) { - amount = RGB_MATRIX_TYPING_HEATMAP_AREA_LIMIT; - } - g_rgb_frame_buffer[i_row][i_col] = qadd8(g_rgb_frame_buffer[i_row][i_col], amount); - } - } - } - } -# endif -} - -// A timer to track the last time we decremented all heatmap values. -static uint16_t heatmap_decrease_timer; -// Whether we should decrement the heatmap values during the next update. -static bool decrease_heatmap_values; - -bool TYPING_HEATMAP(effect_params_t* params) { - RGB_MATRIX_USE_LIMITS(led_min, led_max); - - if (params->init) { - rgb_matrix_set_color_all(0, 0, 0); - memset(g_rgb_frame_buffer, 0, sizeof g_rgb_frame_buffer); - } - - // The heatmap animation might run in several iterations depending on - // `RGB_MATRIX_LED_PROCESS_LIMIT`, therefore we only want to update the - // timer when the animation starts. - if (params->iter == 0) { - decrease_heatmap_values = timer_elapsed(heatmap_decrease_timer) >= RGB_MATRIX_TYPING_HEATMAP_DECREASE_DELAY_MS; - - // Restart the timer if we are going to decrease the heatmap this frame. - if (decrease_heatmap_values) { - heatmap_decrease_timer = timer_read(); - } - } - - // Render heatmap & decrease - uint8_t count = 0; - for (uint8_t row = 0; row < MATRIX_ROWS && count < RGB_MATRIX_LED_PROCESS_LIMIT; row++) { - for (uint8_t col = 0; col < MATRIX_COLS && RGB_MATRIX_LED_PROCESS_LIMIT; col++) { - if (g_led_config.matrix_co[row][col] >= led_min && g_led_config.matrix_co[row][col] < led_max) { - count++; - uint8_t val = g_rgb_frame_buffer[row][col]; - if (!HAS_ANY_FLAGS(g_led_config.flags[g_led_config.matrix_co[row][col]], params->flags)) continue; - - HSV hsv = {170 - qsub8(val, 85), rgb_matrix_config.hsv.s, scale8((qadd8(170, val) - 170) * 3, rgb_matrix_config.hsv.v)}; - RGB rgb = rgb_matrix_hsv_to_rgb(hsv); - rgb_matrix_set_color(g_led_config.matrix_co[row][col], rgb.r, rgb.g, rgb.b); - - if (decrease_heatmap_values) { - g_rgb_frame_buffer[row][col] = qsub8(val, 1); - } - } - } - } - - return rgb_matrix_check_finished_leds(led_max); -} - -# endif // RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP) diff --git a/quantum/rgb_matrix/rgb_matrix.c b/quantum/rgb_matrix/rgb_matrix.c deleted file mode 100644 index 1f3912cf7e0c..000000000000 --- a/quantum/rgb_matrix/rgb_matrix.c +++ /dev/null @@ -1,744 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2017 Jack Humbert - * Copyright 2018 Yiancar - * - * 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 . - */ - -#include "rgb_matrix.h" -#include "progmem.h" -#include "eeprom.h" -#include -#include - -#include - -#ifndef RGB_MATRIX_CENTER -const led_point_t k_rgb_matrix_center = {112, 32}; -#else -const led_point_t k_rgb_matrix_center = RGB_MATRIX_CENTER; -#endif - -__attribute__((weak)) RGB rgb_matrix_hsv_to_rgb(HSV hsv) { - return hsv_to_rgb(hsv); -} - -// Generic effect runners -#include "rgb_matrix_runners.inc" - -// ------------------------------------------ -// -----Begin rgb effect includes macros----- -#define RGB_MATRIX_EFFECT(name) -#define RGB_MATRIX_CUSTOM_EFFECT_IMPLS - -#include "rgb_matrix_effects.inc" -#ifdef RGB_MATRIX_CUSTOM_KB -# include "rgb_matrix_kb.inc" -#endif -#ifdef RGB_MATRIX_CUSTOM_USER -# include "rgb_matrix_user.inc" -#endif - -#undef RGB_MATRIX_CUSTOM_EFFECT_IMPLS -#undef RGB_MATRIX_EFFECT -// -----End rgb effect includes macros------- -// ------------------------------------------ - -#ifndef RGB_MATRIX_TIMEOUT -# define RGB_MATRIX_TIMEOUT 0 -#endif - -#if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX -# undef RGB_MATRIX_MAXIMUM_BRIGHTNESS -# define RGB_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX -#endif - -#if !defined(RGB_MATRIX_HUE_STEP) -# define RGB_MATRIX_HUE_STEP 8 -#endif - -#if !defined(RGB_MATRIX_SAT_STEP) -# define RGB_MATRIX_SAT_STEP 16 -#endif - -#if !defined(RGB_MATRIX_VAL_STEP) -# define RGB_MATRIX_VAL_STEP 16 -#endif - -#if !defined(RGB_MATRIX_SPD_STEP) -# define RGB_MATRIX_SPD_STEP 16 -#endif - -#if !defined(RGB_MATRIX_DEFAULT_MODE) -# ifdef ENABLE_RGB_MATRIX_CYCLE_LEFT_RIGHT -# define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_CYCLE_LEFT_RIGHT -# else -// fallback to solid colors if RGB_MATRIX_CYCLE_LEFT_RIGHT is disabled in userspace -# define RGB_MATRIX_DEFAULT_MODE RGB_MATRIX_SOLID_COLOR -# endif -#endif - -#if !defined(RGB_MATRIX_DEFAULT_HUE) -# define RGB_MATRIX_DEFAULT_HUE 0 -#endif - -#if !defined(RGB_MATRIX_DEFAULT_SAT) -# define RGB_MATRIX_DEFAULT_SAT UINT8_MAX -#endif - -#if !defined(RGB_MATRIX_DEFAULT_VAL) -# define RGB_MATRIX_DEFAULT_VAL RGB_MATRIX_MAXIMUM_BRIGHTNESS -#endif - -#if !defined(RGB_MATRIX_DEFAULT_SPD) -# define RGB_MATRIX_DEFAULT_SPD UINT8_MAX / 2 -#endif - -// globals -rgb_config_t rgb_matrix_config; // TODO: would like to prefix this with g_ for global consistancy, do this in another pr -uint32_t g_rgb_timer; -#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS -uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS] = {{0}}; -#endif // RGB_MATRIX_FRAMEBUFFER_EFFECTS -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -last_hit_t g_last_hit_tracker; -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - -// internals -static bool suspend_state = false; -static uint8_t rgb_last_enable = UINT8_MAX; -static uint8_t rgb_last_effect = UINT8_MAX; -static effect_params_t rgb_effect_params = {0, LED_FLAG_ALL, false}; -static rgb_task_states rgb_task_state = SYNCING; -#if RGB_MATRIX_TIMEOUT > 0 -static uint32_t rgb_anykey_timer; -#endif // RGB_MATRIX_TIMEOUT > 0 - -// double buffers -static uint32_t rgb_timer_buffer; -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -static last_hit_t last_hit_buffer; -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - -// split rgb matrix -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) -const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; -#endif - -EECONFIG_DEBOUNCE_HELPER(rgb_matrix, EECONFIG_RGB_MATRIX, rgb_matrix_config); - -void eeconfig_update_rgb_matrix(void) { - eeconfig_flush_rgb_matrix(true); -} - -void eeconfig_update_rgb_matrix_default(void) { - dprintf("eeconfig_update_rgb_matrix_default\n"); - rgb_matrix_config.enable = 1; - rgb_matrix_config.mode = RGB_MATRIX_DEFAULT_MODE; - rgb_matrix_config.hsv = (HSV){RGB_MATRIX_DEFAULT_HUE, RGB_MATRIX_DEFAULT_SAT, RGB_MATRIX_DEFAULT_VAL}; - rgb_matrix_config.speed = RGB_MATRIX_DEFAULT_SPD; - rgb_matrix_config.flags = LED_FLAG_ALL; - eeconfig_flush_rgb_matrix(true); -} - -void eeconfig_debug_rgb_matrix(void) { - dprintf("rgb_matrix_config EEPROM\n"); - dprintf("rgb_matrix_config.enable = %d\n", rgb_matrix_config.enable); - dprintf("rgb_matrix_config.mode = %d\n", rgb_matrix_config.mode); - dprintf("rgb_matrix_config.hsv.h = %d\n", rgb_matrix_config.hsv.h); - dprintf("rgb_matrix_config.hsv.s = %d\n", rgb_matrix_config.hsv.s); - dprintf("rgb_matrix_config.hsv.v = %d\n", rgb_matrix_config.hsv.v); - dprintf("rgb_matrix_config.speed = %d\n", rgb_matrix_config.speed); - dprintf("rgb_matrix_config.flags = %d\n", rgb_matrix_config.flags); -} - -void rgb_matrix_reload_from_eeprom(void) { - rgb_matrix_disable_noeeprom(); - /* Reset back to what we have in eeprom */ - eeconfig_init_rgb_matrix(); - eeconfig_debug_rgb_matrix(); // display current eeprom values - if (rgb_matrix_config.enable) { - rgb_matrix_mode_noeeprom(rgb_matrix_config.mode); - } -} - -__attribute__((weak)) uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i) { - return 0; -} - -uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i) { - uint8_t led_count = rgb_matrix_map_row_column_to_led_kb(row, column, led_i); - uint8_t led_index = g_led_config.matrix_co[row][column]; - if (led_index != NO_LED) { - led_i[led_count] = led_index; - led_count++; - } - return led_count; -} - -void rgb_matrix_update_pwm_buffers(void) { - rgb_matrix_driver.flush(); -} - -void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue) { - rgb_matrix_driver.set_color(index, red, green, blue); -} - -void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue) { -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - for (uint8_t i = 0; i < RGB_MATRIX_LED_COUNT; i++) - rgb_matrix_set_color(i, red, green, blue); -#else - rgb_matrix_driver.set_color_all(red, green, blue); -#endif -} - -void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed) { -#ifndef RGB_MATRIX_SPLIT - if (!is_keyboard_master()) return; -#endif -#if RGB_MATRIX_TIMEOUT > 0 - rgb_anykey_timer = 0; -#endif // RGB_MATRIX_TIMEOUT > 0 - -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - uint8_t led[LED_HITS_TO_REMEMBER]; - uint8_t led_count = 0; - -# if defined(RGB_MATRIX_KEYRELEASES) - if (!pressed) -# elif defined(RGB_MATRIX_KEYPRESSES) - if (pressed) -# endif // defined(RGB_MATRIX_KEYRELEASES) - { - led_count = rgb_matrix_map_row_column_to_led(row, col, led); - } - - if (last_hit_buffer.count + led_count > LED_HITS_TO_REMEMBER) { - memcpy(&last_hit_buffer.x[0], &last_hit_buffer.x[led_count], LED_HITS_TO_REMEMBER - led_count); - memcpy(&last_hit_buffer.y[0], &last_hit_buffer.y[led_count], LED_HITS_TO_REMEMBER - led_count); - memcpy(&last_hit_buffer.tick[0], &last_hit_buffer.tick[led_count], (LED_HITS_TO_REMEMBER - led_count) * 2); // 16 bit - memcpy(&last_hit_buffer.index[0], &last_hit_buffer.index[led_count], LED_HITS_TO_REMEMBER - led_count); - last_hit_buffer.count = LED_HITS_TO_REMEMBER - led_count; - } - - for (uint8_t i = 0; i < led_count; i++) { - uint8_t index = last_hit_buffer.count; - last_hit_buffer.x[index] = g_led_config.point[led[i]].x; - last_hit_buffer.y[index] = g_led_config.point[led[i]].y; - last_hit_buffer.index[index] = led[i]; - last_hit_buffer.tick[index] = 0; - last_hit_buffer.count++; - } -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - -#if defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP) -# if defined(RGB_MATRIX_KEYRELEASES) - if (!pressed) -# else - if (pressed) -# endif // defined(RGB_MATRIX_KEYRELEASES) - { - if (rgb_matrix_config.mode == RGB_MATRIX_TYPING_HEATMAP) { - process_rgb_matrix_typing_heatmap(row, col); - } - } -#endif // defined(RGB_MATRIX_FRAMEBUFFER_EFFECTS) && defined(ENABLE_RGB_MATRIX_TYPING_HEATMAP) -} - -void rgb_matrix_test(void) { - // Mask out bits 4 and 5 - // Increase the factor to make the test animation slower (and reduce to make it faster) - uint8_t factor = 10; - switch ((g_rgb_timer & (0b11 << factor)) >> factor) { - case 0: { - rgb_matrix_set_color_all(20, 0, 0); - break; - } - case 1: { - rgb_matrix_set_color_all(0, 20, 0); - break; - } - case 2: { - rgb_matrix_set_color_all(0, 0, 20); - break; - } - case 3: { - rgb_matrix_set_color_all(20, 20, 20); - break; - } - } -} - -static bool rgb_matrix_none(effect_params_t *params) { - if (!params->init) { - return false; - } - - rgb_matrix_set_color_all(0, 0, 0); - return false; -} - -static void rgb_task_timers(void) { -#if defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0 - uint32_t deltaTime = sync_timer_elapsed32(rgb_timer_buffer); -#endif // defined(RGB_MATRIX_KEYREACTIVE_ENABLED) || RGB_MATRIX_TIMEOUT > 0 - rgb_timer_buffer = sync_timer_read32(); - - // Update double buffer timers -#if RGB_MATRIX_TIMEOUT > 0 - if (rgb_anykey_timer + deltaTime <= UINT32_MAX) { - rgb_anykey_timer += deltaTime; - } -#endif // RGB_MATRIX_TIMEOUT > 0 - - // Update double buffer last hit timers -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - uint8_t count = last_hit_buffer.count; - for (uint8_t i = 0; i < count; ++i) { - if (UINT16_MAX - deltaTime < last_hit_buffer.tick[i]) { - last_hit_buffer.count--; - continue; - } - last_hit_buffer.tick[i] += deltaTime; - } -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED -} - -static void rgb_task_sync(void) { - eeconfig_flush_rgb_matrix(false); - // next task - if (sync_timer_elapsed32(g_rgb_timer) >= RGB_MATRIX_LED_FLUSH_LIMIT) rgb_task_state = STARTING; -} - -static void rgb_task_start(void) { - // reset iter - rgb_effect_params.iter = 0; - - // update double buffers - g_rgb_timer = rgb_timer_buffer; -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - g_last_hit_tracker = last_hit_buffer; -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - - // next task - rgb_task_state = RENDERING; -} - -static void rgb_task_render(uint8_t effect) { - bool rendering = false; - rgb_effect_params.init = (effect != rgb_last_effect) || (rgb_matrix_config.enable != rgb_last_enable); - if (rgb_effect_params.flags != rgb_matrix_config.flags) { - rgb_effect_params.flags = rgb_matrix_config.flags; - rgb_matrix_set_color_all(0, 0, 0); - } - - // each effect can opt to do calculations - // and/or request PWM buffer updates. - switch (effect) { - case RGB_MATRIX_NONE: - rendering = rgb_matrix_none(&rgb_effect_params); - break; - -// --------------------------------------------- -// -----Begin rgb effect switch case macros----- -#define RGB_MATRIX_EFFECT(name, ...) \ - case RGB_MATRIX_##name: \ - rendering = name(&rgb_effect_params); \ - break; -#include "rgb_matrix_effects.inc" -#undef RGB_MATRIX_EFFECT - -#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) -# define RGB_MATRIX_EFFECT(name, ...) \ - case RGB_MATRIX_CUSTOM_##name: \ - rendering = name(&rgb_effect_params); \ - break; -# ifdef RGB_MATRIX_CUSTOM_KB -# include "rgb_matrix_kb.inc" -# endif -# ifdef RGB_MATRIX_CUSTOM_USER -# include "rgb_matrix_user.inc" -# endif -# undef RGB_MATRIX_EFFECT -#endif - // -----End rgb effect switch case macros------- - // --------------------------------------------- - - // Factory default magic value - case UINT8_MAX: { - rgb_matrix_test(); - rgb_task_state = FLUSHING; - } - return; - } - - rgb_effect_params.iter++; - - // next task - if (!rendering) { - rgb_task_state = FLUSHING; - if (!rgb_effect_params.init && effect == RGB_MATRIX_NONE) { - // We only need to flush once if we are RGB_MATRIX_NONE - rgb_task_state = SYNCING; - } - } -} - -static void rgb_task_flush(uint8_t effect) { - // update last trackers after the first full render so we can init over several frames - rgb_last_effect = effect; - rgb_last_enable = rgb_matrix_config.enable; - - // update pwm buffers - rgb_matrix_update_pwm_buffers(); - - // next task - rgb_task_state = SYNCING; -} - -void rgb_matrix_task(void) { - rgb_task_timers(); - - // Ideally we would also stop sending zeros to the LED driver PWM buffers - // while suspended and just do a software shutdown. This is a cheap hack for now. - bool suspend_backlight = suspend_state || -#if RGB_MATRIX_TIMEOUT > 0 - (rgb_anykey_timer > (uint32_t)RGB_MATRIX_TIMEOUT) || -#endif // RGB_MATRIX_TIMEOUT > 0 - false; - - uint8_t effect = suspend_backlight || !rgb_matrix_config.enable ? 0 : rgb_matrix_config.mode; - - switch (rgb_task_state) { - case STARTING: - rgb_task_start(); - break; - case RENDERING: - rgb_task_render(effect); - if (effect) { - rgb_matrix_indicators(); - rgb_matrix_indicators_advanced(&rgb_effect_params); - } - break; - case FLUSHING: - rgb_task_flush(effect); - break; - case SYNCING: - rgb_task_sync(); - break; - } -} - -void rgb_matrix_indicators(void) { - rgb_matrix_indicators_kb(); -} - -__attribute__((weak)) bool rgb_matrix_indicators_kb(void) { - return rgb_matrix_indicators_user(); -} - -__attribute__((weak)) bool rgb_matrix_indicators_user(void) { - return true; -} - -void rgb_matrix_indicators_advanced(effect_params_t *params) { - /* special handling is needed for "params->iter", since it's already been incremented. - * Could move the invocations to rgb_task_render, but then it's missing a few checks - * and not sure which would be better. Otherwise, this should be called from - * rgb_task_render, right before the iter++ line. - */ - RGB_MATRIX_USE_LIMITS_ITER(min, max, params->iter - 1); - rgb_matrix_indicators_advanced_kb(min, max); -} - -__attribute__((weak)) bool rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max) { - return rgb_matrix_indicators_advanced_user(led_min, led_max); -} - -__attribute__((weak)) bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { - return true; -} - -void rgb_matrix_init(void) { - rgb_matrix_driver.init(); - -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED - g_last_hit_tracker.count = 0; - for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { - g_last_hit_tracker.tick[i] = UINT16_MAX; - } - - last_hit_buffer.count = 0; - for (uint8_t i = 0; i < LED_HITS_TO_REMEMBER; ++i) { - last_hit_buffer.tick[i] = UINT16_MAX; - } -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - - if (!eeconfig_is_enabled()) { - dprintf("rgb_matrix_init_drivers eeconfig is not enabled.\n"); - eeconfig_init(); - eeconfig_update_rgb_matrix_default(); - } - - eeconfig_init_rgb_matrix(); - if (!rgb_matrix_config.mode) { - dprintf("rgb_matrix_init_drivers rgb_matrix_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_update_rgb_matrix_default(); - } - eeconfig_debug_rgb_matrix(); // display current eeprom values -} - -void rgb_matrix_set_suspend_state(bool state) { -#ifdef RGB_DISABLE_WHEN_USB_SUSPENDED - if (state && !suspend_state) { // only run if turning off, and only once - rgb_task_render(0); // turn off all LEDs when suspending - rgb_task_flush(0); // and actually flash led state to LEDs - } - suspend_state = state; -#endif -} - -bool rgb_matrix_get_suspend_state(void) { - return suspend_state; -} - -void rgb_matrix_toggle_eeprom_helper(bool write_to_eeprom) { - rgb_matrix_config.enable ^= 1; - rgb_task_state = STARTING; - eeconfig_flag_rgb_matrix(write_to_eeprom); - dprintf("rgb matrix toggle [%s]: rgb_matrix_config.enable = %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.enable); -} -void rgb_matrix_toggle_noeeprom(void) { - rgb_matrix_toggle_eeprom_helper(false); -} -void rgb_matrix_toggle(void) { - rgb_matrix_toggle_eeprom_helper(true); -} - -void rgb_matrix_enable(void) { - rgb_matrix_enable_noeeprom(); - eeconfig_flag_rgb_matrix(true); -} - -void rgb_matrix_enable_noeeprom(void) { - if (!rgb_matrix_config.enable) rgb_task_state = STARTING; - rgb_matrix_config.enable = 1; -} - -void rgb_matrix_disable(void) { - rgb_matrix_disable_noeeprom(); - eeconfig_flag_rgb_matrix(true); -} - -void rgb_matrix_disable_noeeprom(void) { - if (rgb_matrix_config.enable) rgb_task_state = STARTING; - rgb_matrix_config.enable = 0; -} - -uint8_t rgb_matrix_is_enabled(void) { - return rgb_matrix_config.enable; -} - -void rgb_matrix_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { - if (!rgb_matrix_config.enable) { - return; - } - if (mode < 1) { - rgb_matrix_config.mode = 1; - } else if (mode >= RGB_MATRIX_EFFECT_MAX) { - rgb_matrix_config.mode = RGB_MATRIX_EFFECT_MAX - 1; - } else { - rgb_matrix_config.mode = mode; - } - rgb_task_state = STARTING; - eeconfig_flag_rgb_matrix(write_to_eeprom); - dprintf("rgb matrix mode [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.mode); -} -void rgb_matrix_mode_noeeprom(uint8_t mode) { - rgb_matrix_mode_eeprom_helper(mode, false); -} -void rgb_matrix_mode(uint8_t mode) { - rgb_matrix_mode_eeprom_helper(mode, true); -} - -uint8_t rgb_matrix_get_mode(void) { - return rgb_matrix_config.mode; -} - -void rgb_matrix_step_helper(bool write_to_eeprom) { - uint8_t mode = rgb_matrix_config.mode + 1; - rgb_matrix_mode_eeprom_helper((mode < RGB_MATRIX_EFFECT_MAX) ? mode : 1, write_to_eeprom); -} -void rgb_matrix_step_noeeprom(void) { - rgb_matrix_step_helper(false); -} -void rgb_matrix_step(void) { - rgb_matrix_step_helper(true); -} - -void rgb_matrix_step_reverse_helper(bool write_to_eeprom) { - uint8_t mode = rgb_matrix_config.mode - 1; - rgb_matrix_mode_eeprom_helper((mode < 1) ? RGB_MATRIX_EFFECT_MAX - 1 : mode, write_to_eeprom); -} -void rgb_matrix_step_reverse_noeeprom(void) { - rgb_matrix_step_reverse_helper(false); -} -void rgb_matrix_step_reverse(void) { - rgb_matrix_step_reverse_helper(true); -} - -void rgb_matrix_sethsv_eeprom_helper(uint16_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) { - if (!rgb_matrix_config.enable) { - return; - } - rgb_matrix_config.hsv.h = hue; - rgb_matrix_config.hsv.s = sat; - rgb_matrix_config.hsv.v = (val > RGB_MATRIX_MAXIMUM_BRIGHTNESS) ? RGB_MATRIX_MAXIMUM_BRIGHTNESS : val; - eeconfig_flag_rgb_matrix(write_to_eeprom); - dprintf("rgb matrix set hsv [%s]: %u,%u,%u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v); -} -void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val) { - rgb_matrix_sethsv_eeprom_helper(hue, sat, val, false); -} -void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val) { - rgb_matrix_sethsv_eeprom_helper(hue, sat, val, true); -} - -HSV rgb_matrix_get_hsv(void) { - return rgb_matrix_config.hsv; -} -uint8_t rgb_matrix_get_hue(void) { - return rgb_matrix_config.hsv.h; -} -uint8_t rgb_matrix_get_sat(void) { - return rgb_matrix_config.hsv.s; -} -uint8_t rgb_matrix_get_val(void) { - return rgb_matrix_config.hsv.v; -} - -void rgb_matrix_increase_hue_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h + RGB_MATRIX_HUE_STEP, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v, write_to_eeprom); -} -void rgb_matrix_increase_hue_noeeprom(void) { - rgb_matrix_increase_hue_helper(false); -} -void rgb_matrix_increase_hue(void) { - rgb_matrix_increase_hue_helper(true); -} - -void rgb_matrix_decrease_hue_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h - RGB_MATRIX_HUE_STEP, rgb_matrix_config.hsv.s, rgb_matrix_config.hsv.v, write_to_eeprom); -} -void rgb_matrix_decrease_hue_noeeprom(void) { - rgb_matrix_decrease_hue_helper(false); -} -void rgb_matrix_decrease_hue(void) { - rgb_matrix_decrease_hue_helper(true); -} - -void rgb_matrix_increase_sat_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, qadd8(rgb_matrix_config.hsv.s, RGB_MATRIX_SAT_STEP), rgb_matrix_config.hsv.v, write_to_eeprom); -} -void rgb_matrix_increase_sat_noeeprom(void) { - rgb_matrix_increase_sat_helper(false); -} -void rgb_matrix_increase_sat(void) { - rgb_matrix_increase_sat_helper(true); -} - -void rgb_matrix_decrease_sat_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, qsub8(rgb_matrix_config.hsv.s, RGB_MATRIX_SAT_STEP), rgb_matrix_config.hsv.v, write_to_eeprom); -} -void rgb_matrix_decrease_sat_noeeprom(void) { - rgb_matrix_decrease_sat_helper(false); -} -void rgb_matrix_decrease_sat(void) { - rgb_matrix_decrease_sat_helper(true); -} - -void rgb_matrix_increase_val_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, qadd8(rgb_matrix_config.hsv.v, RGB_MATRIX_VAL_STEP), write_to_eeprom); -} -void rgb_matrix_increase_val_noeeprom(void) { - rgb_matrix_increase_val_helper(false); -} -void rgb_matrix_increase_val(void) { - rgb_matrix_increase_val_helper(true); -} - -void rgb_matrix_decrease_val_helper(bool write_to_eeprom) { - rgb_matrix_sethsv_eeprom_helper(rgb_matrix_config.hsv.h, rgb_matrix_config.hsv.s, qsub8(rgb_matrix_config.hsv.v, RGB_MATRIX_VAL_STEP), write_to_eeprom); -} -void rgb_matrix_decrease_val_noeeprom(void) { - rgb_matrix_decrease_val_helper(false); -} -void rgb_matrix_decrease_val(void) { - rgb_matrix_decrease_val_helper(true); -} - -void rgb_matrix_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { - rgb_matrix_config.speed = speed; - eeconfig_flag_rgb_matrix(write_to_eeprom); - dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.speed); -} -void rgb_matrix_set_speed_noeeprom(uint8_t speed) { - rgb_matrix_set_speed_eeprom_helper(speed, false); -} -void rgb_matrix_set_speed(uint8_t speed) { - rgb_matrix_set_speed_eeprom_helper(speed, true); -} - -uint8_t rgb_matrix_get_speed(void) { - return rgb_matrix_config.speed; -} - -void rgb_matrix_increase_speed_helper(bool write_to_eeprom) { - rgb_matrix_set_speed_eeprom_helper(qadd8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP), write_to_eeprom); -} -void rgb_matrix_increase_speed_noeeprom(void) { - rgb_matrix_increase_speed_helper(false); -} -void rgb_matrix_increase_speed(void) { - rgb_matrix_increase_speed_helper(true); -} - -void rgb_matrix_decrease_speed_helper(bool write_to_eeprom) { - rgb_matrix_set_speed_eeprom_helper(qsub8(rgb_matrix_config.speed, RGB_MATRIX_SPD_STEP), write_to_eeprom); -} -void rgb_matrix_decrease_speed_noeeprom(void) { - rgb_matrix_decrease_speed_helper(false); -} -void rgb_matrix_decrease_speed(void) { - rgb_matrix_decrease_speed_helper(true); -} - -void rgb_matrix_set_flags_eeprom_helper(led_flags_t flags, bool write_to_eeprom) { - rgb_matrix_config.flags = flags; - eeconfig_flag_rgb_matrix(write_to_eeprom); - dprintf("rgb matrix set speed [%s]: %u\n", (write_to_eeprom) ? "EEPROM" : "NOEEPROM", rgb_matrix_config.flags); -} - -led_flags_t rgb_matrix_get_flags(void) { - return rgb_matrix_config.flags; -} - -void rgb_matrix_set_flags(led_flags_t flags) { - rgb_matrix_set_flags_eeprom_helper(flags, true); -} - -void rgb_matrix_set_flags_noeeprom(led_flags_t flags) { - rgb_matrix_set_flags_eeprom_helper(flags, false); -} diff --git a/quantum/rgb_matrix/rgb_matrix.h b/quantum/rgb_matrix/rgb_matrix.h deleted file mode 100644 index 9ea248b66d2c..000000000000 --- a/quantum/rgb_matrix/rgb_matrix.h +++ /dev/null @@ -1,270 +0,0 @@ -/* Copyright 2017 Jason Williams - * Copyright 2017 Jack Humbert - * Copyright 2018 Yiancar - * - * 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 . - */ - -#pragma once - -#include -#include -#include "rgb_matrix_types.h" -#include "color.h" -#include "quantum.h" - -#ifdef IS31FL3731 -# include "is31fl3731.h" -#elif defined(IS31FL3733) -# include "is31fl3733.h" -#elif defined(IS31FL3736) -# include "is31fl3736.h" -#elif defined(IS31FL3737) -# include "is31fl3737.h" -#elif defined(IS31FL3741) -# include "is31fl3741.h" -#elif defined(IS31FLCOMMON) -# include "is31flcommon.h" -#elif defined(CKLED2001) -# include "ckled2001.h" -#elif defined(AW20216) -# include "aw20216.h" -#elif defined(WS2812) -# include "ws2812.h" -#endif - -#ifndef RGB_MATRIX_LED_FLUSH_LIMIT -# define RGB_MATRIX_LED_FLUSH_LIMIT 16 -#endif - -#ifndef RGB_MATRIX_LED_PROCESS_LIMIT -# define RGB_MATRIX_LED_PROCESS_LIMIT (RGB_MATRIX_LED_COUNT + 4) / 5 -#endif - -#if defined(RGB_MATRIX_LED_PROCESS_LIMIT) && RGB_MATRIX_LED_PROCESS_LIMIT > 0 && RGB_MATRIX_LED_PROCESS_LIMIT < RGB_MATRIX_LED_COUNT -# if defined(RGB_MATRIX_SPLIT) -# define RGB_MATRIX_USE_LIMITS_ITER(min, max, iter) \ - uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * (iter); \ - uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT; \ - if (max > RGB_MATRIX_LED_COUNT) max = RGB_MATRIX_LED_COUNT; \ - uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; \ - if (is_keyboard_left() && (max > k_rgb_matrix_split[0])) max = k_rgb_matrix_split[0]; \ - if (!(is_keyboard_left()) && (min < k_rgb_matrix_split[0])) min = k_rgb_matrix_split[0]; -# else -# define RGB_MATRIX_USE_LIMITS_ITER(min, max, iter) \ - uint8_t min = RGB_MATRIX_LED_PROCESS_LIMIT * (iter); \ - uint8_t max = min + RGB_MATRIX_LED_PROCESS_LIMIT; \ - if (max > RGB_MATRIX_LED_COUNT) max = RGB_MATRIX_LED_COUNT; -# endif -#else -# if defined(RGB_MATRIX_SPLIT) -# define RGB_MATRIX_USE_LIMITS_ITER(min, max, iter) \ - uint8_t min = 0; \ - uint8_t max = RGB_MATRIX_LED_COUNT; \ - const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; \ - if (is_keyboard_left() && (max > k_rgb_matrix_split[0])) max = k_rgb_matrix_split[0]; \ - if (!(is_keyboard_left()) && (min < k_rgb_matrix_split[0])) min = k_rgb_matrix_split[0]; -# else -# define RGB_MATRIX_USE_LIMITS_ITER(min, max, iter) \ - uint8_t min = 0; \ - uint8_t max = RGB_MATRIX_LED_COUNT; -# endif -#endif - -#define RGB_MATRIX_USE_LIMITS(min, max) RGB_MATRIX_USE_LIMITS_ITER(min, max, params->iter) - -#define RGB_MATRIX_INDICATOR_SET_COLOR(i, r, g, b) \ - if (i >= led_min && i < led_max) { \ - rgb_matrix_set_color(i, r, g, b); \ - } - -#define RGB_MATRIX_TEST_LED_FLAGS() \ - if (!HAS_ANY_FLAGS(g_led_config.flags[i], params->flags)) continue - -enum rgb_matrix_effects { - RGB_MATRIX_NONE = 0, - -// -------------------------------------- -// -----Begin rgb effect enum macros----- -#define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_##name, -#include "rgb_matrix_effects.inc" -#undef RGB_MATRIX_EFFECT - -#if defined(RGB_MATRIX_CUSTOM_KB) || defined(RGB_MATRIX_CUSTOM_USER) -# define RGB_MATRIX_EFFECT(name, ...) RGB_MATRIX_CUSTOM_##name, -# ifdef RGB_MATRIX_CUSTOM_KB -# include "rgb_matrix_kb.inc" -# endif -# ifdef RGB_MATRIX_CUSTOM_USER -# include "rgb_matrix_user.inc" -# endif -# undef RGB_MATRIX_EFFECT -#endif - // -------------------------------------- - // -----End rgb effect enum macros------- - - RGB_MATRIX_EFFECT_MAX -}; - -void eeconfig_update_rgb_matrix_default(void); -void eeconfig_update_rgb_matrix(void); - -uint8_t rgb_matrix_map_row_column_to_led_kb(uint8_t row, uint8_t column, uint8_t *led_i); -uint8_t rgb_matrix_map_row_column_to_led(uint8_t row, uint8_t column, uint8_t *led_i); - -void rgb_matrix_set_color(int index, uint8_t red, uint8_t green, uint8_t blue); -void rgb_matrix_set_color_all(uint8_t red, uint8_t green, uint8_t blue); - -void process_rgb_matrix(uint8_t row, uint8_t col, bool pressed); - -void rgb_matrix_task(void); - -// This runs after another backlight effect and replaces -// colors already set -void rgb_matrix_indicators(void); -bool rgb_matrix_indicators_kb(void); -bool rgb_matrix_indicators_user(void); - -void rgb_matrix_indicators_advanced(effect_params_t *params); -bool rgb_matrix_indicators_advanced_kb(uint8_t led_min, uint8_t led_max); -bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max); - -void rgb_matrix_init(void); - -void rgb_matrix_reload_from_eeprom(void); - -void rgb_matrix_set_suspend_state(bool state); -bool rgb_matrix_get_suspend_state(void); -void rgb_matrix_toggle(void); -void rgb_matrix_toggle_noeeprom(void); -void rgb_matrix_enable(void); -void rgb_matrix_enable_noeeprom(void); -void rgb_matrix_disable(void); -void rgb_matrix_disable_noeeprom(void); -uint8_t rgb_matrix_is_enabled(void); -void rgb_matrix_mode(uint8_t mode); -void rgb_matrix_mode_noeeprom(uint8_t mode); -uint8_t rgb_matrix_get_mode(void); -void rgb_matrix_step(void); -void rgb_matrix_step_noeeprom(void); -void rgb_matrix_step_reverse(void); -void rgb_matrix_step_reverse_noeeprom(void); -void rgb_matrix_sethsv(uint16_t hue, uint8_t sat, uint8_t val); -void rgb_matrix_sethsv_noeeprom(uint16_t hue, uint8_t sat, uint8_t val); -HSV rgb_matrix_get_hsv(void); -uint8_t rgb_matrix_get_hue(void); -uint8_t rgb_matrix_get_sat(void); -uint8_t rgb_matrix_get_val(void); -void rgb_matrix_increase_hue(void); -void rgb_matrix_increase_hue_noeeprom(void); -void rgb_matrix_decrease_hue(void); -void rgb_matrix_decrease_hue_noeeprom(void); -void rgb_matrix_increase_sat(void); -void rgb_matrix_increase_sat_noeeprom(void); -void rgb_matrix_decrease_sat(void); -void rgb_matrix_decrease_sat_noeeprom(void); -void rgb_matrix_increase_val(void); -void rgb_matrix_increase_val_noeeprom(void); -void rgb_matrix_decrease_val(void); -void rgb_matrix_decrease_val_noeeprom(void); -void rgb_matrix_set_speed(uint8_t speed); -void rgb_matrix_set_speed_noeeprom(uint8_t speed); -uint8_t rgb_matrix_get_speed(void); -void rgb_matrix_increase_speed(void); -void rgb_matrix_increase_speed_noeeprom(void); -void rgb_matrix_decrease_speed(void); -void rgb_matrix_decrease_speed_noeeprom(void); -led_flags_t rgb_matrix_get_flags(void); -void rgb_matrix_set_flags(led_flags_t flags); -void rgb_matrix_set_flags_noeeprom(led_flags_t flags); - -#ifndef RGBLIGHT_ENABLE -# define eeconfig_update_rgblight_current eeconfig_update_rgb_matrix -# define rgblight_reload_from_eeprom rgb_matrix_reload_from_eeprom -# define rgblight_toggle rgb_matrix_toggle -# define rgblight_toggle_noeeprom rgb_matrix_toggle_noeeprom -# define rgblight_enable rgb_matrix_enable -# define rgblight_enable_noeeprom rgb_matrix_enable_noeeprom -# define rgblight_disable rgb_matrix_disable -# define rgblight_disable_noeeprom rgb_matrix_disable_noeeprom -# define rgblight_is_enabled rgb_matrix_is_enabled -# define rgblight_mode rgb_matrix_mode -# define rgblight_mode_noeeprom rgb_matrix_mode_noeeprom -# define rgblight_get_mode rgb_matrix_get_mode -# define rgblight_get_hue rgb_matrix_get_hue -# define rgblight_get_sat rgb_matrix_get_sat -# define rgblight_get_val rgb_matrix_get_val -# define rgblight_get_hsv rgb_matrix_get_hsv -# define rgblight_step rgb_matrix_step -# define rgblight_step_noeeprom rgb_matrix_step_noeeprom -# define rgblight_step_reverse rgb_matrix_step_reverse -# define rgblight_step_reverse_noeeprom rgb_matrix_step_reverse_noeeprom -# define rgblight_sethsv rgb_matrix_sethsv -# define rgblight_sethsv_noeeprom rgb_matrix_sethsv_noeeprom -# define rgblight_increase_hue rgb_matrix_increase_hue -# define rgblight_increase_hue_noeeprom rgb_matrix_increase_hue_noeeprom -# define rgblight_decrease_hue rgb_matrix_decrease_hue -# define rgblight_decrease_hue_noeeprom rgb_matrix_decrease_hue_noeeprom -# define rgblight_increase_sat rgb_matrix_increase_sat -# define rgblight_increase_sat_noeeprom rgb_matrix_increase_sat_noeeprom -# define rgblight_decrease_sat rgb_matrix_decrease_sat -# define rgblight_decrease_sat_noeeprom rgb_matrix_decrease_sat_noeeprom -# define rgblight_increase_val rgb_matrix_increase_val -# define rgblight_increase_val_noeeprom rgb_matrix_increase_val_noeeprom -# define rgblight_decrease_val rgb_matrix_decrease_val -# define rgblight_decrease_val_noeeprom rgb_matrix_decrease_val_noeeprom -# define rgblight_set_speed rgb_matrix_set_speed -# define rgblight_set_speed_noeeprom rgb_matrix_set_speed_noeeprom -# define rgblight_get_speed rgb_matrix_get_speed -# define rgblight_increase_speed rgb_matrix_increase_speed -# define rgblight_increase_speed_noeeprom rgb_matrix_increase_speed_noeeprom -# define rgblight_decrease_speed rgb_matrix_decrease_speed -# define rgblight_decrease_speed_noeeprom rgb_matrix_decrease_speed_noeeprom -#endif - -typedef struct { - /* Perform any initialisation required for the other driver functions to work. */ - void (*init)(void); - /* Set the colour of a single LED in the buffer. */ - void (*set_color)(int index, uint8_t r, uint8_t g, uint8_t b); - /* Set the colour of all LEDS on the keyboard in the buffer. */ - void (*set_color_all)(uint8_t r, uint8_t g, uint8_t b); - /* Flush any buffered changes to the hardware. */ - void (*flush)(void); -} rgb_matrix_driver_t; - -static inline bool rgb_matrix_check_finished_leds(uint8_t led_idx) { -#if defined(RGB_MATRIX_SPLIT) - if (is_keyboard_left()) { - uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; - return led_idx < k_rgb_matrix_split[0]; - } else - return led_idx < RGB_MATRIX_LED_COUNT; -#else - return led_idx < RGB_MATRIX_LED_COUNT; -#endif -} - -extern const rgb_matrix_driver_t rgb_matrix_driver; - -extern rgb_config_t rgb_matrix_config; - -extern uint32_t g_rgb_timer; -extern led_config_t g_led_config; -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -extern last_hit_t g_last_hit_tracker; -#endif -#ifdef RGB_MATRIX_FRAMEBUFFER_EFFECTS -extern uint8_t g_rgb_frame_buffer[MATRIX_ROWS][MATRIX_COLS]; -#endif diff --git a/quantum/rgb_matrix/rgb_matrix_drivers.c b/quantum/rgb_matrix/rgb_matrix_drivers.c deleted file mode 100644 index d66fc801ddea..000000000000 --- a/quantum/rgb_matrix/rgb_matrix_drivers.c +++ /dev/null @@ -1,471 +0,0 @@ -/* Copyright 2018 James Laird-Wah - * - * 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 . - */ - -#include "rgb_matrix.h" - -/* Each driver needs to define the struct - * const rgb_matrix_driver_t rgb_matrix_driver; - * All members must be provided. - * Keyboard custom drivers can define this in their own files, it should only - * be here if shared between boards. - */ - -#if defined(IS31FL3731) || defined(IS31FL3733) || defined(IS31FL3736) || defined(IS31FL3737) || defined(IS31FL3741) || defined(IS31FLCOMMON) || defined(CKLED2001) -# include "i2c_master.h" - -// TODO: Remove this at some later date -# if defined(DRIVER_ADDR_1) && defined(DRIVER_ADDR_2) -# if DRIVER_ADDR_1 == DRIVER_ADDR_2 -# error "Setting DRIVER_ADDR_2 == DRIVER_ADDR_1 is obsolete. If you are only using one ISSI driver, set DRIVER_COUNT to 1 and remove DRIVER_ADDR_2" -# endif -# endif - -static void init(void) { - i2c_init(); - -# if defined(IS31FL3731) - IS31FL3731_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - IS31FL3731_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - IS31FL3731_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - IS31FL3731_init(DRIVER_ADDR_4); -# endif -# endif -# endif - -# elif defined(IS31FL3733) -# if !defined(DRIVER_SYNC_1) -# define DRIVER_SYNC_1 0 -# endif - IS31FL3733_init(DRIVER_ADDR_1, DRIVER_SYNC_1); -# if defined(DRIVER_ADDR_2) -# if !defined(DRIVER_SYNC_2) -# define DRIVER_SYNC_2 0 -# endif - IS31FL3733_init(DRIVER_ADDR_2, DRIVER_SYNC_2); -# if defined(DRIVER_ADDR_3) -# if !defined(DRIVER_SYNC_3) -# define DRIVER_SYNC_3 0 -# endif - IS31FL3733_init(DRIVER_ADDR_3, DRIVER_SYNC_3); -# if defined(DRIVER_ADDR_4) -# if !defined(DRIVER_SYNC_4) -# define DRIVER_SYNC_4 0 -# endif - IS31FL3733_init(DRIVER_ADDR_4, DRIVER_SYNC_4); -# endif -# endif -# endif - -# elif defined(IS31FL3736) - IS31FL3736_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - IS31FL3736_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - IS31FL3736_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - IS31FL3736_init(DRIVER_ADDR_4); -# endif -# endif -# endif - -# elif defined(IS31FL3737) - IS31FL3737_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - IS31FL3737_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - IS31FL3737_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - IS31FL3737_init(DRIVER_ADDR_4); -# endif -# endif -# endif - -# elif defined(IS31FL3741) - IS31FL3741_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - IS31FL3741_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - IS31FL3741_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - IS31FL3741_init(DRIVER_ADDR_4); -# endif -# endif -# endif - -# elif defined(IS31FLCOMMON) - IS31FL_common_init(DRIVER_ADDR_1, ISSI_SSR_1); -# if defined(DRIVER_ADDR_2) - IS31FL_common_init(DRIVER_ADDR_2, ISSI_SSR_2); -# if defined(DRIVER_ADDR_3) - IS31FL_common_init(DRIVER_ADDR_3, ISSI_SSR_3); -# if defined(DRIVER_ADDR_4) - IS31FL_common_init(DRIVER_ADDR_4, ISSI_SSR_4); -# endif -# endif -# endif - -# elif defined(CKLED2001) - CKLED2001_init(DRIVER_ADDR_1); -# if defined(DRIVER_ADDR_2) - CKLED2001_init(DRIVER_ADDR_2); -# if defined(DRIVER_ADDR_3) - CKLED2001_init(DRIVER_ADDR_3); -# if defined(DRIVER_ADDR_4) - CKLED2001_init(DRIVER_ADDR_4); -# endif -# endif -# endif -# endif - - for (int index = 0; index < RGB_MATRIX_LED_COUNT; index++) { - bool enabled = true; - - // This only caches it for later -# if defined(IS31FL3731) - IS31FL3731_set_led_control_register(index, enabled, enabled, enabled); -# elif defined(IS31FL3733) - IS31FL3733_set_led_control_register(index, enabled, enabled, enabled); -# elif defined(IS31FL3736) - IS31FL3736_set_led_control_register(index, enabled, enabled, enabled); -# elif defined(IS31FL3737) - IS31FL3737_set_led_control_register(index, enabled, enabled, enabled); -# elif defined(IS31FL3741) - IS31FL3741_set_led_control_register(index, enabled, enabled, enabled); -# elif defined(IS31FLCOMMON) - IS31FL_RGB_set_scaling_buffer(index, enabled, enabled, enabled); -# elif defined(CKLED2001) - CKLED2001_set_led_control_register(index, enabled, enabled, enabled); -# endif - } - - // This actually updates the LED drivers -# if defined(IS31FL3731) - IS31FL3731_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3731_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3731_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3731_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FL3733) - IS31FL3733_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3733_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3733_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3733_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FL3736) - IS31FL3736_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3736_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3736_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3736_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FL3737) - IS31FL3737_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3737_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3737_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3737_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FL3741) - IS31FL3741_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3741_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3741_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3741_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(IS31FLCOMMON) -# ifdef ISSI_MANUAL_SCALING - IS31FL_set_manual_scaling_buffer(); -# endif - IS31FL_common_update_scaling_register(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL_common_update_scaling_register(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL_common_update_scaling_register(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL_common_update_scaling_register(DRIVER_ADDR_4, 3); -# endif -# endif -# endif - -# elif defined(CKLED2001) - CKLED2001_update_led_control_registers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - CKLED2001_update_led_control_registers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - CKLED2001_update_led_control_registers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - CKLED2001_update_led_control_registers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -# endif -} - -# if defined(IS31FL3731) -static void flush(void) { - IS31FL3731_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3731_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3731_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3731_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL3731_set_color, - .set_color_all = IS31FL3731_set_color_all, -}; - -# elif defined(IS31FL3733) -static void flush(void) { - IS31FL3733_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3733_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3733_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3733_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL3733_set_color, - .set_color_all = IS31FL3733_set_color_all, -}; - -# elif defined(IS31FL3736) -static void flush(void) { - IS31FL3736_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3736_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3736_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3736_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL3736_set_color, - .set_color_all = IS31FL3736_set_color_all, -}; - -# elif defined(IS31FL3737) -static void flush(void) { - IS31FL3737_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3737_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3737_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3737_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL3737_set_color, - .set_color_all = IS31FL3737_set_color_all, -}; - -# elif defined(IS31FL3741) -static void flush(void) { - IS31FL3741_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL3741_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL3741_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL3741_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL3741_set_color, - .set_color_all = IS31FL3741_set_color_all, -}; - -# elif defined(IS31FLCOMMON) -static void flush(void) { - IS31FL_common_update_pwm_register(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - IS31FL_common_update_pwm_register(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - IS31FL_common_update_pwm_register(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - IS31FL_common_update_pwm_register(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = IS31FL_RGB_set_color, - .set_color_all = IS31FL_RGB_set_color_all, -}; - -# elif defined(CKLED2001) -static void flush(void) { - CKLED2001_update_pwm_buffers(DRIVER_ADDR_1, 0); -# if defined(DRIVER_ADDR_2) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_2, 1); -# if defined(DRIVER_ADDR_3) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_3, 2); -# if defined(DRIVER_ADDR_4) - CKLED2001_update_pwm_buffers(DRIVER_ADDR_4, 3); -# endif -# endif -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = CKLED2001_set_color, - .set_color_all = CKLED2001_set_color_all, -}; -# endif - -#elif defined(AW20216) -# include "spi_master.h" - -static void init(void) { - spi_init(); - - AW20216_init(DRIVER_1_CS, DRIVER_1_EN); -# if defined(DRIVER_2_CS) - AW20216_init(DRIVER_2_CS, DRIVER_2_EN); -# endif -} - -static void flush(void) { - AW20216_update_pwm_buffers(DRIVER_1_CS, 0); -# if defined(DRIVER_2_CS) - AW20216_update_pwm_buffers(DRIVER_2_CS, 1); -# endif -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = AW20216_set_color, - .set_color_all = AW20216_set_color_all, -}; - -#elif defined(WS2812) -# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_CUSTOM_DRIVER) -# pragma message "Cannot use RGBLIGHT and RGB Matrix using WS2812 at the same time." -# pragma message "You need to use a custom driver, or re-implement the WS2812 driver to use a different configuration." -# endif - -// LED color buffer -LED_TYPE rgb_matrix_ws2812_array[RGB_MATRIX_LED_COUNT]; - -static void init(void) {} - -static void flush(void) { - ws2812_setleds(rgb_matrix_ws2812_array, RGB_MATRIX_LED_COUNT); -} - -// Set an led in the buffer to a color -static inline void setled(int i, uint8_t r, uint8_t g, uint8_t b) { -# if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - const uint8_t k_rgb_matrix_split[2] = RGB_MATRIX_SPLIT; - if (!is_keyboard_left()) { - if (i >= k_rgb_matrix_split[0]) { - i -= k_rgb_matrix_split[0]; - } else { - return; - } - } else if (i >= k_rgb_matrix_split[0]) { - return; - } -# endif - - rgb_matrix_ws2812_array[i].r = r; - rgb_matrix_ws2812_array[i].g = g; - rgb_matrix_ws2812_array[i].b = b; -# ifdef RGBW - convert_rgb_to_rgbw(&rgb_matrix_ws2812_array[i]); -# endif -} - -static void setled_all(uint8_t r, uint8_t g, uint8_t b) { - for (int i = 0; i < ARRAY_SIZE(rgb_matrix_ws2812_array); i++) { - setled(i, r, g, b); - } -} - -const rgb_matrix_driver_t rgb_matrix_driver = { - .init = init, - .flush = flush, - .set_color = setled, - .set_color_all = setled_all, -}; -#endif diff --git a/quantum/rgb_matrix/rgb_matrix_types.h b/quantum/rgb_matrix/rgb_matrix_types.h deleted file mode 100644 index 53ff7321b8df..000000000000 --- a/quantum/rgb_matrix/rgb_matrix_types.h +++ /dev/null @@ -1,100 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -#pragma once - -#include -#include -#include "color.h" - -#if defined(__GNUC__) -# define PACKED __attribute__((__packed__)) -#else -# define PACKED -#endif - -#if defined(_MSC_VER) -# pragma pack(push, 1) -#endif - -#if defined(RGB_MATRIX_KEYPRESSES) || defined(RGB_MATRIX_KEYRELEASES) -# define RGB_MATRIX_KEYREACTIVE_ENABLED -#endif - -// Last led hit -#ifndef LED_HITS_TO_REMEMBER -# define LED_HITS_TO_REMEMBER 8 -#endif // LED_HITS_TO_REMEMBER - -#ifdef RGB_MATRIX_KEYREACTIVE_ENABLED -typedef struct PACKED { - uint8_t count; - uint8_t x[LED_HITS_TO_REMEMBER]; - uint8_t y[LED_HITS_TO_REMEMBER]; - uint8_t index[LED_HITS_TO_REMEMBER]; - uint16_t tick[LED_HITS_TO_REMEMBER]; -} last_hit_t; -#endif // RGB_MATRIX_KEYREACTIVE_ENABLED - -typedef enum rgb_task_states { STARTING, RENDERING, FLUSHING, SYNCING } rgb_task_states; - -typedef uint8_t led_flags_t; - -typedef struct PACKED { - uint8_t iter; - led_flags_t flags; - bool init; -} effect_params_t; - -typedef struct PACKED { - uint8_t x; - uint8_t y; -} led_point_t; - -#define HAS_FLAGS(bits, flags) ((bits & flags) == flags) -#define HAS_ANY_FLAGS(bits, flags) ((bits & flags) != 0x00) - -#define LED_FLAG_ALL 0xFF -#define LED_FLAG_NONE 0x00 -#define LED_FLAG_MODIFIER 0x01 -#define LED_FLAG_UNDERGLOW 0x02 -#define LED_FLAG_KEYLIGHT 0x04 -#define LED_FLAG_INDICATOR 0x08 - -#define NO_LED 255 - -typedef struct PACKED { - uint8_t matrix_co[MATRIX_ROWS][MATRIX_COLS]; - led_point_t point[RGB_MATRIX_LED_COUNT]; - uint8_t flags[RGB_MATRIX_LED_COUNT]; -} led_config_t; - -typedef union { - uint64_t raw; - struct PACKED { - uint8_t enable : 2; - uint8_t mode : 6; - HSV hsv; - uint8_t speed; - led_flags_t flags; - }; -} rgb_config_t; - -_Static_assert(sizeof(rgb_config_t) == sizeof(uint64_t), "RGB Matrix EECONFIG out of spec."); - -#if defined(_MSC_VER) -# pragma pack(pop) -#endif diff --git a/quantum/rgblight/rgblight.c b/quantum/rgblight/rgblight.c deleted file mode 100644 index ea28801a40ad..000000000000 --- a/quantum/rgblight/rgblight.c +++ /dev/null @@ -1,1521 +0,0 @@ -/* Copyright 2016-2017 Yang Liu - * - * 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 . - */ -#include -#include -#include -#include "progmem.h" -#include "sync_timer.h" -#include "rgblight.h" -#include "color.h" -#include "debug.h" -#include "util.h" -#include "led_tables.h" -#include -#ifdef EEPROM_ENABLE -# include "eeprom.h" -#endif -#ifdef VELOCIKEY_ENABLE -# include "velocikey.h" -#endif - -#ifdef RGBLIGHT_SPLIT -/* for split keyboard */ -# define RGBLIGHT_SPLIT_SET_CHANGE_MODE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_MODE -# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_HSVS -# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS rgblight_status.change_flags |= (RGBLIGHT_STATUS_CHANGE_MODE | RGBLIGHT_STATUS_CHANGE_HSVS) -# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_LAYERS -# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE rgblight_status.change_flags |= RGBLIGHT_STATUS_CHANGE_TIMER -# define RGBLIGHT_SPLIT_ANIMATION_TICK rgblight_status.change_flags |= RGBLIGHT_STATUS_ANIMATION_TICK -#else -# define RGBLIGHT_SPLIT_SET_CHANGE_MODE -# define RGBLIGHT_SPLIT_SET_CHANGE_HSVS -# define RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS -# define RGBLIGHT_SPLIT_SET_CHANGE_LAYERS -# define RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE -# define RGBLIGHT_SPLIT_ANIMATION_TICK -#endif - -#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_SINGLE_DYNAMIC(sym) -#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_MULTI_DYNAMIC(sym) -#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym, -#define _RGBM_TMP_DYNAMIC(sym, msym) -static uint8_t static_effect_table[] = { -#include "rgblight_modes.h" -}; - -#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##msym, -#define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##msym, -static uint8_t mode_base_table[] = { - 0, // RGBLIGHT_MODE_zero -#include "rgblight_modes.h" -}; - -#if !defined(RGBLIGHT_DEFAULT_MODE) -# define RGBLIGHT_DEFAULT_MODE RGBLIGHT_MODE_STATIC_LIGHT -#endif - -#if !defined(RGBLIGHT_DEFAULT_HUE) -# define RGBLIGHT_DEFAULT_HUE 0 -#endif - -#if !defined(RGBLIGHT_DEFAULT_SAT) -# define RGBLIGHT_DEFAULT_SAT UINT8_MAX -#endif - -#if !defined(RGBLIGHT_DEFAULT_VAL) -# define RGBLIGHT_DEFAULT_VAL RGBLIGHT_LIMIT_VAL -#endif - -#if !defined(RGBLIGHT_DEFAULT_SPD) -# define RGBLIGHT_DEFAULT_SPD 0 -#endif - -static inline int is_static_effect(uint8_t mode) { - return memchr(static_effect_table, mode, sizeof(static_effect_table)) != NULL; -} - -#ifdef RGBLIGHT_LED_MAP -const uint8_t led_map[] PROGMEM = RGBLIGHT_LED_MAP; -#endif - -#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT -__attribute__((weak)) const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64}; -#endif - -rgblight_config_t rgblight_config; -rgblight_status_t rgblight_status = {.timer_enabled = false}; -bool is_rgblight_initialized = false; - -#ifdef RGBLIGHT_SLEEP -static bool is_suspended; -static bool pre_suspend_enabled; -#endif - -#ifdef RGBLIGHT_USE_TIMER -animation_status_t animation_status = {}; -#endif - -#ifndef LED_ARRAY -LED_TYPE led[RGBLED_NUM]; -# define LED_ARRAY led -#endif - -#ifdef RGBLIGHT_LAYERS -rgblight_segment_t const *const *rgblight_layers = NULL; - -static bool deferred_set_layer_state = false; -#endif - -rgblight_ranges_t rgblight_ranges = {0, RGBLED_NUM, 0, RGBLED_NUM, RGBLED_NUM}; - -void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds) { - rgblight_ranges.clipping_start_pos = start_pos; - rgblight_ranges.clipping_num_leds = num_leds; -} - -void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds) { - if (start_pos >= RGBLED_NUM) return; - if (start_pos + num_leds > RGBLED_NUM) return; - rgblight_ranges.effect_start_pos = start_pos; - rgblight_ranges.effect_end_pos = start_pos + num_leds; - rgblight_ranges.effect_num_leds = num_leds; -} - -__attribute__((weak)) RGB rgblight_hsv_to_rgb(HSV hsv) { - return hsv_to_rgb(hsv); -} - -void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { - HSV hsv = {hue, sat, val}; - RGB rgb = rgblight_hsv_to_rgb(hsv); - setrgb(rgb.r, rgb.g, rgb.b, led1); -} - -void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1) { - sethsv_raw(hue, sat, val > RGBLIGHT_LIMIT_VAL ? RGBLIGHT_LIMIT_VAL : val, led1); -} - -void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1) { - led1->r = r; - led1->g = g; - led1->b = b; -#ifdef RGBW - led1->w = 0; -#endif -} - -void rgblight_check_config(void) { - /* Add some out of bound checks for RGB light config */ - - if (rgblight_config.mode < RGBLIGHT_MODE_STATIC_LIGHT) { - rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT; - } else if (rgblight_config.mode > RGBLIGHT_MODES) { - rgblight_config.mode = RGBLIGHT_MODES; - } - - if (rgblight_config.val > RGBLIGHT_LIMIT_VAL) { - rgblight_config.val = RGBLIGHT_LIMIT_VAL; - } -} - -uint64_t eeconfig_read_rgblight(void) { -#ifdef EEPROM_ENABLE - return (uint64_t)((eeprom_read_dword(EECONFIG_RGBLIGHT)) | ((uint64_t)eeprom_read_byte(EECONFIG_RGBLIGHT_EXTENDED) << 32)); -#else - return 0; -#endif -} - -void eeconfig_update_rgblight(uint64_t val) { -#ifdef EEPROM_ENABLE - rgblight_check_config(); - eeprom_update_dword(EECONFIG_RGBLIGHT, val & 0xFFFFFFFF); - eeprom_update_byte(EECONFIG_RGBLIGHT_EXTENDED, (val >> 32) & 0xFF); -#endif -} - -void eeconfig_update_rgblight_current(void) { - eeconfig_update_rgblight(rgblight_config.raw); -} - -void eeconfig_update_rgblight_default(void) { - rgblight_config.enable = 1; - rgblight_config.mode = RGBLIGHT_DEFAULT_MODE; - rgblight_config.hue = RGBLIGHT_DEFAULT_HUE; - rgblight_config.sat = RGBLIGHT_DEFAULT_SAT; - rgblight_config.val = RGBLIGHT_DEFAULT_VAL; - rgblight_config.speed = RGBLIGHT_DEFAULT_SPD; - RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; - eeconfig_update_rgblight(rgblight_config.raw); -} - -void eeconfig_debug_rgblight(void) { - dprintf("rgblight_config EEPROM:\n"); - dprintf("rgblight_config.enable = %d\n", rgblight_config.enable); - dprintf("rghlight_config.mode = %d\n", rgblight_config.mode); - dprintf("rgblight_config.hue = %d\n", rgblight_config.hue); - dprintf("rgblight_config.sat = %d\n", rgblight_config.sat); - dprintf("rgblight_config.val = %d\n", rgblight_config.val); - dprintf("rgblight_config.speed = %d\n", rgblight_config.speed); -} - -void rgblight_init(void) { - /* if already initialized, don't do it again. - If you must do it again, extern this and set to false, first. - This is a dirty, dirty hack until proper hooks can be added for keyboard startup. */ - if (is_rgblight_initialized) { - return; - } - - dprintf("rgblight_init called.\n"); - dprintf("rgblight_init start!\n"); - if (!eeconfig_is_enabled()) { - dprintf("rgblight_init eeconfig is not enabled.\n"); - eeconfig_init(); - eeconfig_update_rgblight_default(); - } - rgblight_config.raw = eeconfig_read_rgblight(); - RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; - if (!rgblight_config.mode) { - dprintf("rgblight_init rgblight_config.mode = 0. Write default values to EEPROM.\n"); - eeconfig_update_rgblight_default(); - rgblight_config.raw = eeconfig_read_rgblight(); - } - rgblight_check_config(); - - eeconfig_debug_rgblight(); // display current eeprom values - - rgblight_timer_init(); // setup the timer - - if (rgblight_config.enable) { - rgblight_mode_noeeprom(rgblight_config.mode); - } - - is_rgblight_initialized = true; -} - -void rgblight_reload_from_eeprom(void) { - /* Reset back to what we have in eeprom */ - rgblight_config.raw = eeconfig_read_rgblight(); - RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; - rgblight_check_config(); - eeconfig_debug_rgblight(); // display current eeprom values - if (rgblight_config.enable) { - rgblight_mode_noeeprom(rgblight_config.mode); - } -} - -uint64_t rgblight_read_qword(void) { - return rgblight_config.raw; -} - -void rgblight_update_qword(uint64_t qword) { - RGBLIGHT_SPLIT_SET_CHANGE_MODEHSVS; - rgblight_config.raw = qword; - if (rgblight_config.enable) - rgblight_mode_noeeprom(rgblight_config.mode); - else { - rgblight_timer_disable(); - rgblight_set(); - } -} - -void rgblight_increase(void) { - uint8_t mode = 0; - if (rgblight_config.mode < RGBLIGHT_MODES) { - mode = rgblight_config.mode + 1; - } - rgblight_mode(mode); -} -void rgblight_decrease(void) { - uint8_t mode = 0; - // Mode will never be < 1. If it ever is, eeprom needs to be initialized. - if (rgblight_config.mode > RGBLIGHT_MODE_STATIC_LIGHT) { - mode = rgblight_config.mode - 1; - } - rgblight_mode(mode); -} -void rgblight_step_helper(bool write_to_eeprom) { - uint8_t mode = 0; - mode = rgblight_config.mode + 1; - if (mode > RGBLIGHT_MODES) { - mode = 1; - } - rgblight_mode_eeprom_helper(mode, write_to_eeprom); -} -void rgblight_step_noeeprom(void) { - rgblight_step_helper(false); -} -void rgblight_step(void) { - rgblight_step_helper(true); -} -void rgblight_step_reverse_helper(bool write_to_eeprom) { - uint8_t mode = 0; - mode = rgblight_config.mode - 1; - if (mode < 1) { - mode = RGBLIGHT_MODES; - } - rgblight_mode_eeprom_helper(mode, write_to_eeprom); -} -void rgblight_step_reverse_noeeprom(void) { - rgblight_step_reverse_helper(false); -} -void rgblight_step_reverse(void) { - rgblight_step_reverse_helper(true); -} - -uint8_t rgblight_get_mode(void) { - if (!rgblight_config.enable) { - return false; - } - - return rgblight_config.mode; -} - -void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom) { - if (!rgblight_config.enable) { - return; - } - if (mode < RGBLIGHT_MODE_STATIC_LIGHT) { - rgblight_config.mode = RGBLIGHT_MODE_STATIC_LIGHT; - } else if (mode > RGBLIGHT_MODES) { - rgblight_config.mode = RGBLIGHT_MODES; - } else { - rgblight_config.mode = mode; - } - RGBLIGHT_SPLIT_SET_CHANGE_MODE; - if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight mode [EEPROM]: %u\n", rgblight_config.mode); - } else { - dprintf("rgblight mode [NOEEPROM]: %u\n", rgblight_config.mode); - } - if (is_static_effect(rgblight_config.mode)) { - rgblight_timer_disable(); - } else { - rgblight_timer_enable(); - } -#ifdef RGBLIGHT_USE_TIMER - animation_status.restart = true; -#endif - rgblight_sethsv_noeeprom(rgblight_config.hue, rgblight_config.sat, rgblight_config.val); -} - -void rgblight_mode(uint8_t mode) { - rgblight_mode_eeprom_helper(mode, true); -} - -void rgblight_mode_noeeprom(uint8_t mode) { - rgblight_mode_eeprom_helper(mode, false); -} - -void rgblight_toggle(void) { - dprintf("rgblight toggle [EEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_disable(); - } else { - rgblight_enable(); - } -} - -void rgblight_toggle_noeeprom(void) { - dprintf("rgblight toggle [NOEEPROM]: rgblight_config.enable = %u\n", !rgblight_config.enable); - if (rgblight_config.enable) { - rgblight_disable_noeeprom(); - } else { - rgblight_enable_noeeprom(); - } -} - -void rgblight_enable(void) { - rgblight_config.enable = 1; - // No need to update EEPROM here. rgblight_mode() will do that, actually - // eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight enable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); - rgblight_mode(rgblight_config.mode); -} - -void rgblight_enable_noeeprom(void) { - rgblight_config.enable = 1; - dprintf("rgblight enable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); - rgblight_mode_noeeprom(rgblight_config.mode); -} - -void rgblight_disable(void) { - rgblight_config.enable = 0; - eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight disable [EEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); - rgblight_timer_disable(); - RGBLIGHT_SPLIT_SET_CHANGE_MODE; - rgblight_set(); -} - -void rgblight_disable_noeeprom(void) { - rgblight_config.enable = 0; - dprintf("rgblight disable [NOEEPROM]: rgblight_config.enable = %u\n", rgblight_config.enable); - rgblight_timer_disable(); - RGBLIGHT_SPLIT_SET_CHANGE_MODE; - rgblight_set(); -} - -void rgblight_enabled_noeeprom(bool state) { - state ? rgblight_enable_noeeprom() : rgblight_disable_noeeprom(); -} - -bool rgblight_is_enabled(void) { - return rgblight_config.enable; -} - -void rgblight_increase_hue_helper(bool write_to_eeprom) { - uint8_t hue = rgblight_config.hue + RGBLIGHT_HUE_STEP; - rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); -} -void rgblight_increase_hue_noeeprom(void) { - rgblight_increase_hue_helper(false); -} -void rgblight_increase_hue(void) { - rgblight_increase_hue_helper(true); -} -void rgblight_decrease_hue_helper(bool write_to_eeprom) { - uint8_t hue = rgblight_config.hue - RGBLIGHT_HUE_STEP; - rgblight_sethsv_eeprom_helper(hue, rgblight_config.sat, rgblight_config.val, write_to_eeprom); -} -void rgblight_decrease_hue_noeeprom(void) { - rgblight_decrease_hue_helper(false); -} -void rgblight_decrease_hue(void) { - rgblight_decrease_hue_helper(true); -} -void rgblight_increase_sat_helper(bool write_to_eeprom) { - uint8_t sat = qadd8(rgblight_config.sat, RGBLIGHT_SAT_STEP); - rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom); -} -void rgblight_increase_sat_noeeprom(void) { - rgblight_increase_sat_helper(false); -} -void rgblight_increase_sat(void) { - rgblight_increase_sat_helper(true); -} -void rgblight_decrease_sat_helper(bool write_to_eeprom) { - uint8_t sat = qsub8(rgblight_config.sat, RGBLIGHT_SAT_STEP); - rgblight_sethsv_eeprom_helper(rgblight_config.hue, sat, rgblight_config.val, write_to_eeprom); -} -void rgblight_decrease_sat_noeeprom(void) { - rgblight_decrease_sat_helper(false); -} -void rgblight_decrease_sat(void) { - rgblight_decrease_sat_helper(true); -} -void rgblight_increase_val_helper(bool write_to_eeprom) { - uint8_t val = qadd8(rgblight_config.val, RGBLIGHT_VAL_STEP); - rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom); -} -void rgblight_increase_val_noeeprom(void) { - rgblight_increase_val_helper(false); -} -void rgblight_increase_val(void) { - rgblight_increase_val_helper(true); -} -void rgblight_decrease_val_helper(bool write_to_eeprom) { - uint8_t val = qsub8(rgblight_config.val, RGBLIGHT_VAL_STEP); - rgblight_sethsv_eeprom_helper(rgblight_config.hue, rgblight_config.sat, val, write_to_eeprom); -} -void rgblight_decrease_val_noeeprom(void) { - rgblight_decrease_val_helper(false); -} -void rgblight_decrease_val(void) { - rgblight_decrease_val_helper(true); -} - -void rgblight_increase_speed_helper(bool write_to_eeprom) { - if (rgblight_config.speed < 3) rgblight_config.speed++; - // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED? - if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); - } -} -void rgblight_increase_speed(void) { - rgblight_increase_speed_helper(true); -} -void rgblight_increase_speed_noeeprom(void) { - rgblight_increase_speed_helper(false); -} - -void rgblight_decrease_speed_helper(bool write_to_eeprom) { - if (rgblight_config.speed > 0) rgblight_config.speed--; - // RGBLIGHT_SPLIT_SET_CHANGE_HSVS; // NEED?? - if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); - } -} -void rgblight_decrease_speed(void) { - rgblight_decrease_speed_helper(true); -} -void rgblight_decrease_speed_noeeprom(void) { - rgblight_decrease_speed_helper(false); -} - -void rgblight_sethsv_noeeprom_old(uint8_t hue, uint8_t sat, uint8_t val) { - if (rgblight_config.enable) { - LED_TYPE tmp_led; - sethsv(hue, sat, val, &tmp_led); - rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); - } -} - -void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom) { - if (rgblight_config.enable) { -#ifdef RGBLIGHT_SPLIT - if (rgblight_config.hue != hue || rgblight_config.sat != sat || rgblight_config.val != val) { - RGBLIGHT_SPLIT_SET_CHANGE_HSVS; - } -#endif - rgblight_status.base_mode = mode_base_table[rgblight_config.mode]; - if (rgblight_config.mode == RGBLIGHT_MODE_STATIC_LIGHT) { - // same static color - LED_TYPE tmp_led; -#ifdef RGBLIGHT_LAYERS_RETAIN_VAL - // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val - rgblight_config.val = val; -#endif - sethsv(hue, sat, val, &tmp_led); - rgblight_setrgb(tmp_led.r, tmp_led.g, tmp_led.b); - } else { - // all LEDs in same color - if (1 == 0) { // dummy - } -#ifdef RGBLIGHT_EFFECT_BREATHING - else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) { - // breathing mode, ignore the change of val, use in memory value instead - val = rgblight_config.val; - } -#endif -#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD - else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) { - // rainbow mood, ignore the change of hue - hue = rgblight_config.hue; - } -#endif -#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL - else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) { - // rainbow swirl, ignore the change of hue - hue = rgblight_config.hue; - } -#endif -#ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT - else if (rgblight_status.base_mode == RGBLIGHT_MODE_STATIC_GRADIENT) { - // static gradient - uint8_t delta = rgblight_config.mode - rgblight_status.base_mode; - bool direction = (delta % 2) == 0; - - uint8_t range = pgm_read_byte(&RGBLED_GRADIENT_RANGES[delta / 2]); - for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) { - uint8_t _hue = ((uint16_t)i * (uint16_t)range) / rgblight_ranges.effect_num_leds; - if (direction) { - _hue = hue + _hue; - } else { - _hue = hue - _hue; - } - dprintf("rgblight rainbow set hsv: %d,%d,%d,%u\n", i, _hue, direction, range); - sethsv(_hue, sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); - } -# ifdef RGBLIGHT_LAYERS_RETAIN_VAL - // needed for rgblight_layers_write() to get the new val, since it reads rgblight_config.val - rgblight_config.val = val; -# endif - rgblight_set(); - } -#endif - } - rgblight_config.hue = hue; - rgblight_config.sat = sat; - rgblight_config.val = val; - if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight set hsv [EEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - } else { - dprintf("rgblight set hsv [NOEEPROM]: %u,%u,%u\n", rgblight_config.hue, rgblight_config.sat, rgblight_config.val); - } - } -} - -void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val) { - rgblight_sethsv_eeprom_helper(hue, sat, val, true); -} - -void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val) { - rgblight_sethsv_eeprom_helper(hue, sat, val, false); -} - -uint8_t rgblight_get_speed(void) { - return rgblight_config.speed; -} - -void rgblight_set_speed_eeprom_helper(uint8_t speed, bool write_to_eeprom) { - rgblight_config.speed = speed; - if (write_to_eeprom) { - eeconfig_update_rgblight(rgblight_config.raw); - dprintf("rgblight set speed [EEPROM]: %u\n", rgblight_config.speed); - } else { - dprintf("rgblight set speed [NOEEPROM]: %u\n", rgblight_config.speed); - } -} - -void rgblight_set_speed(uint8_t speed) { - rgblight_set_speed_eeprom_helper(speed, true); -} - -void rgblight_set_speed_noeeprom(uint8_t speed) { - rgblight_set_speed_eeprom_helper(speed, false); -} - -uint8_t rgblight_get_hue(void) { - return rgblight_config.hue; -} - -uint8_t rgblight_get_sat(void) { - return rgblight_config.sat; -} - -uint8_t rgblight_get_val(void) { - return rgblight_config.val; -} - -HSV rgblight_get_hsv(void) { - return (HSV){rgblight_config.hue, rgblight_config.sat, rgblight_config.val}; -} - -void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b) { - if (!rgblight_config.enable) { - return; - } - - for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { - led[i].r = r; - led[i].g = g; - led[i].b = b; -#ifdef RGBW - led[i].w = 0; -#endif - } - rgblight_set(); -} - -void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index) { - if (!rgblight_config.enable || index >= RGBLED_NUM) { - return; - } - - led[index].r = r; - led[index].g = g; - led[index].b = b; -#ifdef RGBW - led[index].w = 0; -#endif - rgblight_set(); -} - -void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index) { - if (!rgblight_config.enable) { - return; - } - - LED_TYPE tmp_led; - sethsv(hue, sat, val, &tmp_led); - rgblight_setrgb_at(tmp_led.r, tmp_led.g, tmp_led.b, index); -} - -#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) || defined(RGBLIGHT_EFFECT_SNAKE) || defined(RGBLIGHT_EFFECT_KNIGHT) || defined(RGBLIGHT_EFFECT_TWINKLE) - -static uint8_t get_interval_time(const uint8_t *default_interval_address, uint8_t velocikey_min, uint8_t velocikey_max) { - return -# ifdef VELOCIKEY_ENABLE - velocikey_enabled() ? velocikey_match_speed(velocikey_min, velocikey_max) : -# endif - pgm_read_byte(default_interval_address); -} - -#endif - -void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end) { - if (!rgblight_config.enable || start < 0 || start >= end || end > RGBLED_NUM) { - return; - } - - for (uint8_t i = start; i < end; i++) { - led[i].r = r; - led[i].g = g; - led[i].b = b; -#ifdef RGBW - led[i].w = 0; -#endif - } - rgblight_set(); -} - -void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end) { - if (!rgblight_config.enable) { - return; - } - - LED_TYPE tmp_led; - sethsv(hue, sat, val, &tmp_led); - rgblight_setrgb_range(tmp_led.r, tmp_led.g, tmp_led.b, start, end); -} - -#ifndef RGBLIGHT_SPLIT -void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b) { - rgblight_setrgb_range(r, g, b, 0, (uint8_t)RGBLED_NUM / 2); -} - -void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b) { - rgblight_setrgb_range(r, g, b, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM); -} - -void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val) { - rgblight_sethsv_range(hue, sat, val, 0, (uint8_t)RGBLED_NUM / 2); -} - -void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val) { - rgblight_sethsv_range(hue, sat, val, (uint8_t)RGBLED_NUM / 2, (uint8_t)RGBLED_NUM); -} -#endif // ifndef RGBLIGHT_SPLIT - -#ifdef RGBLIGHT_LAYERS -void rgblight_set_layer_state(uint8_t layer, bool enabled) { - rgblight_layer_mask_t mask = (rgblight_layer_mask_t)1 << layer; - if (enabled) { - rgblight_status.enabled_layer_mask |= mask; - } else { - rgblight_status.enabled_layer_mask &= ~mask; - } - RGBLIGHT_SPLIT_SET_CHANGE_LAYERS; - - // Calling rgblight_set() here (directly or indirectly) could - // potentially cause timing issues when there are multiple - // successive calls to rgblight_set_layer_state(). Instead, - // set a flag and do it the next time rgblight_task() runs. - - deferred_set_layer_state = true; -} - -bool rgblight_get_layer_state(uint8_t layer) { - rgblight_layer_mask_t mask = (rgblight_layer_mask_t)1 << layer; - return (rgblight_status.enabled_layer_mask & mask) != 0; -} - -// Write any enabled LED layers into the buffer -static void rgblight_layers_write(void) { -# ifdef RGBLIGHT_LAYERS_RETAIN_VAL - uint8_t current_val = rgblight_get_val(); -# endif - uint8_t i = 0; - // For each layer - for (const rgblight_segment_t *const *layer_ptr = rgblight_layers; i < RGBLIGHT_MAX_LAYERS; layer_ptr++, i++) { - if (!rgblight_get_layer_state(i)) { - continue; // Layer is disabled - } - const rgblight_segment_t *segment_ptr = pgm_read_ptr(layer_ptr); - if (segment_ptr == NULL) { - break; // No more layers - } - // For each segment - while (1) { - rgblight_segment_t segment; - memcpy_P(&segment, segment_ptr, sizeof(rgblight_segment_t)); - if (segment.index == RGBLIGHT_END_SEGMENT_INDEX) { - break; // No more segments - } - // Write segment.count LEDs - LED_TYPE *const limit = &led[MIN(segment.index + segment.count, RGBLED_NUM)]; - for (LED_TYPE *led_ptr = &led[segment.index]; led_ptr < limit; led_ptr++) { -# ifdef RGBLIGHT_LAYERS_RETAIN_VAL - sethsv(segment.hue, segment.sat, current_val, led_ptr); -# else - sethsv(segment.hue, segment.sat, segment.val, led_ptr); -# endif - } - segment_ptr++; - } - } -} - -# ifdef RGBLIGHT_LAYER_BLINK -rgblight_layer_mask_t _blinking_layer_mask = 0; -static uint16_t _repeat_timer; -static uint8_t _times_remaining; -static uint16_t _dur; - -void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) { - rgblight_blink_layer_repeat(layer, duration_ms, 1); -} - -void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times) { - if (times > UINT8_MAX / 2) { - times = UINT8_MAX / 2; - } - - _times_remaining = times * 2; - _dur = duration_ms; - - rgblight_set_layer_state(layer, true); - _times_remaining--; - _blinking_layer_mask |= (rgblight_layer_mask_t)1 << layer; - _repeat_timer = sync_timer_read() + duration_ms; -} - -void rgblight_unblink_layer(uint8_t layer) { - rgblight_set_layer_state(layer, false); - _blinking_layer_mask &= ~((rgblight_layer_mask_t)1 << layer); -} - -void rgblight_unblink_all_but_layer(uint8_t layer) { - for (uint8_t i = 0; i < RGBLIGHT_MAX_LAYERS; i++) { - if (i != layer) { - if ((_blinking_layer_mask & (rgblight_layer_mask_t)1 << i) != 0) { - rgblight_unblink_layer(i); - } - } - } -} - -void rgblight_blink_layer_repeat_helper(void) { - if (_blinking_layer_mask != 0 && timer_expired(sync_timer_read(), _repeat_timer)) { - for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) { - if ((_blinking_layer_mask & (rgblight_layer_mask_t)1 << layer) != 0) { - if (_times_remaining % 2 == 1) { - rgblight_set_layer_state(layer, false); - } else { - rgblight_set_layer_state(layer, true); - } - } - } - _times_remaining--; - if (_times_remaining <= 0) { - _blinking_layer_mask = 0; - } else { - _repeat_timer = sync_timer_read() + _dur; - } - } -} -# endif - -#endif - -#ifdef RGBLIGHT_SLEEP - -void rgblight_suspend(void) { - rgblight_timer_disable(); - if (!is_suspended) { - is_suspended = true; - pre_suspend_enabled = rgblight_config.enable; - -# ifdef RGBLIGHT_LAYER_BLINK - // make sure any layer blinks don't come back after suspend - rgblight_status.enabled_layer_mask &= ~_blinking_layer_mask; - _blinking_layer_mask = 0; -# endif - - rgblight_disable_noeeprom(); - } -} - -void rgblight_wakeup(void) { - is_suspended = false; - - if (pre_suspend_enabled) { - rgblight_enable_noeeprom(); - } -# ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF - // Need this or else the LEDs won't be set - else if (rgblight_status.enabled_layer_mask != 0) { - rgblight_set(); - } -# endif - - rgblight_timer_enable(); -} - -#endif - -__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { - ws2812_setleds(start_led, num_leds); -} - -#ifndef RGBLIGHT_CUSTOM_DRIVER - -void rgblight_set(void) { - LED_TYPE *start_led; - uint8_t num_leds = rgblight_ranges.clipping_num_leds; - - if (!rgblight_config.enable) { - for (uint8_t i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { - led[i].r = 0; - led[i].g = 0; - led[i].b = 0; -# ifdef RGBW - led[i].w = 0; -# endif - } - } - -# ifdef RGBLIGHT_LAYERS - if (rgblight_layers != NULL -# if !defined(RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF) - && rgblight_config.enable -# elif defined(RGBLIGHT_SLEEP) - && !is_suspended -# endif - ) { - rgblight_layers_write(); - } -# endif - -# ifdef RGBLIGHT_LED_MAP - LED_TYPE led0[RGBLED_NUM]; - for (uint8_t i = 0; i < RGBLED_NUM; i++) { - led0[i] = led[pgm_read_byte(&led_map[i])]; - } - start_led = led0 + rgblight_ranges.clipping_start_pos; -# else - start_led = led + rgblight_ranges.clipping_start_pos; -# endif - -# ifdef RGBW - for (uint8_t i = 0; i < num_leds; i++) { - convert_rgb_to_rgbw(&start_led[i]); - } -# endif - rgblight_call_driver(start_led, num_leds); -} -#endif - -#ifdef RGBLIGHT_SPLIT -/* for split keyboard master side */ -uint8_t rgblight_get_change_flags(void) { - return rgblight_status.change_flags; -} - -void rgblight_clear_change_flags(void) { - rgblight_status.change_flags = 0; -} - -void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo) { - syncinfo->config = rgblight_config; - syncinfo->status = rgblight_status; -} - -/* for split keyboard slave side */ -void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom) { -# ifdef RGBLIGHT_LAYERS - if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_LAYERS) { - rgblight_status.enabled_layer_mask = syncinfo->status.enabled_layer_mask; - } -# endif - if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_MODE) { - if (syncinfo->config.enable) { - rgblight_config.enable = 1; // == rgblight_enable_noeeprom(); - rgblight_mode_eeprom_helper(syncinfo->config.mode, write_to_eeprom); - } else { - rgblight_disable_noeeprom(); - } - } - if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_HSVS) { - rgblight_sethsv_eeprom_helper(syncinfo->config.hue, syncinfo->config.sat, syncinfo->config.val, write_to_eeprom); - // rgblight_config.speed = config->speed; // NEED??? - } -# ifdef RGBLIGHT_USE_TIMER - if (syncinfo->status.change_flags & RGBLIGHT_STATUS_CHANGE_TIMER) { - if (syncinfo->status.timer_enabled) { - rgblight_timer_enable(); - } else { - rgblight_timer_disable(); - } - } -# ifndef RGBLIGHT_SPLIT_NO_ANIMATION_SYNC - if (syncinfo->status.change_flags & RGBLIGHT_STATUS_ANIMATION_TICK) { - animation_status.restart = true; - } -# endif /* RGBLIGHT_SPLIT_NO_ANIMATION_SYNC */ -# endif /* RGBLIGHT_USE_TIMER */ -} -#endif /* RGBLIGHT_SPLIT */ - -#ifdef RGBLIGHT_USE_TIMER - -typedef void (*effect_func_t)(animation_status_t *anim); - -// Animation timer -- use system timer (AVR Timer0) -void rgblight_timer_init(void) { - rgblight_status.timer_enabled = false; - RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; -} -void rgblight_timer_enable(void) { - if (!is_static_effect(rgblight_config.mode)) { - rgblight_status.timer_enabled = true; - } - animation_status.last_timer = sync_timer_read(); - RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; - dprintf("rgblight timer enabled.\n"); -} -void rgblight_timer_disable(void) { - rgblight_status.timer_enabled = false; - RGBLIGHT_SPLIT_SET_CHANGE_TIMER_ENABLE; - dprintf("rgblight timer disable.\n"); -} -void rgblight_timer_toggle(void) { - dprintf("rgblight timer toggle.\n"); - if (rgblight_status.timer_enabled) { - rgblight_timer_disable(); - } else { - rgblight_timer_enable(); - } -} - -void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b) { - rgblight_enable(); - rgblight_mode(RGBLIGHT_MODE_STATIC_LIGHT); - rgblight_setrgb(r, g, b); -} - -static void rgblight_effect_dummy(animation_status_t *anim) { - // do nothing - /******** - dprintf("rgblight_task() what happened?\n"); - dprintf("is_static_effect %d\n", is_static_effect(rgblight_config.mode)); - dprintf("mode = %d, base_mode = %d, timer_enabled %d, ", - rgblight_config.mode, rgblight_status.base_mode, - rgblight_status.timer_enabled); - dprintf("last_timer = %d\n",anim->last_timer); - **/ -} - -void rgblight_task(void) { - if (rgblight_status.timer_enabled) { - effect_func_t effect_func = rgblight_effect_dummy; - uint16_t interval_time = 2000; // dummy interval - uint8_t delta = rgblight_config.mode - rgblight_status.base_mode; - animation_status.delta = delta; - - // static light mode, do nothing here - if (1 == 0) { // dummy - } -# ifdef RGBLIGHT_EFFECT_BREATHING - else if (rgblight_status.base_mode == RGBLIGHT_MODE_BREATHING) { - // breathing mode - interval_time = get_interval_time(&RGBLED_BREATHING_INTERVALS[delta], 1, 100); - effect_func = rgblight_effect_breathing; - } -# endif -# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD - else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_MOOD) { - // rainbow mood mode - interval_time = get_interval_time(&RGBLED_RAINBOW_MOOD_INTERVALS[delta], 5, 100); - effect_func = rgblight_effect_rainbow_mood; - } -# endif -# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL - else if (rgblight_status.base_mode == RGBLIGHT_MODE_RAINBOW_SWIRL) { - // rainbow swirl mode - interval_time = get_interval_time(&RGBLED_RAINBOW_SWIRL_INTERVALS[delta / 2], 1, 100); - effect_func = rgblight_effect_rainbow_swirl; - } -# endif -# ifdef RGBLIGHT_EFFECT_SNAKE - else if (rgblight_status.base_mode == RGBLIGHT_MODE_SNAKE) { - // snake mode - interval_time = get_interval_time(&RGBLED_SNAKE_INTERVALS[delta / 2], 1, 200); - effect_func = rgblight_effect_snake; - } -# endif -# ifdef RGBLIGHT_EFFECT_KNIGHT - else if (rgblight_status.base_mode == RGBLIGHT_MODE_KNIGHT) { - // knight mode - interval_time = get_interval_time(&RGBLED_KNIGHT_INTERVALS[delta], 5, 100); - effect_func = rgblight_effect_knight; - } -# endif -# ifdef RGBLIGHT_EFFECT_CHRISTMAS - else if (rgblight_status.base_mode == RGBLIGHT_MODE_CHRISTMAS) { - // christmas mode - interval_time = RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL; - effect_func = (effect_func_t)rgblight_effect_christmas; - } -# endif -# ifdef RGBLIGHT_EFFECT_RGB_TEST - else if (rgblight_status.base_mode == RGBLIGHT_MODE_RGB_TEST) { - // RGB test mode - interval_time = pgm_read_word(&RGBLED_RGBTEST_INTERVALS[0]); - effect_func = (effect_func_t)rgblight_effect_rgbtest; - } -# endif -# ifdef RGBLIGHT_EFFECT_ALTERNATING - else if (rgblight_status.base_mode == RGBLIGHT_MODE_ALTERNATING) { - interval_time = 500; - effect_func = (effect_func_t)rgblight_effect_alternating; - } -# endif -# ifdef RGBLIGHT_EFFECT_TWINKLE - else if (rgblight_status.base_mode == RGBLIGHT_MODE_TWINKLE) { - interval_time = get_interval_time(&RGBLED_TWINKLE_INTERVALS[delta % 3], 5, 30); - effect_func = (effect_func_t)rgblight_effect_twinkle; - } -# endif - if (animation_status.restart) { - animation_status.restart = false; - animation_status.last_timer = sync_timer_read(); - animation_status.pos16 = 0; // restart signal to local each effect - } - uint16_t now = sync_timer_read(); - if (timer_expired(now, animation_status.last_timer)) { -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - static uint16_t report_last_timer = 0; - static bool tick_flag = false; - uint16_t oldpos16; - if (tick_flag) { - tick_flag = false; - if (timer_expired(now, report_last_timer)) { - report_last_timer += 30000; - dprintf("rgblight animation tick report to slave\n"); - RGBLIGHT_SPLIT_ANIMATION_TICK; - } - } - oldpos16 = animation_status.pos16; -# endif - animation_status.last_timer += interval_time; - effect_func(&animation_status); -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - if (animation_status.pos16 == 0 && oldpos16 != 0) { - tick_flag = true; - } -# endif - } - } - -# ifdef RGBLIGHT_LAYERS -# ifdef RGBLIGHT_LAYER_BLINK - rgblight_blink_layer_repeat_helper(); -# endif - - if (deferred_set_layer_state) { - deferred_set_layer_state = false; - - // Static modes don't have a ticker running to update the LEDs - if (rgblight_status.timer_enabled == false) { - rgblight_mode_noeeprom(rgblight_config.mode); - } - -# ifdef RGBLIGHT_LAYERS_OVERRIDE_RGB_OFF - // If not enabled, then nothing else will actually set the LEDs... - if (!rgblight_config.enable) { - rgblight_set(); - } -# endif - } -# endif -} - -#endif /* RGBLIGHT_USE_TIMER */ - -#if defined(RGBLIGHT_EFFECT_BREATHING) || defined(RGBLIGHT_EFFECT_TWINKLE) - -# ifndef RGBLIGHT_EFFECT_BREATHE_CENTER -# ifndef RGBLIGHT_BREATHE_TABLE_SIZE -# define RGBLIGHT_BREATHE_TABLE_SIZE 256 // 256 or 128 or 64 -# endif -# include -# endif - -static uint8_t breathe_calc(uint8_t pos) { - // http://sean.voisen.org/blog/2011/10/breathing-led-with-arduino/ -# ifdef RGBLIGHT_EFFECT_BREATHE_TABLE - return pgm_read_byte(&rgblight_effect_breathe_table[pos / table_scale]); -# else - return (exp(sin((pos / 255.0) * M_PI)) - RGBLIGHT_EFFECT_BREATHE_CENTER / M_E) * (RGBLIGHT_EFFECT_BREATHE_MAX / (M_E - 1 / M_E)); -# endif -} - -#endif - -// Effects -#ifdef RGBLIGHT_EFFECT_BREATHING - -__attribute__((weak)) const uint8_t RGBLED_BREATHING_INTERVALS[] PROGMEM = {30, 20, 10, 5}; - -void rgblight_effect_breathing(animation_status_t *anim) { - uint8_t val = breathe_calc(anim->pos); - rgblight_sethsv_noeeprom_old(rgblight_config.hue, rgblight_config.sat, val); - anim->pos = (anim->pos + 1); -} -#endif - -#ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD -__attribute__((weak)) const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[] PROGMEM = {120, 60, 30}; - -void rgblight_effect_rainbow_mood(animation_status_t *anim) { - rgblight_sethsv_noeeprom_old(anim->current_hue, rgblight_config.sat, rgblight_config.val); - anim->current_hue++; -} -#endif - -#ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL -# ifndef RGBLIGHT_RAINBOW_SWIRL_RANGE -# define RGBLIGHT_RAINBOW_SWIRL_RANGE 255 -# endif - -__attribute__((weak)) const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[] PROGMEM = {100, 50, 20}; - -void rgblight_effect_rainbow_swirl(animation_status_t *anim) { - uint8_t hue; - uint8_t i; - - for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { - hue = (RGBLIGHT_RAINBOW_SWIRL_RANGE / rgblight_ranges.effect_num_leds * i + anim->current_hue); - sethsv(hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); - } - rgblight_set(); - - if (anim->delta % 2) { - anim->current_hue++; - } else { - anim->current_hue--; - } -} -#endif - -#ifdef RGBLIGHT_EFFECT_SNAKE -__attribute__((weak)) const uint8_t RGBLED_SNAKE_INTERVALS[] PROGMEM = {100, 50, 20}; - -void rgblight_effect_snake(animation_status_t *anim) { - static uint8_t pos = 0; - uint8_t i, j; - int8_t k; - int8_t increment = 1; - - if (anim->delta % 2) { - increment = -1; - } - -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - if (anim->pos == 0) { // restart signal - if (increment == 1) { - pos = rgblight_ranges.effect_num_leds - 1; - } else { - pos = 0; - } - anim->pos = 1; - } -# endif - - for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { - LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; - ledp->r = 0; - ledp->g = 0; - ledp->b = 0; -# ifdef RGBW - ledp->w = 0; -# endif - for (j = 0; j < RGBLIGHT_EFFECT_SNAKE_LENGTH; j++) { - k = pos + j * increment; - if (k > RGBLED_NUM) { - k = k % RGBLED_NUM; - } - if (k < 0) { - k = k + rgblight_ranges.effect_num_leds; - } - if (i == k) { - sethsv(rgblight_config.hue, rgblight_config.sat, (uint8_t)(rgblight_config.val * (RGBLIGHT_EFFECT_SNAKE_LENGTH - j) / RGBLIGHT_EFFECT_SNAKE_LENGTH), ledp); - } - } - } - rgblight_set(); - if (increment == 1) { - if (pos - RGBLIGHT_EFFECT_SNAKE_INCREMENT < 0) { - pos = rgblight_ranges.effect_num_leds - 1; -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - anim->pos = 0; -# endif - } else { - pos -= RGBLIGHT_EFFECT_SNAKE_INCREMENT; -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - anim->pos = 1; -# endif - } - } else { - pos = (pos + RGBLIGHT_EFFECT_SNAKE_INCREMENT) % rgblight_ranges.effect_num_leds; -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - anim->pos = pos; -# endif - } -} -#endif - -#ifdef RGBLIGHT_EFFECT_KNIGHT -__attribute__((weak)) const uint8_t RGBLED_KNIGHT_INTERVALS[] PROGMEM = {127, 63, 31}; - -void rgblight_effect_knight(animation_status_t *anim) { - static int8_t low_bound = 0; - static int8_t high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; - static int8_t increment = RGBLIGHT_EFFECT_KNIGHT_INCREMENT; - uint8_t i, cur; - -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - if (anim->pos == 0) { // restart signal - anim->pos = 1; - low_bound = 0; - high_bound = RGBLIGHT_EFFECT_KNIGHT_LENGTH - 1; - increment = 1; - } -# endif - // Set all the LEDs to 0 - for (i = rgblight_ranges.effect_start_pos; i < rgblight_ranges.effect_end_pos; i++) { - led[i].r = 0; - led[i].g = 0; - led[i].b = 0; -# ifdef RGBW - led[i].w = 0; -# endif - } - // Determine which LEDs should be lit up - for (i = 0; i < RGBLIGHT_EFFECT_KNIGHT_LED_NUM; i++) { - cur = (i + RGBLIGHT_EFFECT_KNIGHT_OFFSET) % rgblight_ranges.effect_num_leds + rgblight_ranges.effect_start_pos; - - if (i >= low_bound && i <= high_bound) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, (LED_TYPE *)&led[cur]); - } else { - led[cur].r = 0; - led[cur].g = 0; - led[cur].b = 0; -# ifdef RGBW - led[cur].w = 0; -# endif - } - } - rgblight_set(); - - // Move from low_bound to high_bound changing the direction we increment each - // time a boundary is hit. - low_bound += increment; - high_bound += increment; - - if (high_bound <= 0 || low_bound >= RGBLIGHT_EFFECT_KNIGHT_LED_NUM - 1) { - increment = -increment; -# if defined(RGBLIGHT_SPLIT) && !defined(RGBLIGHT_SPLIT_NO_ANIMATION_SYNC) - if (increment == 1) { - anim->pos = 0; - } -# endif - } -} -#endif - -#ifdef RGBLIGHT_EFFECT_CHRISTMAS -# define CUBED(x) ((x) * (x) * (x)) - -/** - * Christmas lights effect, with a smooth animation between red & green. - */ -void rgblight_effect_christmas(animation_status_t *anim) { - static int8_t increment = 1; - const uint8_t max_pos = 32; - const uint8_t hue_green = 85; - - uint32_t xa; - uint8_t hue, val; - uint8_t i; - - // The effect works by animating anim->pos from 0 to 32 and back to 0. - // The pos is used in a cubic bezier formula to ease-in-out between red and green, leaving the interpolated colors visible as short as possible. - xa = CUBED((uint32_t)anim->pos); - hue = ((uint32_t)hue_green) * xa / (xa + CUBED((uint32_t)(max_pos - anim->pos))); - // Additionally, these interpolated colors get shown with a slightly darker value, to make them less prominent than the main colors. - val = 255 - (3 * (hue < hue_green / 2 ? hue : hue_green - hue) / 2); - - for (i = 0; i < rgblight_ranges.effect_num_leds; i++) { - uint8_t local_hue = (i / RGBLIGHT_EFFECT_CHRISTMAS_STEP) % 2 ? hue : hue_green - hue; - sethsv(local_hue, rgblight_config.sat, val, (LED_TYPE *)&led[i + rgblight_ranges.effect_start_pos]); - } - rgblight_set(); - - if (anim->pos == 0) { - increment = 1; - } else if (anim->pos == max_pos) { - increment = -1; - } - anim->pos += increment; -} -#endif - -#ifdef RGBLIGHT_EFFECT_RGB_TEST -__attribute__((weak)) const uint16_t RGBLED_RGBTEST_INTERVALS[] PROGMEM = {1024}; - -void rgblight_effect_rgbtest(animation_status_t *anim) { - static uint8_t maxval = 0; - uint8_t g; - uint8_t r; - uint8_t b; - - if (maxval == 0) { - LED_TYPE tmp_led; - sethsv(0, 255, RGBLIGHT_LIMIT_VAL, &tmp_led); - maxval = tmp_led.r; - } - g = r = b = 0; - switch (anim->pos) { - case 0: - r = maxval; - break; - case 1: - g = maxval; - break; - case 2: - b = maxval; - break; - } - rgblight_setrgb(r, g, b); - anim->pos = (anim->pos + 1) % 3; -} -#endif - -#ifdef RGBLIGHT_EFFECT_ALTERNATING -void rgblight_effect_alternating(animation_status_t *anim) { - for (int i = 0; i < rgblight_ranges.effect_num_leds; i++) { - LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; - if (i < rgblight_ranges.effect_num_leds / 2 && anim->pos) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); - } else if (i >= rgblight_ranges.effect_num_leds / 2 && !anim->pos) { - sethsv(rgblight_config.hue, rgblight_config.sat, rgblight_config.val, ledp); - } else { - sethsv(rgblight_config.hue, rgblight_config.sat, 0, ledp); - } - } - rgblight_set(); - anim->pos = (anim->pos + 1) % 2; -} -#endif - -#ifdef RGBLIGHT_EFFECT_TWINKLE -__attribute__((weak)) const uint8_t RGBLED_TWINKLE_INTERVALS[] PROGMEM = {30, 15, 5}; - -typedef struct PACKED { - HSV hsv; - uint8_t life; - uint8_t max_life; -} TwinkleState; - -static TwinkleState led_twinkle_state[RGBLED_NUM]; - -void rgblight_effect_twinkle(animation_status_t *anim) { - const bool random_color = anim->delta / 3; - const bool restart = anim->pos == 0; - anim->pos = 1; - - const uint8_t bottom = breathe_calc(0); - const uint8_t top = breathe_calc(127); - - uint8_t frac(uint8_t n, uint8_t d) { - return (uint16_t)255 * n / d; - } - uint8_t scale(uint16_t v, uint8_t scale) { - return (v * scale) >> 8; - } - - const uint8_t trigger = scale((uint16_t)0xFF * RGBLIGHT_EFFECT_TWINKLE_PROBABILITY, 127 + rgblight_config.val / 2); - - for (uint8_t i = 0; i < rgblight_ranges.effect_num_leds; i++) { - TwinkleState *t = &(led_twinkle_state[i]); - HSV * c = &(t->hsv); - - if (!random_color) { - c->h = rgblight_config.hue; - c->s = rgblight_config.sat; - } - - if (restart) { - // Restart - t->life = 0; - c->v = 0; - } else if (t->life) { - // This LED is already on, either brightening or dimming - t->life--; - uint8_t unscaled = frac(breathe_calc(frac(t->life, t->max_life)) - bottom, top - bottom); - c->v = scale(rgblight_config.val, unscaled); - } else if ((rand() % 0xFF) < trigger) { - // This LED is off, but was randomly selected to start brightening - if (random_color) { - c->h = rand() % 0xFF; - c->s = (rand() % (rgblight_config.sat / 2)) + (rgblight_config.sat / 2); - } - c->v = 0; - t->max_life = MAX(20, MIN(RGBLIGHT_EFFECT_TWINKLE_LIFE, rgblight_config.val)); - t->life = t->max_life; - } else { - // This LED is off, and was NOT selected to start brightening - } - - LED_TYPE *ledp = led + i + rgblight_ranges.effect_start_pos; - sethsv(c->h, c->s, c->v, ledp); - } - - rgblight_set(); -} -#endif diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h deleted file mode 100644 index 001058f96230..000000000000 --- a/quantum/rgblight/rgblight.h +++ /dev/null @@ -1,448 +0,0 @@ -/* Copyright 2017 Yang Liu - * - * 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 . - */ - -#pragma once - -/***** rgblight_mode(mode)/rgblight_mode_noeeprom(mode) **** - - old mode number (before 0.6.117) to new mode name table - -|-----------------|-----------------------------------| -| old mode number | new mode name | -|-----------------|-----------------------------------| -| 1 | RGBLIGHT_MODE_STATIC_LIGHT | -| 2 | RGBLIGHT_MODE_BREATHING | -| 3 | RGBLIGHT_MODE_BREATHING + 1 | -| 4 | RGBLIGHT_MODE_BREATHING + 2 | -| 5 | RGBLIGHT_MODE_BREATHING + 3 | -| 6 | RGBLIGHT_MODE_RAINBOW_MOOD | -| 7 | RGBLIGHT_MODE_RAINBOW_MOOD + 1 | -| 8 | RGBLIGHT_MODE_RAINBOW_MOOD + 2 | -| 9 | RGBLIGHT_MODE_RAINBOW_SWIRL | -| 10 | RGBLIGHT_MODE_RAINBOW_SWIRL + 1 | -| 11 | RGBLIGHT_MODE_RAINBOW_SWIRL + 2 | -| 12 | RGBLIGHT_MODE_RAINBOW_SWIRL + 3 | -| 13 | RGBLIGHT_MODE_RAINBOW_SWIRL + 4 | -| 14 | RGBLIGHT_MODE_RAINBOW_SWIRL + 5 | -| 15 | RGBLIGHT_MODE_SNAKE | -| 16 | RGBLIGHT_MODE_SNAKE + 1 | -| 17 | RGBLIGHT_MODE_SNAKE + 2 | -| 18 | RGBLIGHT_MODE_SNAKE + 3 | -| 19 | RGBLIGHT_MODE_SNAKE + 4 | -| 20 | RGBLIGHT_MODE_SNAKE + 5 | -| 21 | RGBLIGHT_MODE_KNIGHT | -| 22 | RGBLIGHT_MODE_KNIGHT + 1 | -| 23 | RGBLIGHT_MODE_KNIGHT + 2 | -| 24 | RGBLIGHT_MODE_CHRISTMAS | -| 25 | RGBLIGHT_MODE_STATIC_GRADIENT | -| 26 | RGBLIGHT_MODE_STATIC_GRADIENT + 1 | -| 27 | RGBLIGHT_MODE_STATIC_GRADIENT + 2 | -| 28 | RGBLIGHT_MODE_STATIC_GRADIENT + 3 | -| 29 | RGBLIGHT_MODE_STATIC_GRADIENT + 4 | -| 30 | RGBLIGHT_MODE_STATIC_GRADIENT + 5 | -| 31 | RGBLIGHT_MODE_STATIC_GRADIENT + 6 | -| 32 | RGBLIGHT_MODE_STATIC_GRADIENT + 7 | -| 33 | RGBLIGHT_MODE_STATIC_GRADIENT + 8 | -| 34 | RGBLIGHT_MODE_STATIC_GRADIENT + 9 | -| 35 | RGBLIGHT_MODE_RGB_TEST | -| 36 | RGBLIGHT_MODE_ALTERNATING | -| 37 | RGBLIGHT_MODE_TWINKLE | -| 38 | RGBLIGHT_MODE_TWINKLE + 1 | -| 39 | RGBLIGHT_MODE_TWINKLE + 2 | -| 40 | RGBLIGHT_MODE_TWINKLE + 3 | -| 41 | RGBLIGHT_MODE_TWINKLE + 4 | -| 42 | RGBLIGHT_MODE_TWINKLE + 5 | -|-----------------|-----------------------------------| - *****/ - -// clang-format off - -// check dynamic animation effects chose ? -#if defined(RGBLIGHT_EFFECT_BREATHING) \ - || defined(RGBLIGHT_EFFECT_RAINBOW_MOOD) \ - || defined(RGBLIGHT_EFFECT_RAINBOW_SWIRL) \ - || defined(RGBLIGHT_EFFECT_SNAKE) \ - || defined(RGBLIGHT_EFFECT_KNIGHT) \ - || defined(RGBLIGHT_EFFECT_CHRISTMAS) \ - || defined(RGBLIGHT_EFFECT_RGB_TEST) \ - || defined(RGBLIGHT_EFFECT_ALTERNATING) \ - || defined(RGBLIGHT_EFFECT_TWINKLE) -# define RGBLIGHT_USE_TIMER -#endif - -// clang-format on - -#define _RGBM_SINGLE_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_SINGLE_DYNAMIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_MULTI_STATIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_MULTI_DYNAMIC(sym) RGBLIGHT_MODE_##sym, -#define _RGBM_TMP_STATIC(sym, msym) RGBLIGHT_MODE_##sym, -#define _RGBM_TMP_DYNAMIC(sym, msym) RGBLIGHT_MODE_##sym, -enum RGBLIGHT_EFFECT_MODE { - RGBLIGHT_MODE_zero = 0, -#include "rgblight_modes.h" - RGBLIGHT_MODE_last -}; - -#define RGBLIGHT_MODES (RGBLIGHT_MODE_last - 1) - -// sample: #define RGBLIGHT_EFFECT_BREATHE_CENTER 1.85 - -#ifndef RGBLIGHT_EFFECT_BREATHE_MAX -# define RGBLIGHT_EFFECT_BREATHE_MAX 255 // 0-255 -#endif - -#ifndef RGBLIGHT_EFFECT_SNAKE_LENGTH -# define RGBLIGHT_EFFECT_SNAKE_LENGTH 4 -#endif - -#ifndef RGBLIGHT_EFFECT_SNAKE_INCREMENT -# define RGBLIGHT_EFFECT_SNAKE_INCREMENT 1 -#endif - -#ifndef RGBLIGHT_EFFECT_KNIGHT_LENGTH -# define RGBLIGHT_EFFECT_KNIGHT_LENGTH 3 -#endif - -#ifndef RGBLIGHT_EFFECT_KNIGHT_INCREMENT -# define RGBLIGHT_EFFECT_KNIGHT_INCREMENT 1 -#endif - -#ifndef RGBLIGHT_EFFECT_KNIGHT_OFFSET -# define RGBLIGHT_EFFECT_KNIGHT_OFFSET 0 -#endif - -#ifndef RGBLIGHT_EFFECT_KNIGHT_LED_NUM -# define RGBLIGHT_EFFECT_KNIGHT_LED_NUM (rgblight_ranges.effect_num_leds) -#endif - -#ifndef RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL -# define RGBLIGHT_EFFECT_CHRISTMAS_INTERVAL 40 -#endif - -#ifndef RGBLIGHT_EFFECT_CHRISTMAS_STEP -# define RGBLIGHT_EFFECT_CHRISTMAS_STEP 2 -#endif - -#ifndef RGBLIGHT_EFFECT_TWINKLE_LIFE -# define RGBLIGHT_EFFECT_TWINKLE_LIFE 200 -#endif - -#ifndef RGBLIGHT_EFFECT_TWINKLE_PROBABILITY -# define RGBLIGHT_EFFECT_TWINKLE_PROBABILITY 1 / 127 -#endif - -#ifndef RGBLIGHT_HUE_STEP -# define RGBLIGHT_HUE_STEP 8 -#endif -#ifndef RGBLIGHT_SAT_STEP -# define RGBLIGHT_SAT_STEP 17 -#endif -#ifndef RGBLIGHT_VAL_STEP -# define RGBLIGHT_VAL_STEP 17 -#endif -#ifndef RGBLIGHT_LIMIT_VAL -# define RGBLIGHT_LIMIT_VAL 255 -#endif - -#include -#include -#include "progmem.h" -#include "eeconfig.h" -#include "ws2812.h" -#include "color.h" - -#ifdef RGBLIGHT_LAYERS -typedef struct { - uint8_t index; // The first LED to light - uint8_t count; // The number of LEDs to light - uint8_t hue; - uint8_t sat; - uint8_t val; -} rgblight_segment_t; - -// rgblight_set_layer_state doesn't take effect until the next time -// rgblight_task runs, so timers must be enabled for layers to work. -# define RGBLIGHT_USE_TIMER - -# define RGBLIGHT_END_SEGMENT_INDEX (255) -# define RGBLIGHT_END_SEGMENTS \ - { RGBLIGHT_END_SEGMENT_INDEX, 0, 0, 0 } -# ifndef RGBLIGHT_MAX_LAYERS -# define RGBLIGHT_MAX_LAYERS 8 -# endif -# if RGBLIGHT_MAX_LAYERS <= 0 -# error invalid RGBLIGHT_MAX_LAYERS value (must be >= 1) -# elif RGBLIGHT_MAX_LAYERS <= 8 -typedef uint8_t rgblight_layer_mask_t; -# elif RGBLIGHT_MAX_LAYERS <= 16 -typedef uint16_t rgblight_layer_mask_t; -# elif RGBLIGHT_MAX_LAYERS <= 32 -typedef uint32_t rgblight_layer_mask_t; -# else -# error invalid RGBLIGHT_MAX_LAYERS value (must be <= 32) -# endif -# define RGBLIGHT_LAYER_SEGMENTS(...) \ - { __VA_ARGS__, RGBLIGHT_END_SEGMENTS } -# define RGBLIGHT_LAYERS_LIST(...) \ - { __VA_ARGS__, NULL } - -// Get/set enabled rgblight layers -void rgblight_set_layer_state(uint8_t layer, bool enabled); -bool rgblight_get_layer_state(uint8_t layer); - -// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers -extern const rgblight_segment_t *const *rgblight_layers; - -# ifdef RGBLIGHT_LAYER_BLINK -# define RGBLIGHT_USE_TIMER -void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms); -void rgblight_blink_layer_repeat(uint8_t layer, uint16_t duration_ms, uint8_t times); -/** - * \brief Stop blinking on one layer. - * - * Stop a layer that is blinking. If the layer is not blinking it will - * be unaffected. - * - * \param layer Layer number to stop blinking. - */ -void rgblight_unblink_layer(uint8_t layer); -/** - * \brief Stop blinking all layers except one. - * - * Stop all layers that are blinking except for one specific layer. - * Layers that are not blinking are unaffected. - * - * \param layer Layer number to keep blinking. - */ -void rgblight_unblink_all_but_layer(uint8_t layer); -# endif - -#endif - -extern LED_TYPE led[RGBLED_NUM]; - -extern const uint8_t RGBLED_BREATHING_INTERVALS[4] PROGMEM; -extern const uint8_t RGBLED_RAINBOW_MOOD_INTERVALS[3] PROGMEM; -extern const uint8_t RGBLED_RAINBOW_SWIRL_INTERVALS[3] PROGMEM; -extern const uint8_t RGBLED_SNAKE_INTERVALS[3] PROGMEM; -extern const uint8_t RGBLED_KNIGHT_INTERVALS[3] PROGMEM; -extern const uint16_t RGBLED_RGBTEST_INTERVALS[1] PROGMEM; -extern const uint8_t RGBLED_TWINKLE_INTERVALS[3] PROGMEM; -extern bool is_rgblight_initialized; - -typedef union { - uint64_t raw; - struct { - bool enable : 1; - uint8_t mode : 7; - uint8_t hue : 8; - uint8_t sat : 8; - uint8_t val : 8; - uint8_t speed : 8; - }; -} rgblight_config_t; - -_Static_assert(sizeof(rgblight_config_t) == sizeof(uint64_t), "RGB Light EECONFIG out of spec."); - -typedef struct _rgblight_status_t { - uint8_t base_mode; - bool timer_enabled; -#ifdef RGBLIGHT_SPLIT - uint8_t change_flags; -#endif -#ifdef RGBLIGHT_LAYERS - rgblight_layer_mask_t enabled_layer_mask; -#endif -} rgblight_status_t; - -/* - * Structure for RGB Light clipping ranges - */ -typedef struct _rgblight_ranges_t { - uint8_t clipping_start_pos; - uint8_t clipping_num_leds; - uint8_t effect_start_pos; - uint8_t effect_end_pos; - uint8_t effect_num_leds; -} rgblight_ranges_t; - -extern rgblight_ranges_t rgblight_ranges; - -/* === Utility Functions ===*/ -void sethsv(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); -void sethsv_raw(uint8_t hue, uint8_t sat, uint8_t val, LED_TYPE *led1); // without RGBLIGHT_LIMIT_VAL check -void setrgb(uint8_t r, uint8_t g, uint8_t b, LED_TYPE *led1); - -/* === Low level Functions === */ -void rgblight_set(void); -void rgblight_set_clipping_range(uint8_t start_pos, uint8_t num_leds); - -/* === Effects and Animations Functions === */ -/* effect range setting */ -void rgblight_set_effect_range(uint8_t start_pos, uint8_t num_leds); - -/* direct operation */ -void rgblight_setrgb_at(uint8_t r, uint8_t g, uint8_t b, uint8_t index); -void rgblight_sethsv_at(uint8_t hue, uint8_t sat, uint8_t val, uint8_t index); -void rgblight_setrgb_range(uint8_t r, uint8_t g, uint8_t b, uint8_t start, uint8_t end); -void rgblight_sethsv_range(uint8_t hue, uint8_t sat, uint8_t val, uint8_t start, uint8_t end); -void rgblight_setrgb(uint8_t r, uint8_t g, uint8_t b); - -#ifndef RGBLIGHT_SPLIT -void rgblight_setrgb_master(uint8_t r, uint8_t g, uint8_t b); -void rgblight_setrgb_slave(uint8_t r, uint8_t g, uint8_t b); -void rgblight_sethsv_master(uint8_t hue, uint8_t sat, uint8_t val); -void rgblight_sethsv_slave(uint8_t hue, uint8_t sat, uint8_t val); -#endif - -/* effect mode change */ -void rgblight_mode(uint8_t mode); -void rgblight_mode_noeeprom(uint8_t mode); -void rgblight_increase(void); -void rgblight_decrease(void); -void rgblight_step(void); -void rgblight_step_noeeprom(void); -void rgblight_step_reverse(void); -void rgblight_step_reverse_noeeprom(void); - -/* effects mode disable/enable */ -void rgblight_toggle(void); -void rgblight_toggle_noeeprom(void); -void rgblight_enable(void); -void rgblight_enable_noeeprom(void); -void rgblight_disable(void); -void rgblight_disable_noeeprom(void); -void rgblight_enabled_noeeprom(bool state); - -/* hue, sat, val change */ -void rgblight_increase_hue(void); -void rgblight_increase_hue_noeeprom(void); -void rgblight_decrease_hue(void); -void rgblight_decrease_hue_noeeprom(void); -void rgblight_increase_sat(void); -void rgblight_increase_sat_noeeprom(void); -void rgblight_decrease_sat(void); -void rgblight_decrease_sat_noeeprom(void); -void rgblight_increase_val(void); -void rgblight_increase_val_noeeprom(void); -void rgblight_decrease_val(void); -void rgblight_decrease_val_noeeprom(void); -void rgblight_increase_speed(void); -void rgblight_increase_speed_noeeprom(void); -void rgblight_decrease_speed(void); -void rgblight_decrease_speed_noeeprom(void); -void rgblight_sethsv(uint8_t hue, uint8_t sat, uint8_t val); -void rgblight_sethsv_noeeprom(uint8_t hue, uint8_t sat, uint8_t val); - -/* effect speed */ -uint8_t rgblight_get_speed(void); -void rgblight_set_speed(uint8_t speed); -void rgblight_set_speed_noeeprom(uint8_t speed); - -/* reset */ -void rgblight_reload_from_eeprom(void); - -/* query */ -uint8_t rgblight_get_mode(void); -uint8_t rgblight_get_hue(void); -uint8_t rgblight_get_sat(void); -uint8_t rgblight_get_val(void); -bool rgblight_is_enabled(void); -HSV rgblight_get_hsv(void); - -/* === qmk_firmware (core)internal Functions === */ -void rgblight_init(void); -void rgblight_suspend(void); -void rgblight_wakeup(void); -uint64_t rgblight_read_qword(void); -void rgblight_update_qword(uint64_t qword); -uint64_t eeconfig_read_rgblight(void); -void eeconfig_update_rgblight(uint64_t val); -void eeconfig_update_rgblight_current(void); -void eeconfig_update_rgblight_default(void); -void eeconfig_debug_rgblight(void); - -void rgb_matrix_increase(void); -void rgb_matrix_decrease(void); - -void rgblight_sethsv_eeprom_helper(uint8_t hue, uint8_t sat, uint8_t val, bool write_to_eeprom); -void rgblight_mode_eeprom_helper(uint8_t mode, bool write_to_eeprom); - -#define EZ_RGB(val) rgblight_show_solid_color((val >> 16) & 0xFF, (val >> 8) & 0xFF, val & 0xFF) -void rgblight_show_solid_color(uint8_t r, uint8_t g, uint8_t b); - -#ifdef RGBLIGHT_USE_TIMER -void rgblight_task(void); -void rgblight_timer_init(void); -void rgblight_timer_enable(void); -void rgblight_timer_disable(void); -void rgblight_timer_toggle(void); -#else -# define rgblight_task() -# define rgblight_timer_init() -# define rgblight_timer_enable() -# define rgblight_timer_disable() -# define rgblight_timer_toggle() -#endif - -#ifdef RGBLIGHT_SPLIT -# define RGBLIGHT_STATUS_CHANGE_MODE (1 << 0) -# define RGBLIGHT_STATUS_CHANGE_HSVS (1 << 1) -# define RGBLIGHT_STATUS_CHANGE_TIMER (1 << 2) -# define RGBLIGHT_STATUS_ANIMATION_TICK (1 << 3) -# define RGBLIGHT_STATUS_CHANGE_LAYERS (1 << 4) - -typedef struct _rgblight_syncinfo_t { - rgblight_config_t config; - rgblight_status_t status; -} rgblight_syncinfo_t; - -/* for split keyboard master side */ -uint8_t rgblight_get_change_flags(void); -void rgblight_clear_change_flags(void); -void rgblight_get_syncinfo(rgblight_syncinfo_t *syncinfo); -/* for split keyboard slave side */ -void rgblight_update_sync(rgblight_syncinfo_t *syncinfo, bool write_to_eeprom); -#endif - -#ifdef RGBLIGHT_USE_TIMER - -typedef struct _animation_status_t { - uint16_t last_timer; - uint8_t delta; /* mode - base_mode */ - bool restart; - union { - uint16_t pos16; - uint8_t pos; - int8_t current_hue; - uint16_t current_offset; - }; -} animation_status_t; - -extern animation_status_t animation_status; - -void rgblight_effect_breathing(animation_status_t *anim); -void rgblight_effect_rainbow_mood(animation_status_t *anim); -void rgblight_effect_rainbow_swirl(animation_status_t *anim); -void rgblight_effect_snake(animation_status_t *anim); -void rgblight_effect_knight(animation_status_t *anim); -void rgblight_effect_christmas(animation_status_t *anim); -void rgblight_effect_rgbtest(animation_status_t *anim); -void rgblight_effect_alternating(animation_status_t *anim); -void rgblight_effect_twinkle(animation_status_t *anim); - -#endif diff --git a/quantum/rgblight/rgblight_breathe_table.h b/quantum/rgblight/rgblight_breathe_table.h deleted file mode 100644 index 5c7660ab6a62..000000000000 --- a/quantum/rgblight/rgblight_breathe_table.h +++ /dev/null @@ -1,141 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -/******************************************************************************* - 88888888888 888 d8b .d888 d8b 888 d8b - 888 888 Y8P d88P" Y8P 888 Y8P - 888 888 888 888 - 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b - 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K - 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. - 888 888 888 888 X88 888 888 888 Y8b. 888 X88 - 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' - 888 888 - 888 888 - 888 888 - .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 - d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 - 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 - Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 - "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 - 888 - Y8b d88P - "Y88P" -*******************************************************************************/ - -#pragma once -// clang-format off -#define RGBLIGHT_EFFECT_BREATHE_TABLE - -// Breathing center: 1.85 -// Breathing max: 255 - -const uint8_t PROGMEM rgblight_effect_breathe_table[] = { -#if RGBLIGHT_BREATHE_TABLE_SIZE == 256 - 0x22, 0x23, 0x25, 0x26, 0x28, 0x29, 0x2A, 0x2C, - 0x2D, 0x2F, 0x30, 0x32, 0x33, 0x35, 0x36, 0x38, - 0x3A, 0x3B, 0x3D, 0x3E, 0x40, 0x42, 0x43, 0x45, - 0x47, 0x49, 0x4A, 0x4C, 0x4E, 0x50, 0x51, 0x53, - 0x55, 0x57, 0x59, 0x5A, 0x5C, 0x5E, 0x60, 0x62, - 0x64, 0x66, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x71, - 0x73, 0x75, 0x77, 0x79, 0x7B, 0x7D, 0x7F, 0x81, - 0x83, 0x85, 0x87, 0x89, 0x8A, 0x8C, 0x8E, 0x90, - 0x92, 0x94, 0x96, 0x98, 0x9A, 0x9C, 0x9E, 0x9F, - 0xA1, 0xA3, 0xA5, 0xA7, 0xA8, 0xAA, 0xAC, 0xAE, - 0xAF, 0xB1, 0xB3, 0xB4, 0xB6, 0xB8, 0xB9, 0xBB, - 0xBC, 0xBE, 0xBF, 0xC1, 0xC2, 0xC3, 0xC5, 0xC6, - 0xC7, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xD0, - 0xD1, 0xD2, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, - 0xD7, 0xD8, 0xD9, 0xD9, 0xDA, 0xDA, 0xDB, 0xDB, - 0xDB, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDD, 0xDD, - 0xDD, 0xDD, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB, - 0xDB, 0xDB, 0xDA, 0xDA, 0xD9, 0xD9, 0xD8, 0xD7, - 0xD7, 0xD6, 0xD5, 0xD4, 0xD3, 0xD2, 0xD2, 0xD1, - 0xD0, 0xCE, 0xCD, 0xCC, 0xCB, 0xCA, 0xC9, 0xC7, - 0xC6, 0xC5, 0xC3, 0xC2, 0xC1, 0xBF, 0xBE, 0xBC, - 0xBB, 0xB9, 0xB8, 0xB6, 0xB4, 0xB3, 0xB1, 0xAF, - 0xAE, 0xAC, 0xAA, 0xA8, 0xA7, 0xA5, 0xA3, 0xA1, - 0x9F, 0x9E, 0x9C, 0x9A, 0x98, 0x96, 0x94, 0x92, - 0x90, 0x8E, 0x8C, 0x8A, 0x89, 0x87, 0x85, 0x83, - 0x81, 0x7F, 0x7D, 0x7B, 0x79, 0x77, 0x75, 0x73, - 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x68, 0x66, 0x64, - 0x62, 0x60, 0x5E, 0x5C, 0x5A, 0x59, 0x57, 0x55, - 0x53, 0x51, 0x50, 0x4E, 0x4C, 0x4A, 0x49, 0x47, - 0x45, 0x43, 0x42, 0x40, 0x3E, 0x3D, 0x3B, 0x3A, - 0x38, 0x36, 0x35, 0x33, 0x32, 0x30, 0x2F, 0x2D, - 0x2C, 0x2A, 0x29, 0x28, 0x26, 0x25, 0x23, 0x22 -#endif - -#if RGBLIGHT_BREATHE_TABLE_SIZE == 128 - 0x22, 0x25, 0x28, 0x2A, - 0x2D, 0x30, 0x33, 0x36, - 0x3A, 0x3D, 0x40, 0x43, - 0x47, 0x4A, 0x4E, 0x51, - 0x55, 0x59, 0x5C, 0x60, - 0x64, 0x68, 0x6B, 0x6F, - 0x73, 0x77, 0x7B, 0x7F, - 0x83, 0x87, 0x8A, 0x8E, - 0x92, 0x96, 0x9A, 0x9E, - 0xA1, 0xA5, 0xA8, 0xAC, - 0xAF, 0xB3, 0xB6, 0xB9, - 0xBC, 0xBF, 0xC2, 0xC5, - 0xC7, 0xCA, 0xCC, 0xCE, - 0xD1, 0xD2, 0xD4, 0xD6, - 0xD7, 0xD9, 0xDA, 0xDB, - 0xDB, 0xDC, 0xDC, 0xDD, - 0xDD, 0xDC, 0xDC, 0xDC, - 0xDB, 0xDA, 0xD9, 0xD8, - 0xD7, 0xD5, 0xD3, 0xD2, - 0xD0, 0xCD, 0xCB, 0xC9, - 0xC6, 0xC3, 0xC1, 0xBE, - 0xBB, 0xB8, 0xB4, 0xB1, - 0xAE, 0xAA, 0xA7, 0xA3, - 0x9F, 0x9C, 0x98, 0x94, - 0x90, 0x8C, 0x89, 0x85, - 0x81, 0x7D, 0x79, 0x75, - 0x71, 0x6D, 0x69, 0x66, - 0x62, 0x5E, 0x5A, 0x57, - 0x53, 0x50, 0x4C, 0x49, - 0x45, 0x42, 0x3E, 0x3B, - 0x38, 0x35, 0x32, 0x2F, - 0x2C, 0x29, 0x26, 0x23 -#endif - -#if RGBLIGHT_BREATHE_TABLE_SIZE == 64 - 0x22, 0x28, - 0x2D, 0x33, - 0x3A, 0x40, - 0x47, 0x4E, - 0x55, 0x5C, - 0x64, 0x6B, - 0x73, 0x7B, - 0x83, 0x8A, - 0x92, 0x9A, - 0xA1, 0xA8, - 0xAF, 0xB6, - 0xBC, 0xC2, - 0xC7, 0xCC, - 0xD1, 0xD4, - 0xD7, 0xDA, - 0xDB, 0xDC, - 0xDD, 0xDC, - 0xDB, 0xD9, - 0xD7, 0xD3, - 0xD0, 0xCB, - 0xC6, 0xC1, - 0xBB, 0xB4, - 0xAE, 0xA7, - 0x9F, 0x98, - 0x90, 0x89, - 0x81, 0x79, - 0x71, 0x69, - 0x62, 0x5A, - 0x53, 0x4C, - 0x45, 0x3E, - 0x38, 0x32, - 0x2C, 0x26 -#endif -}; - -static const int table_scale = 256 / sizeof(rgblight_effect_breathe_table); - diff --git a/quantum/rgblight/rgblight_modes.h b/quantum/rgblight/rgblight_modes.h deleted file mode 100644 index 7abdb87bc6e3..000000000000 --- a/quantum/rgblight/rgblight_modes.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifdef _RGBM_SINGLE_STATIC -_RGBM_SINGLE_STATIC(STATIC_LIGHT) -# ifdef RGBLIGHT_EFFECT_BREATHING -_RGBM_MULTI_DYNAMIC(BREATHING) -_RGBM_TMP_DYNAMIC(breathing_3, BREATHING) -_RGBM_TMP_DYNAMIC(breathing_4, BREATHING) -_RGBM_TMP_DYNAMIC(BREATHING_end, BREATHING) -# endif -# ifdef RGBLIGHT_EFFECT_RAINBOW_MOOD -_RGBM_MULTI_DYNAMIC(RAINBOW_MOOD) -_RGBM_TMP_DYNAMIC(rainbow_mood_7, RAINBOW_MOOD) -_RGBM_TMP_DYNAMIC(RAINBOW_MOOD_end, RAINBOW_MOOD) -# endif -# ifdef RGBLIGHT_EFFECT_RAINBOW_SWIRL -_RGBM_MULTI_DYNAMIC(RAINBOW_SWIRL) -_RGBM_TMP_DYNAMIC(rainbow_swirl_10, RAINBOW_SWIRL) -_RGBM_TMP_DYNAMIC(rainbow_swirl_11, RAINBOW_SWIRL) -_RGBM_TMP_DYNAMIC(rainbow_swirl_12, RAINBOW_SWIRL) -_RGBM_TMP_DYNAMIC(rainbow_swirl_13, RAINBOW_SWIRL) -_RGBM_TMP_DYNAMIC(RAINBOW_SWIRL_end, RAINBOW_SWIRL) -# endif -# ifdef RGBLIGHT_EFFECT_SNAKE -_RGBM_MULTI_DYNAMIC(SNAKE) -_RGBM_TMP_DYNAMIC(snake_16, SNAKE) -_RGBM_TMP_DYNAMIC(snake_17, SNAKE) -_RGBM_TMP_DYNAMIC(snake_18, SNAKE) -_RGBM_TMP_DYNAMIC(snake_19, SNAKE) -_RGBM_TMP_DYNAMIC(SNAKE_end, SNAKE) -# endif -# ifdef RGBLIGHT_EFFECT_KNIGHT -_RGBM_MULTI_DYNAMIC(KNIGHT) -_RGBM_TMP_DYNAMIC(knight_22, KNIGHT) -_RGBM_TMP_DYNAMIC(KNIGHT_end, KNIGHT) -# endif -# ifdef RGBLIGHT_EFFECT_CHRISTMAS -_RGBM_SINGLE_DYNAMIC(CHRISTMAS) -# endif -# ifdef RGBLIGHT_EFFECT_STATIC_GRADIENT -_RGBM_MULTI_STATIC(STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_26, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_27, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_28, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_29, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_30, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_31, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_32, STATIC_GRADIENT) -_RGBM_TMP_STATIC(static_gradient_33, STATIC_GRADIENT) -_RGBM_TMP_STATIC(STATIC_GRADIENT_end, STATIC_GRADIENT) -# endif -# ifdef RGBLIGHT_EFFECT_RGB_TEST -_RGBM_SINGLE_DYNAMIC(RGB_TEST) -# endif -# ifdef RGBLIGHT_EFFECT_ALTERNATING -_RGBM_SINGLE_DYNAMIC(ALTERNATING) -# endif -# ifdef RGBLIGHT_EFFECT_TWINKLE -_RGBM_MULTI_DYNAMIC(TWINKLE) -_RGBM_TMP_DYNAMIC(twinkle_38, TWINKLE) -_RGBM_TMP_DYNAMIC(twinkle_39, TWINKLE) -_RGBM_TMP_DYNAMIC(twinkle_40, TWINKLE) -_RGBM_TMP_DYNAMIC(twinkle_41, TWINKLE) -_RGBM_TMP_DYNAMIC(TWINKLE_end, TWINKLE) -# endif -//// Add a new mode here. -// #ifdef RGBLIGHT_EFFECT_ -// _RGBM__( ) -// #endif -#endif - -#undef _RGBM_SINGLE_STATIC -#undef _RGBM_SINGLE_DYNAMIC -#undef _RGBM_MULTI_STATIC -#undef _RGBM_MULTI_DYNAMIC -#undef _RGBM_TMP_STATIC -#undef _RGBM_TMP_DYNAMIC diff --git a/quantum/rgblight/rgblight_post_config.h b/quantum/rgblight/rgblight_post_config.h deleted file mode 100644 index 3c14cb6109f7..000000000000 --- a/quantum/rgblight/rgblight_post_config.h +++ /dev/null @@ -1,5 +0,0 @@ -#if defined(RGBLED_SPLIT) && !defined(RGBLIGHT_SPLIT) -// When RGBLED_SPLIT is defined, -// it is considered that RGBLIGHT_SPLIT is defined implicitly. -# define RGBLIGHT_SPLIT -#endif diff --git a/quantum/ring_buffer.h b/quantum/ring_buffer.h deleted file mode 100644 index 54b2bfffd1dd..000000000000 --- a/quantum/ring_buffer.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -#include -#include -#include "atomic_util.h" - -#ifndef RBUF_SIZE -# define RBUF_SIZE 32 -#endif - -static uint8_t rbuf[RBUF_SIZE]; -static uint8_t rbuf_head = 0; -static uint8_t rbuf_tail = 0; -static inline bool rbuf_enqueue(uint8_t data) { - bool ret = false; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - uint8_t next = (rbuf_head + 1) % RBUF_SIZE; - if (next != rbuf_tail) { - rbuf[rbuf_head] = data; - rbuf_head = next; - ret = true; - } - } - return ret; -} -static inline uint8_t rbuf_dequeue(void) { - uint8_t val = 0; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - if (rbuf_head != rbuf_tail) { - val = rbuf[rbuf_tail]; - rbuf_tail = (rbuf_tail + 1) % RBUF_SIZE; - } - } - - return val; -} -static inline bool rbuf_has_data(void) { - bool has_data; - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - has_data = (rbuf_head != rbuf_tail); - } - return has_data; -} -static inline void rbuf_clear(void) { - ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { - rbuf_head = rbuf_tail = 0; - } -} diff --git a/quantum/secure.c b/quantum/secure.c deleted file mode 100644 index f2a567f31d9e..000000000000 --- a/quantum/secure.c +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright 2022 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "secure.h" -#include "timer.h" -#include "util.h" - -#ifndef SECURE_UNLOCK_TIMEOUT -# define SECURE_UNLOCK_TIMEOUT 5000 -#endif - -#ifndef SECURE_IDLE_TIMEOUT -# define SECURE_IDLE_TIMEOUT 60000 -#endif - -#ifndef SECURE_UNLOCK_SEQUENCE -# define SECURE_UNLOCK_SEQUENCE \ - { \ - { 0, 0 } \ - } -#endif - -static secure_status_t secure_status = SECURE_LOCKED; -static uint32_t unlock_time = 0; -static uint32_t idle_time = 0; - -static void secure_hook(secure_status_t secure_status) { - secure_hook_quantum(secure_status); - secure_hook_kb(secure_status); -} - -secure_status_t secure_get_status(void) { - return secure_status; -} - -void secure_lock(void) { - secure_status = SECURE_LOCKED; - secure_hook(secure_status); -} - -void secure_unlock(void) { - secure_status = SECURE_UNLOCKED; - idle_time = timer_read32(); - secure_hook(secure_status); -} - -void secure_request_unlock(void) { - if (secure_status == SECURE_LOCKED) { - secure_status = SECURE_PENDING; - unlock_time = timer_read32(); - } - secure_hook(secure_status); -} - -void secure_activity_event(void) { - if (secure_status == SECURE_UNLOCKED) { - idle_time = timer_read32(); - } -} - -void secure_keypress_event(uint8_t row, uint8_t col) { - static const uint8_t sequence[][2] = SECURE_UNLOCK_SEQUENCE; - static const uint8_t sequence_len = ARRAY_SIZE(sequence); - - static uint8_t offset = 0; - if ((sequence[offset][0] == row) && (sequence[offset][1] == col)) { - offset++; - if (offset == sequence_len) { - offset = 0; - secure_unlock(); - } - } else { - offset = 0; - secure_lock(); - } -} - -void secure_task(void) { -#if SECURE_UNLOCK_TIMEOUT != 0 - // handle unlock timeout - if (secure_status == SECURE_PENDING) { - if (timer_elapsed32(unlock_time) >= SECURE_UNLOCK_TIMEOUT) { - secure_lock(); - } - } -#endif - -#if SECURE_IDLE_TIMEOUT != 0 - // handle idle timeout - if (secure_status == SECURE_UNLOCKED) { - if (timer_elapsed32(idle_time) >= SECURE_IDLE_TIMEOUT) { - secure_lock(); - } - } -#endif -} - -__attribute__((weak)) bool secure_hook_user(secure_status_t secure_status) { - return true; -} -__attribute__((weak)) bool secure_hook_kb(secure_status_t secure_status) { - return secure_hook_user(secure_status); -} diff --git a/quantum/secure.h b/quantum/secure.h deleted file mode 100644 index ae9b5b904521..000000000000 --- a/quantum/secure.h +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2022 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -/** - * \file - * - * \defgroup secure Secure API - * - * \brief Exposes a set of functionality to act as a virtual padlock for your device - * ...as long as that padlock is made of paper and it's currently raining. - * - * \{ - */ - -#include -#include - -/** \brief Available secure states - */ -typedef enum { - SECURE_LOCKED, - SECURE_PENDING, - SECURE_UNLOCKED, -} secure_status_t; - -/** \brief Query current secure state - */ -secure_status_t secure_get_status(void); - -/** \brief Helper to check if unlocking is currently locked - */ -#define secure_is_locked() (secure_get_status() == SECURE_LOCKED) - -/** \brief Helper to check if unlocking is currently in progress - */ -#define secure_is_unlocking() (secure_get_status() == SECURE_PENDING) - -/** \brief Helper to check if unlocking is currently unlocked - */ -#define secure_is_unlocked() (secure_get_status() == SECURE_UNLOCKED) - -/** \brief Lock down the device - */ -void secure_lock(void); - -/** \brief Force unlock the device - * - * \warning bypasses user unlock sequence - */ -void secure_unlock(void); - -/** \brief Begin listening for an unlock sequence - */ -void secure_request_unlock(void); - -/** \brief Flag to the secure subsystem that user activity has happened - * - * Call when some user activity has happened and the device should remain unlocked - */ -void secure_activity_event(void); - -/** \brief Flag to the secure subsystem that user has triggered a keypress - * - * Call to trigger processing of the unlock sequence - */ -void secure_keypress_event(uint8_t row, uint8_t col); - -/** \brief Handle various secure subsystem background tasks - */ -void secure_task(void); - -/** \brief quantum hook called when changing secure status device - */ -void secure_hook_quantum(secure_status_t secure_status); - -/** \brief user hook called when changing secure status device - */ -bool secure_hook_user(secure_status_t secure_status); - -/** \brief keyboard hook called when changing secure status device - */ -bool secure_hook_kb(secure_status_t secure_status); - -/** \} */ diff --git a/quantum/send_string/send_string.c b/quantum/send_string/send_string.c deleted file mode 100644 index 820fc2516322..000000000000 --- a/quantum/send_string/send_string.c +++ /dev/null @@ -1,328 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -#include "send_string.h" - -#include -#include - -#include "quantum_keycodes.h" -#include "keycode.h" -#include "action.h" -#include "wait.h" - -#if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL) -# include "audio.h" -# ifndef BELL_SOUND -# define BELL_SOUND TERMINAL_SOUND -# endif -float bell_song[][2] = SONG(BELL_SOUND); -#endif - -// clang-format off - -/* Bit-Packed look-up table to convert an ASCII character to whether - * [Shift] needs to be sent with the keycode. - */ -__attribute__((weak)) const uint8_t ascii_to_shift_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 1, 1, 1, 1, 1, 1, 0), - KCLUT_ENTRY(1, 1, 1, 1, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 1, 0, 1, 0, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 1, 1, 1, 1, 1), - KCLUT_ENTRY(1, 1, 1, 0, 0, 0, 1, 1), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 1, 1, 1, 1, 0) -}; - -/* Bit-Packed look-up table to convert an ASCII character to whether - * [AltGr] needs to be sent with the keycode. - */ -__attribute__((weak)) const uint8_t ascii_to_altgr_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -/* Bit-Packed look-up table to convert an ASCII character to whether - * [Space] needs to be sent after the keycode - */ -__attribute__((weak)) const uint8_t ascii_to_dead_lut[16] PROGMEM = { - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0), - KCLUT_ENTRY(0, 0, 0, 0, 0, 0, 0, 0) -}; - -/* Look-up table to convert an ASCII character to a keycode. - */ -__attribute__((weak)) const uint8_t ascii_to_keycode_lut[128] PROGMEM = { - // NUL SOH STX ETX EOT ENQ ACK BEL - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // BS TAB LF VT FF CR SO SI - KC_BSPC, KC_TAB, KC_ENT, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // DLE DC1 DC2 DC3 DC4 NAK SYN ETB - XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - // CAN EM SUB ESC FS GS RS US - XXXXXXX, XXXXXXX, XXXXXXX, KC_ESC, XXXXXXX, XXXXXXX, XXXXXXX, XXXXXXX, - - // ! " # $ % & ' - KC_SPC, KC_1, KC_QUOT, KC_3, KC_4, KC_5, KC_7, KC_QUOT, - // ( ) * + , - . / - KC_9, KC_0, KC_8, KC_EQL, KC_COMM, KC_MINS, KC_DOT, KC_SLSH, - // 0 1 2 3 4 5 6 7 - KC_0, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, - // 8 9 : ; < = > ? - KC_8, KC_9, KC_SCLN, KC_SCLN, KC_COMM, KC_EQL, KC_DOT, KC_SLSH, - // @ A B C D E F G - KC_2, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, - // H I J K L M N O - KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, - // P Q R S T U V W - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, - // X Y Z [ \ ] ^ _ - KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_6, KC_MINS, - // ` a b c d e f g - KC_GRV, KC_A, KC_B, KC_C, KC_D, KC_E, KC_F, KC_G, - // h i j k l m n o - KC_H, KC_I, KC_J, KC_K, KC_L, KC_M, KC_N, KC_O, - // p q r s t u v w - KC_P, KC_Q, KC_R, KC_S, KC_T, KC_U, KC_V, KC_W, - // x y z { | } ~ DEL - KC_X, KC_Y, KC_Z, KC_LBRC, KC_BSLS, KC_RBRC, KC_GRV, KC_DEL -}; - -// clang-format on - -// Note: we bit-pack in "reverse" order to optimize loading -#define PGM_LOADBIT(mem, pos) ((pgm_read_byte(&((mem)[(pos) / 8])) >> ((pos) % 8)) & 0x01) - -void send_string(const char *string) { - send_string_with_delay(string, 0); -} - -void send_string_with_delay(const char *string, uint8_t interval) { - while (1) { - char ascii_code = *string; - if (!ascii_code) break; - if (ascii_code == SS_QMK_PREFIX) { - ascii_code = *(++string); - if (ascii_code == SS_TAP_CODE) { - // tap - uint8_t keycode = *(++string); - tap_code(keycode); - } else if (ascii_code == SS_DOWN_CODE) { - // down - uint8_t keycode = *(++string); - register_code(keycode); - } else if (ascii_code == SS_UP_CODE) { - // up - uint8_t keycode = *(++string); - unregister_code(keycode); - } else if (ascii_code == SS_DELAY_CODE) { - // delay - int ms = 0; - uint8_t keycode = *(++string); - while (isdigit(keycode)) { - ms *= 10; - ms += keycode - '0'; - keycode = *(++string); - } - while (ms--) - wait_ms(1); - } - } else { - send_char(ascii_code); - } - ++string; - // interval - { - uint8_t ms = interval; - while (ms--) - wait_ms(1); - } - } -} - -void send_char(char ascii_code) { -#if defined(AUDIO_ENABLE) && defined(SENDSTRING_BELL) - if (ascii_code == '\a') { // BEL - PLAY_SONG(bell_song); - return; - } -#endif - - uint8_t keycode = pgm_read_byte(&ascii_to_keycode_lut[(uint8_t)ascii_code]); - bool is_shifted = PGM_LOADBIT(ascii_to_shift_lut, (uint8_t)ascii_code); - bool is_altgred = PGM_LOADBIT(ascii_to_altgr_lut, (uint8_t)ascii_code); - bool is_dead = PGM_LOADBIT(ascii_to_dead_lut, (uint8_t)ascii_code); - - if (is_shifted) { - register_code(KC_LEFT_SHIFT); - } - if (is_altgred) { - register_code(KC_RIGHT_ALT); - } - tap_code(keycode); - if (is_altgred) { - unregister_code(KC_RIGHT_ALT); - } - if (is_shifted) { - unregister_code(KC_LEFT_SHIFT); - } - if (is_dead) { - tap_code(KC_SPACE); - } -} - -void send_dword(uint32_t number) { - send_word(number >> 16); - send_word(number & 0xFFFFUL); -} - -void send_word(uint16_t number) { - send_byte(number >> 8); - send_byte(number & 0xFF); -} - -void send_byte(uint8_t number) { - send_nibble(number >> 4); - send_nibble(number & 0xF); -} - -void send_nibble(uint8_t number) { - switch (number & 0xF) { - case 0 ... 9: - send_char(number + '0'); - break; - case 10 ... 15: - send_char(number - 10 + 'a'); - break; - } -} - -void tap_random_base64(void) { -#if defined(__AVR_ATmega32U4__) - uint8_t key = (TCNT0 + TCNT1 + TCNT3 + TCNT4) % 64; -#else - uint8_t key = rand() % 64; -#endif - switch (key) { - case 0 ... 25: - send_char(key + 'A'); - break; - case 26 ... 51: - send_char(key - 26 + 'a'); - break; - case 52: - send_char('0'); - break; - case 53 ... 61: - send_char(key - 53 + '1'); - break; - case 62: - send_char('+'); - break; - case 63: - send_char('/'); - break; - } -} - -#if defined(__AVR__) -void send_string_P(const char *string) { - send_string_with_delay_P(string, 0); -} - -void send_string_with_delay_P(const char *string, uint8_t interval) { - while (1) { - char ascii_code = pgm_read_byte(string); - if (!ascii_code) break; - if (ascii_code == SS_QMK_PREFIX) { - ascii_code = pgm_read_byte(++string); - if (ascii_code == SS_TAP_CODE) { - // tap - uint8_t keycode = pgm_read_byte(++string); - tap_code(keycode); - } else if (ascii_code == SS_DOWN_CODE) { - // down - uint8_t keycode = pgm_read_byte(++string); - register_code(keycode); - } else if (ascii_code == SS_UP_CODE) { - // up - uint8_t keycode = pgm_read_byte(++string); - unregister_code(keycode); - } else if (ascii_code == SS_DELAY_CODE) { - // delay - int ms = 0; - uint8_t keycode = pgm_read_byte(++string); - while (isdigit(keycode)) { - ms *= 10; - ms += keycode - '0'; - keycode = pgm_read_byte(++string); - } - while (ms--) - wait_ms(1); - } - } else { - send_char(ascii_code); - } - ++string; - // interval - { - uint8_t ms = interval; - while (ms--) - wait_ms(1); - } - } -} -#endif diff --git a/quantum/send_string/send_string.h b/quantum/send_string/send_string.h deleted file mode 100644 index dbaed43ebccb..000000000000 --- a/quantum/send_string/send_string.h +++ /dev/null @@ -1,154 +0,0 @@ -/* Copyright 2021 - * - * 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 . - */ - -/** - * \file - * - * \defgroup send_string Send String API - * - * \brief These functions allow you to create macros by typing out sequences of keystrokes. - * \{ - */ - -#include - -#include "progmem.h" -#include "send_string_keycodes.h" - -// Look-Up Tables (LUTs) to convert ASCII character to keycode sequence. -extern const uint8_t ascii_to_shift_lut[16]; -extern const uint8_t ascii_to_altgr_lut[16]; -extern const uint8_t ascii_to_dead_lut[16]; -extern const uint8_t ascii_to_keycode_lut[128]; - -// clang-format off -#define KCLUT_ENTRY(a, b, c, d, e, f, g, h) \ - ( ((a) ? 1 : 0) << 0 \ - | ((b) ? 1 : 0) << 1 \ - | ((c) ? 1 : 0) << 2 \ - | ((d) ? 1 : 0) << 3 \ - | ((e) ? 1 : 0) << 4 \ - | ((f) ? 1 : 0) << 5 \ - | ((g) ? 1 : 0) << 6 \ - | ((h) ? 1 : 0) << 7 ) -// clang-format on - -/** - * \brief Type out a string of ASCII characters. - * - * This function simply calls `send_string_with_delay(string, 0)`. - * - * Most keycodes from the basic keycode range are also supported by way of a special sequence - see `send_string_keycodes.h`. - * - * \param string The string to type out. - */ -void send_string(const char *string); - -/** - * \brief Type out a string of ASCII characters, with a delay between each character. - * - * \param string The string to type out. - * \param interval The amount of time, in milliseconds, to wait before typing the next character. - */ -void send_string_with_delay(const char *string, uint8_t interval); - -/** - * \brief Type out an ASCII character. - * - * \param ascii_code The character to type. - */ -void send_char(char ascii_code); - -/** - * \brief Type out an eight digit (unsigned 32-bit) hexadecimal value. - * - * The format is `[0-9a-f]{8}`, eg. `00000000` through `ffffffff`. - * - * \param number The value to type, from 0 to 4,294,967,295. - */ -void send_dword(uint32_t number); - -/** - * \brief Type out a four digit (unsigned 16-bit) hexadecimal value. - * - * The format is `[0-9a-f]{4}`, eg. `0000` through `ffff`. - * - * \param number The value to type, from 0 to 65,535. - */ -void send_word(uint16_t number); - -/** - * \brief Type out a two digit (8-bit) hexadecimal value. - * - * The format is `[0-9a-f]{2}`, eg. `00` through `ff`. - * - * \param number The value to type, from 0 to 255. - */ -void send_byte(uint8_t number); - -/** - * \brief Type out a single hexadecimal digit. - * - * The format is `[0-9a-f]{1}`, eg. `0` through `f`. - * - * \param number The value to type, from 0 to 15. - */ -void send_nibble(uint8_t number); - -/** - * \brief Type a pseudorandom character from the set `A-Z`, `a-z`, `0-9`, `+` and `/`. - */ -void tap_random_base64(void); - -#if defined(__AVR__) || defined(__DOXYGEN__) -/** - * \brief Type out a PROGMEM string of ASCII characters. - * - * On ARM devices, this function is simply an alias for send_string_with_delay(string, 0). - * - * \param string The string to type out. - */ -void send_string_P(const char *string); - -/** - * \brief Type out a PROGMEM string of ASCII characters, with a delay between each character. - * - * On ARM devices, this function is simply an alias for send_string_with_delay(string, interval). - * - * \param string The string to type out. - * \param interval The amount of time, in milliseconds, to wait before typing the next character. - */ -void send_string_with_delay_P(const char *string, uint8_t interval); -#else -# define send_string_P(string) send_string_with_delay(string, 0) -# define send_string_with_delay_P(string, interval) send_string_with_delay(string, interval) -#endif - -/** - * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), 0). - * - * On ARM devices, this define evaluates to send_string_with_delay(string, 0). - */ -#define SEND_STRING(string) send_string_with_delay_P(PSTR(string), 0) - -/** - * \brief Shortcut macro for send_string_with_delay_P(PSTR(string), interval). - * - * On ARM devices, this define evaluates to send_string_with_delay(string, interval). - */ -#define SEND_STRING_DELAY(string, interval) send_string_with_delay_P(PSTR(string), interval) - -/** \} */ diff --git a/quantum/send_string/send_string_keycodes.h b/quantum/send_string/send_string_keycodes.h deleted file mode 100644 index 54b838205319..000000000000 --- a/quantum/send_string/send_string_keycodes.h +++ /dev/null @@ -1,445 +0,0 @@ -/* Copyright 2019 - * - * 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 . - */ - -#pragma once - -// clang-format off - -/* Punctuation */ -#define X_ENT X_ENTER -#define X_ESC X_ESCAPE -#define X_BSPC X_BACKSPACE -#define X_SPC X_SPACE -#define X_MINS X_MINUS -#define X_EQL X_EQUAL -#define X_LBRC X_LEFT_BRACKET -#define X_RBRC X_RIGHT_BRACKET -#define X_BSLS X_BACKSLASH -#define X_NUHS X_NONUS_HASH -#define X_SCLN X_SEMICOLON -#define X_QUOT X_QUOTE -#define X_GRV X_GRAVE -#define X_COMM X_COMMA -#define X_SLSH X_SLASH -#define X_NUBS X_NONUS_BACKSLASH - -/* Lock Keys */ -#define X_CAPS X_CAPS_LOCK -#define X_SCRL X_SCROLL_LOCK -#define X_NUM X_NUM_LOCK -#define X_LCAP X_LOCKING_CAPS_LOCK -#define X_LNUM X_LOCKING_NUM_LOCK -#define X_LSCR X_LOCKING_SCROLL_LOCK - -/* Commands */ -#define X_PSCR X_PRINT_SCREEN -#define X_PAUS X_PAUSE -#define X_BRK X_PAUSE -#define X_INS X_INSERT -#define X_PGUP X_PAGE_UP -#define X_DEL X_DELETE -#define X_PGDN X_PAGE_DOWN -#define X_RGHT X_RIGHT -#define X_APP X_APPLICATION -#define X_EXEC X_EXECUTE -#define X_SLCT X_SELECT -#define X_AGIN X_AGAIN -#define X_PSTE X_PASTE -#define X_ERAS X_ALTERNATE_ERASE -#define X_SYRQ X_SYSTEM_REQUEST -#define X_CNCL X_CANCEL -#define X_CLR X_CLEAR -#define X_PRIR X_PRIOR -#define X_RETN X_RETURN -#define X_SEPR X_SEPARATOR -#define X_CLAG X_CLEAR_AGAIN -#define X_CRSL X_CRSEL -#define X_EXSL X_EXSEL - -/* Keypad */ -#define X_PSLS X_KP_SLASH -#define X_PAST X_KP_ASTERISK -#define X_PMNS X_KP_MINUS -#define X_PPLS X_KP_PLUS -#define X_PENT X_KP_ENTER -#define X_P1 X_KP_1 -#define X_P2 X_KP_2 -#define X_P3 X_KP_3 -#define X_P4 X_KP_4 -#define X_P5 X_KP_5 -#define X_P6 X_KP_6 -#define X_P7 X_KP_7 -#define X_P8 X_KP_8 -#define X_P9 X_KP_9 -#define X_P0 X_KP_0 -#define X_PDOT X_KP_DOT -#define X_PEQL X_KP_EQUAL -#define X_PCMM X_KP_COMMA - -/* Language Specific */ -#define X_INT1 X_INTERNATIONAL_1 -#define X_INT2 X_INTERNATIONAL_2 -#define X_INT3 X_INTERNATIONAL_3 -#define X_INT4 X_INTERNATIONAL_4 -#define X_INT5 X_INTERNATIONAL_5 -#define X_INT6 X_INTERNATIONAL_6 -#define X_INT7 X_INTERNATIONAL_7 -#define X_INT8 X_INTERNATIONAL_8 -#define X_INT9 X_INTERNATIONAL_9 -#define X_LNG1 X_LANGUAGE_1 -#define X_LNG2 X_LANGUAGE_2 -#define X_LNG3 X_LANGUAGE_3 -#define X_LNG4 X_LANGUAGE_4 -#define X_LNG5 X_LANGUAGE_5 -#define X_LNG6 X_LANGUAGE_6 -#define X_LNG7 X_LANGUAGE_7 -#define X_LNG8 X_LANGUAGE_8 -#define X_LNG9 X_LANGUAGE_9 - -/* Modifiers */ -#define X_LCTL X_LEFT_CTRL -#define X_LSFT X_LEFT_SHIFT -#define X_LALT X_LEFT_ALT -#define X_LOPT X_LEFT_ALT -#define X_LGUI X_LEFT_GUI -#define X_LCMD X_LEFT_GUI -#define X_LWIN X_LEFT_GUI -#define X_RCTL X_RIGHT_CTRL -#define X_RSFT X_RIGHT_SHIFT -#define X_RALT X_RIGHT_ALT -#define X_ALGR X_RIGHT_ALT -#define X_ROPT X_RIGHT_ALT -#define X_RGUI X_RIGHT_GUI -#define X_RCMD X_RIGHT_GUI -#define X_RWIN X_RIGHT_GUI - -/* Generic Desktop Page (0x01) */ -#define X_PWR X_SYSTEM_POWER -#define X_SLEP X_SYSTEM_SLEEP -#define X_WAKE X_SYSTEM_WAKE - -/* Consumer Page (0x0C) */ -#define X_MUTE X_AUDIO_MUTE -#define X_VOLU X_AUDIO_VOL_UP -#define X_VOLD X_AUDIO_VOL_DOWN -#define X_MNXT X_MEDIA_NEXT_TRACK -#define X_MPRV X_MEDIA_PREV_TRACK -#define X_MSTP X_MEDIA_STOP -#define X_MPLY X_MEDIA_PLAY_PAUSE -#define X_MSEL X_MEDIA_SELECT -#define X_EJCT X_MEDIA_EJECT -#define X_CALC X_CALCULATOR -#define X_MYCM X_MY_COMPUTER -#define X_WSCH X_WWW_SEARCH -#define X_WHOM X_WWW_HOME -#define X_WBAK X_WWW_BACK -#define X_WFWD X_WWW_FORWARD -#define X_WSTP X_WWW_STOP -#define X_WREF X_WWW_REFRESH -#define X_WFAV X_WWW_FAVORITES -#define X_MFFD X_MEDIA_FAST_FORWARD -#define X_MRWD X_MEDIA_REWIND -#define X_BRIU X_BRIGHTNESS_UP -#define X_BRID X_BRIGHTNESS_DOWN -#define X_CPNL X_CONTROL_PANEL -#define X_ASST X_ASSISTANT - -/* System Specific */ -#define X_BRMU X_PAUSE -#define X_BRMD X_SCROLL_LOCK - -/* Mouse Keys */ -#define X_MS_U X_MS_UP -#define X_MS_D X_MS_DOWN -#define X_MS_L X_MS_LEFT -#define X_MS_R X_MS_RIGHT -#define X_BTN1 X_MS_BTN1 -#define X_BTN2 X_MS_BTN2 -#define X_BTN3 X_MS_BTN3 -#define X_BTN4 X_MS_BTN4 -#define X_BTN5 X_MS_BTN5 -#define X_BTN6 X_MS_BTN6 -#define X_BTN7 X_MS_BTN7 -#define X_BTN8 X_MS_BTN8 -#define X_WH_U X_MS_WH_UP -#define X_WH_D X_MS_WH_DOWN -#define X_WH_L X_MS_WH_LEFT -#define X_WH_R X_MS_WH_RIGHT -#define X_ACL0 X_MS_ACCEL0 -#define X_ACL1 X_MS_ACCEL1 -#define X_ACL2 X_MS_ACCEL2 - -/* Keyboard/Keypad Page (0x07) */ -#define X_A 04 -#define X_B 05 -#define X_C 06 -#define X_D 07 -#define X_E 08 -#define X_F 09 -#define X_G 0a -#define X_H 0b -#define X_I 0c -#define X_J 0d -#define X_K 0e -#define X_L 0f -#define X_M 10 -#define X_N 11 -#define X_O 12 -#define X_P 13 -#define X_Q 14 -#define X_R 15 -#define X_S 16 -#define X_T 17 -#define X_U 18 -#define X_V 19 -#define X_W 1a -#define X_X 1b -#define X_Y 1c -#define X_Z 1d -#define X_1 1e -#define X_2 1f -#define X_3 20 -#define X_4 21 -#define X_5 22 -#define X_6 23 -#define X_7 24 -#define X_8 25 -#define X_9 26 -#define X_0 27 -#define X_ENTER 28 -#define X_ESCAPE 29 -#define X_BACKSPACE 2a -#define X_TAB 2b -#define X_SPACE 2c -#define X_MINUS 2d -#define X_EQUAL 2e -#define X_LEFT_BRACKET 2f -#define X_RIGHT_BRACKET 30 -#define X_BACKSLASH 31 -#define X_NONUS_HASH 32 -#define X_SEMICOLON 33 -#define X_QUOTE 34 -#define X_GRAVE 35 -#define X_COMMA 36 -#define X_DOT 37 -#define X_SLASH 38 -#define X_CAPS_LOCK 39 -#define X_F1 3a -#define X_F2 3b -#define X_F3 3c -#define X_F4 3d -#define X_F5 3e -#define X_F6 3f -#define X_F7 40 -#define X_F8 41 -#define X_F9 42 -#define X_F10 43 -#define X_F11 44 -#define X_F12 45 -#define X_PRINT_SCREEN 46 -#define X_SCROLL_LOCK 47 -#define X_PAUSE 48 -#define X_INSERT 49 -#define X_HOME 4a -#define X_PAGE_UP 4b -#define X_DELETE 4c -#define X_END 4d -#define X_PAGE_DOWN 4e -#define X_RIGHT 4f -#define X_LEFT 50 -#define X_DOWN 51 -#define X_UP 52 -#define X_NUM_LOCK 53 -#define X_KP_SLASH 54 -#define X_KP_ASTERISK 55 -#define X_KP_MINUS 56 -#define X_KP_PLUS 57 -#define X_KP_ENTER 58 -#define X_KP_1 59 -#define X_KP_2 5a -#define X_KP_3 5b -#define X_KP_4 5c -#define X_KP_5 5d -#define X_KP_6 5e -#define X_KP_7 5f -#define X_KP_8 60 -#define X_KP_9 61 -#define X_KP_0 62 -#define X_KP_DOT 63 -#define X_NONUS_BACKSLASH 64 -#define X_APPLICATION 65 -#define X_KB_POWER 66 -#define X_KP_EQUAL 67 -#define X_F13 68 -#define X_F14 69 -#define X_F15 6a -#define X_F16 6b -#define X_F17 6c -#define X_F18 6d -#define X_F19 6e -#define X_F20 6f -#define X_F21 70 -#define X_F22 71 -#define X_F23 72 -#define X_F24 73 -#define X_EXECUTE 74 -#define X_HELP 75 -#define X_MENU 76 -#define X_SELECT 77 -#define X_STOP 78 -#define X_AGAIN 79 -#define X_UNDO 7a -#define X_CUT 7b -#define X_COPY 7c -#define X_PASTE 7d -#define X_FIND 7e -#define X_KB_MUTE 7f -#define X_KB_VOLUME_UP 80 -#define X_KB_VOLUME_DOWN 81 -#define X_LOCKING_CAPS_LOCK 82 -#define X_LOCKING_NUM_LOCK 83 -#define X_LOCKING_SCROLL_LOCK 84 -#define X_KP_COMMA 85 -#define X_KP_EQUAL_AS400 86 -#define X_INTERNATIONAL_1 87 -#define X_INTERNATIONAL_2 88 -#define X_INTERNATIONAL_3 89 -#define X_INTERNATIONAL_4 8a -#define X_INTERNATIONAL_5 8b -#define X_INTERNATIONAL_6 8c -#define X_INTERNATIONAL_7 8d -#define X_INTERNATIONAL_8 8e -#define X_INTERNATIONAL_9 8f -#define X_LANGUAGE_1 90 -#define X_LANGUAGE_2 91 -#define X_LANGUAGE_3 92 -#define X_LANGUAGE_4 93 -#define X_LANGUAGE_5 94 -#define X_LANGUAGE_6 95 -#define X_LANGUAGE_7 96 -#define X_LANGUAGE_8 97 -#define X_LANGUAGE_9 98 -#define X_ALTERNATE_ERASE 99 -#define X_SYSTEM_REQUEST 9a -#define X_CANCEL 9b -#define X_CLEAR 9c -#define X_PRIOR 9d -#define X_RETURN 9e -#define X_SEPARATOR 9f -#define X_OUT a0 -#define X_OPER a1 -#define X_CLEAR_AGAIN a2 -#define X_CRSEL a3 -#define X_EXSEL a4 - -/* Modifiers */ -#define X_LEFT_CTRL e0 -#define X_LEFT_SHIFT e1 -#define X_LEFT_ALT e2 -#define X_LEFT_GUI e3 -#define X_RIGHT_CTRL e4 -#define X_RIGHT_SHIFT e5 -#define X_RIGHT_ALT e6 -#define X_RIGHT_GUI e7 - -/* Media and Function keys */ -/* Generic Desktop Page (0x01) */ -#define X_SYSTEM_POWER a5 -#define X_SYSTEM_SLEEP a6 -#define X_SYSTEM_WAKE a7 - -/* Consumer Page (0x0C) */ -#define X_AUDIO_MUTE a8 -#define X_AUDIO_VOL_UP a9 -#define X_AUDIO_VOL_DOWN aa -#define X_MEDIA_NEXT_TRACK ab -#define X_MEDIA_PREV_TRACK ac -#define X_MEDIA_STOP ad -#define X_MEDIA_PLAY_PAUSE ae -#define X_MEDIA_SELECT af -#define X_MEDIA_EJECT b0 -#define X_MAIL b1 -#define X_CALCULATOR b2 -#define X_MY_COMPUTER b3 -#define X_WWW_SEARCH b4 -#define X_WWW_HOME b5 -#define X_WWW_BACK b6 -#define X_WWW_FORWARD b7 -#define X_WWW_STOP b8 -#define X_WWW_REFRESH b9 -#define X_WWW_FAVORITES ba -#define X_MEDIA_FAST_FORWARD bb -#define X_MEDIA_REWIND bc -#define X_BRIGHTNESS_UP bd -#define X_BRIGHTNESS_DOWN be -#define X_CONTROL_PANEL bf -#define X_ASSISTANT c0 - -/* Mouse Buttons (unallocated range in HID spec) */ -#define X_MS_UP cd -#define X_MS_DOWN ce -#define X_MS_LEFT cf -#define X_MS_RIGHT d0 -#define X_MS_BTN1 d1 -#define X_MS_BTN2 d2 -#define X_MS_BTN3 d3 -#define X_MS_BTN4 d4 -#define X_MS_BTN5 d5 -#define X_MS_BTN6 d6 -#define X_MS_BTN7 d7 -#define X_MS_BTN8 d8 -#define X_MS_WH_UP d9 -#define X_MS_WH_DOWN da -#define X_MS_WH_LEFT db -#define X_MS_WH_RIGHT dc -#define X_MS_ACCEL0 dd -#define X_MS_ACCEL1 de -#define X_MS_ACCEL2 df - -// Send string macros -#define STRINGIZE(z) #z -#define ADD_SLASH_X(y) STRINGIZE(\x##y) -#define SYMBOL_STR(x) ADD_SLASH_X(x) - -#define SS_QMK_PREFIX 1 - -#define SS_TAP_CODE 1 -#define SS_DOWN_CODE 2 -#define SS_UP_CODE 3 -#define SS_DELAY_CODE 4 - -#define SS_TAP(keycode) "\1\1" SYMBOL_STR(keycode) -#define SS_DOWN(keycode) "\1\2" SYMBOL_STR(keycode) -#define SS_UP(keycode) "\1\3" SYMBOL_STR(keycode) -#define SS_DELAY(msecs) "\1\4" STRINGIZE(msecs) "|" - -// `string` arguments must not be parenthesized -#define SS_LCTL(string) SS_DOWN(X_LCTL) string SS_UP(X_LCTL) -#define SS_LSFT(string) SS_DOWN(X_LSFT) string SS_UP(X_LSFT) -#define SS_LALT(string) SS_DOWN(X_LALT) string SS_UP(X_LALT) -#define SS_LGUI(string) SS_DOWN(X_LGUI) string SS_UP(X_LGUI) -#define SS_LOPT(string) SS_LALT(string) -#define SS_LCMD(string) SS_LGUI(string) -#define SS_LWIN(string) SS_LGUI(string) - -#define SS_RCTL(string) SS_DOWN(X_RCTL) string SS_UP(X_RCTL) -#define SS_RSFT(string) SS_DOWN(X_RSFT) string SS_UP(X_RSFT) -#define SS_RALT(string) SS_DOWN(X_RALT) string SS_UP(X_RALT) -#define SS_RGUI(string) SS_DOWN(X_RGUI) string SS_UP(X_RGUI) -#define SS_ALGR(string) SS_RALT(string) -#define SS_ROPT(string) SS_RALT(string) -#define SS_RCMD(string) SS_RGUI(string) -#define SS_RWIN(string) SS_RGUI(string) diff --git a/quantum/sequencer/sequencer.c b/quantum/sequencer/sequencer.c deleted file mode 100644 index ff243c870bb9..000000000000 --- a/quantum/sequencer/sequencer.c +++ /dev/null @@ -1,303 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#include "sequencer.h" -#include "debug.h" -#include "timer.h" - -#ifdef MIDI_ENABLE -# include "process_midi.h" -#endif - -#ifdef MIDI_MOCKED -# include "tests/midi_mock.h" -#endif - -sequencer_config_t sequencer_config = { - false, // enabled - {false}, // steps - {0}, // track notes - 60, // tempo - SQ_RES_4, // resolution -}; - -sequencer_state_t sequencer_internal_state = {0, 0, 0, 0, SEQUENCER_PHASE_ATTACK}; - -bool is_sequencer_on(void) { - return sequencer_config.enabled; -} - -void sequencer_on(void) { - dprintln("sequencer on"); - sequencer_config.enabled = true; - sequencer_internal_state.current_track = 0; - sequencer_internal_state.current_step = 0; - sequencer_internal_state.timer = timer_read(); - sequencer_internal_state.phase = SEQUENCER_PHASE_ATTACK; -} - -void sequencer_off(void) { - dprintln("sequencer off"); - sequencer_config.enabled = false; - sequencer_internal_state.current_step = 0; -} - -void sequencer_toggle(void) { - if (is_sequencer_on()) { - sequencer_off(); - } else { - sequencer_on(); - } -} - -void sequencer_set_track_notes(const uint16_t track_notes[SEQUENCER_TRACKS]) { - for (uint8_t i = 0; i < SEQUENCER_TRACKS; i++) { - sequencer_config.track_notes[i] = track_notes[i]; - } -} - -bool is_sequencer_track_active(uint8_t track) { - return (sequencer_internal_state.active_tracks >> track) & true; -} - -void sequencer_set_track_activation(uint8_t track, bool value) { - if (value) { - sequencer_internal_state.active_tracks |= (1 << track); - } else { - sequencer_internal_state.active_tracks &= ~(1 << track); - } - dprintf("sequencer: track %d is %s\n", track, value ? "active" : "inactive"); -} - -void sequencer_toggle_track_activation(uint8_t track) { - sequencer_set_track_activation(track, !is_sequencer_track_active(track)); -} - -void sequencer_toggle_single_active_track(uint8_t track) { - if (is_sequencer_track_active(track)) { - sequencer_internal_state.active_tracks = 0; - } else { - sequencer_internal_state.active_tracks = 1 << track; - } -} - -bool is_sequencer_step_on(uint8_t step) { - return step < SEQUENCER_STEPS && (sequencer_config.steps[step] & sequencer_internal_state.active_tracks) > 0; -} - -bool is_sequencer_step_on_for_track(uint8_t step, uint8_t track) { - return step < SEQUENCER_STEPS && (sequencer_config.steps[step] >> track) & true; -} - -void sequencer_set_step(uint8_t step, bool value) { - if (step < SEQUENCER_STEPS) { - if (value) { - sequencer_config.steps[step] |= sequencer_internal_state.active_tracks; - } else { - sequencer_config.steps[step] &= ~sequencer_internal_state.active_tracks; - } - dprintf("sequencer: step %d is %s\n", step, value ? "on" : "off"); - } else { - dprintf("sequencer: step %d is out of range\n", step); - } -} - -void sequencer_toggle_step(uint8_t step) { - if (is_sequencer_step_on(step)) { - sequencer_set_step_off(step); - } else { - sequencer_set_step_on(step); - } -} - -void sequencer_set_all_steps(bool value) { - for (uint8_t step = 0; step < SEQUENCER_STEPS; step++) { - if (value) { - sequencer_config.steps[step] |= sequencer_internal_state.active_tracks; - } else { - sequencer_config.steps[step] &= ~sequencer_internal_state.active_tracks; - } - } - dprintf("sequencer: all steps are %s\n", value ? "on" : "off"); -} - -uint8_t sequencer_get_tempo(void) { - return sequencer_config.tempo; -} - -void sequencer_set_tempo(uint8_t tempo) { - if (tempo > 0) { - sequencer_config.tempo = tempo; - dprintf("sequencer: tempo set to %d bpm\n", tempo); - } else { - dprintln("sequencer: cannot set tempo to 0"); - } -} - -void sequencer_increase_tempo(void) { - // Handling potential uint8_t overflow - if (sequencer_config.tempo < UINT8_MAX) { - sequencer_set_tempo(sequencer_config.tempo + 1); - } else { - dprintf("sequencer: cannot set tempo above %d\n", UINT8_MAX); - } -} - -void sequencer_decrease_tempo(void) { - sequencer_set_tempo(sequencer_config.tempo - 1); -} - -sequencer_resolution_t sequencer_get_resolution(void) { - return sequencer_config.resolution; -} - -void sequencer_set_resolution(sequencer_resolution_t resolution) { - if (resolution >= 0 && resolution < SEQUENCER_RESOLUTIONS) { - sequencer_config.resolution = resolution; - dprintf("sequencer: resolution set to %d\n", resolution); - } else { - dprintf("sequencer: resolution %d is out of range\n", resolution); - } -} - -void sequencer_increase_resolution(void) { - sequencer_set_resolution(sequencer_config.resolution + 1); -} - -void sequencer_decrease_resolution(void) { - sequencer_set_resolution(sequencer_config.resolution - 1); -} - -uint8_t sequencer_get_current_step(void) { - return sequencer_internal_state.current_step; -} - -void sequencer_phase_attack(void) { - dprintf("sequencer: step %d\n", sequencer_internal_state.current_step); - dprintf("sequencer: time %d\n", timer_read()); - - if (sequencer_internal_state.current_track == 0) { - sequencer_internal_state.timer = timer_read(); - } - - if (timer_elapsed(sequencer_internal_state.timer) < sequencer_internal_state.current_track * SEQUENCER_TRACK_THROTTLE) { - return; - } - -#if defined(MIDI_ENABLE) || defined(MIDI_MOCKED) - if (is_sequencer_step_on_for_track(sequencer_internal_state.current_step, sequencer_internal_state.current_track)) { - process_midi_basic_noteon(midi_compute_note(sequencer_config.track_notes[sequencer_internal_state.current_track])); - } -#endif - - if (sequencer_internal_state.current_track < SEQUENCER_TRACKS - 1) { - sequencer_internal_state.current_track++; - } else { - sequencer_internal_state.phase = SEQUENCER_PHASE_RELEASE; - } -} - -void sequencer_phase_release(void) { - if (timer_elapsed(sequencer_internal_state.timer) < SEQUENCER_PHASE_RELEASE_TIMEOUT + sequencer_internal_state.current_track * SEQUENCER_TRACK_THROTTLE) { - return; - } -#if defined(MIDI_ENABLE) || defined(MIDI_MOCKED) - if (is_sequencer_step_on_for_track(sequencer_internal_state.current_step, sequencer_internal_state.current_track)) { - process_midi_basic_noteoff(midi_compute_note(sequencer_config.track_notes[sequencer_internal_state.current_track])); - } -#endif - if (sequencer_internal_state.current_track > 0) { - sequencer_internal_state.current_track--; - } else { - sequencer_internal_state.phase = SEQUENCER_PHASE_PAUSE; - } -} - -void sequencer_phase_pause(void) { - if (timer_elapsed(sequencer_internal_state.timer) < sequencer_get_step_duration()) { - return; - } - - sequencer_internal_state.current_step = (sequencer_internal_state.current_step + 1) % SEQUENCER_STEPS; - sequencer_internal_state.phase = SEQUENCER_PHASE_ATTACK; -} - -void sequencer_task(void) { - if (!sequencer_config.enabled) { - return; - } - - if (sequencer_internal_state.phase == SEQUENCER_PHASE_PAUSE) { - sequencer_phase_pause(); - } - - if (sequencer_internal_state.phase == SEQUENCER_PHASE_RELEASE) { - sequencer_phase_release(); - } - - if (sequencer_internal_state.phase == SEQUENCER_PHASE_ATTACK) { - sequencer_phase_attack(); - } -} - -uint16_t sequencer_get_beat_duration(void) { - return get_beat_duration(sequencer_config.tempo); -} - -uint16_t sequencer_get_step_duration(void) { - return get_step_duration(sequencer_config.tempo, sequencer_config.resolution); -} - -uint16_t get_beat_duration(uint8_t tempo) { - // Don’t crash in the unlikely case where the given tempo is 0 - if (tempo == 0) { - return get_beat_duration(60); - } - - /** - * Given - * t = tempo and d = duration, both strictly greater than 0 - * When - * t beats / minute = 1 beat / d ms - * Then - * t beats / 60000ms = 1 beat / d ms - * d ms = 60000ms / t - */ - return 60000 / tempo; -} - -uint16_t get_step_duration(uint8_t tempo, sequencer_resolution_t resolution) { - /** - * Resolution cheatsheet: - * 1/2 => 2 steps per 4 beats - * 1/2T => 3 steps per 4 beats - * 1/4 => 4 steps per 4 beats - * 1/4T => 6 steps per 4 beats - * 1/8 => 8 steps per 4 beats - * 1/8T => 12 steps per 4 beats - * 1/16 => 16 steps per 4 beats - * 1/16T => 24 steps per 4 beats - * 1/32 => 32 steps per 4 beats - * - * The number of steps for binary resolutions follows the powers of 2. - * The ternary variants are simply 1.5x faster. - */ - bool is_binary = resolution % 2 == 0; - uint8_t binary_steps = 2 << (resolution / 2); - uint16_t binary_step_duration = get_beat_duration(tempo) * 4 / binary_steps; - - return is_binary ? binary_step_duration : 2 * binary_step_duration / 3; -} diff --git a/quantum/sequencer/sequencer.h b/quantum/sequencer/sequencer.h deleted file mode 100644 index a6498ed4131a..000000000000 --- a/quantum/sequencer/sequencer.h +++ /dev/null @@ -1,132 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#pragma once - -#include -#include - -// Maximum number of steps: 256 -#ifndef SEQUENCER_STEPS -# define SEQUENCER_STEPS 16 -#endif - -// Maximum number of tracks: 8 -#ifndef SEQUENCER_TRACKS -# define SEQUENCER_TRACKS 8 -#endif - -#ifndef SEQUENCER_TRACK_THROTTLE -# define SEQUENCER_TRACK_THROTTLE 3 -#endif - -#ifndef SEQUENCER_PHASE_RELEASE_TIMEOUT -# define SEQUENCER_PHASE_RELEASE_TIMEOUT 30 -#endif - -/** - * Make sure that the items of this enumeration follow the powers of 2, separated by a ternary variant. - * Check the implementation of `get_step_duration` for further explanation. - */ -typedef enum { - SQ_RES_2, // - SQ_RES_2T, - SQ_RES_4, - SQ_RES_4T, - SQ_RES_8, - SQ_RES_8T, - SQ_RES_16, - SQ_RES_16T, - SQ_RES_32, - SEQUENCER_RESOLUTIONS -} sequencer_resolution_t; - -typedef struct { - bool enabled; - uint8_t steps[SEQUENCER_STEPS]; - uint16_t track_notes[SEQUENCER_TRACKS]; - uint8_t tempo; // Is a maximum tempo of 255 reasonable? - sequencer_resolution_t resolution; -} sequencer_config_t; - -/** - * Because Digital Audio Workstations get overwhelmed when too many MIDI signals are sent concurrently, - * We use a "phase" state machine to delay some of the events. - */ -typedef enum sequencer_phase_t { - SEQUENCER_PHASE_ATTACK, // t=0ms, send the MIDI note on signal - SEQUENCER_PHASE_RELEASE, // t=SEQUENCER_PHASE_RELEASE_TIMEOUT ms, send the MIDI note off signal - SEQUENCER_PHASE_PAUSE // t=step duration ms, loop -} sequencer_phase_t; - -typedef struct { - uint8_t active_tracks; - uint8_t current_track; - uint8_t current_step; - uint16_t timer; - sequencer_phase_t phase; -} sequencer_state_t; - -extern sequencer_config_t sequencer_config; - -// We expose the internal state to make the feature more "unit-testable" -extern sequencer_state_t sequencer_internal_state; - -bool is_sequencer_on(void); -void sequencer_toggle(void); -void sequencer_on(void); -void sequencer_off(void); - -void sequencer_set_track_notes(const uint16_t track_notes[SEQUENCER_TRACKS]); - -bool is_sequencer_track_active(uint8_t track); -void sequencer_set_track_activation(uint8_t track, bool value); -void sequencer_toggle_track_activation(uint8_t track); -void sequencer_toggle_single_active_track(uint8_t track); - -#define sequencer_activate_track(track) sequencer_set_track_activation(track, true) -#define sequencer_deactivate_track(track) sequencer_set_track_activation(track, false) - -bool is_sequencer_step_on(uint8_t step); -bool is_sequencer_step_on_for_track(uint8_t step, uint8_t track); -void sequencer_set_step(uint8_t step, bool value); -void sequencer_toggle_step(uint8_t step); -void sequencer_set_all_steps(bool value); - -#define sequencer_set_step_on(step) sequencer_set_step(step, true) -#define sequencer_set_step_off(step) sequencer_set_step(step, false) -#define sequencer_set_all_steps_on() sequencer_set_all_steps(true) -#define sequencer_set_all_steps_off() sequencer_set_all_steps(false) - -uint8_t sequencer_get_tempo(void); -void sequencer_set_tempo(uint8_t tempo); -void sequencer_increase_tempo(void); -void sequencer_decrease_tempo(void); - -sequencer_resolution_t sequencer_get_resolution(void); -void sequencer_set_resolution(sequencer_resolution_t resolution); -void sequencer_increase_resolution(void); -void sequencer_decrease_resolution(void); - -uint8_t sequencer_get_current_step(void); - -uint16_t sequencer_get_beat_duration(void); -uint16_t sequencer_get_step_duration(void); - -uint16_t get_beat_duration(uint8_t tempo); -uint16_t get_step_duration(uint8_t tempo, sequencer_resolution_t resolution); - -void sequencer_task(void); diff --git a/quantum/sequencer/tests/midi_mock.c b/quantum/sequencer/tests/midi_mock.c deleted file mode 100644 index 5bd945d615c0..000000000000 --- a/quantum/sequencer/tests/midi_mock.c +++ /dev/null @@ -1,32 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#include "midi_mock.h" - -uint16_t last_noteon = 0; -uint16_t last_noteoff = 0; - -uint16_t midi_compute_note(uint16_t keycode) { - return keycode; -} - -void process_midi_basic_noteon(uint16_t note) { - last_noteon = note; -} - -void process_midi_basic_noteoff(uint16_t note) { - last_noteoff = note; -} diff --git a/quantum/sequencer/tests/midi_mock.h b/quantum/sequencer/tests/midi_mock.h deleted file mode 100644 index 4d8c2eb307b4..000000000000 --- a/quantum/sequencer/tests/midi_mock.h +++ /dev/null @@ -1,26 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#pragma once - -#include - -extern uint16_t last_noteon; -extern uint16_t last_noteoff; - -uint16_t midi_compute_note(uint16_t keycode); -void process_midi_basic_noteon(uint16_t note); -void process_midi_basic_noteoff(uint16_t note); diff --git a/quantum/sequencer/tests/rules.mk b/quantum/sequencer/tests/rules.mk deleted file mode 100644 index 611459e060e3..000000000000 --- a/quantum/sequencer/tests/rules.mk +++ /dev/null @@ -1,11 +0,0 @@ -# The letter case of these variables might seem odd. However: -# - it is consistent with the example that is used as a reference in the Unit Testing article (https://docs.qmk.fm/#/unit_testing?id=adding-tests-for-new-or-existing-features) -# - Neither `make test:sequencer` or `make test:SEQUENCER` work when using SCREAMING_SNAKE_CASE - -sequencer_DEFS := -DMATRIX_ROWS=1 -DMATRIX_COLS=1 -DNO_DEBUG -DMIDI_MOCKED - -sequencer_SRC := \ - $(QUANTUM_PATH)/sequencer/tests/midi_mock.c \ - $(QUANTUM_PATH)/sequencer/tests/sequencer_tests.cpp \ - $(QUANTUM_PATH)/sequencer/sequencer.c \ - $(PLATFORM_PATH)/$(PLATFORM_KEY)/timer.c diff --git a/quantum/sequencer/tests/sequencer_tests.cpp b/quantum/sequencer/tests/sequencer_tests.cpp deleted file mode 100644 index 79ec10cabf8b..000000000000 --- a/quantum/sequencer/tests/sequencer_tests.cpp +++ /dev/null @@ -1,592 +0,0 @@ -/* Copyright 2020 Rodolphe Belouin - * - * 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 . - */ - -#include "gtest/gtest.h" - -extern "C" { -#include "sequencer.h" -#include "midi_mock.h" -#include "quantum/quantum_keycodes.h" -} - -extern "C" { -void set_time(uint32_t t); -void advance_time(uint32_t ms); -} - -class SequencerTest : public ::testing::Test { - protected: - void SetUp() override { - config_copy.enabled = sequencer_config.enabled; - - for (int i = 0; i < SEQUENCER_STEPS; i++) { - config_copy.steps[i] = sequencer_config.steps[i]; - } - - for (int i = 0; i < SEQUENCER_TRACKS; i++) { - config_copy.track_notes[i] = sequencer_config.track_notes[i]; - } - - config_copy.tempo = sequencer_config.tempo; - config_copy.resolution = sequencer_config.resolution; - - state_copy.active_tracks = sequencer_internal_state.active_tracks; - state_copy.current_track = sequencer_internal_state.current_track; - state_copy.current_step = sequencer_internal_state.current_step; - state_copy.timer = sequencer_internal_state.timer; - - last_noteon = 0; - last_noteoff = 0; - - set_time(0); - } - - void TearDown() override { - sequencer_config.enabled = config_copy.enabled; - - for (int i = 0; i < SEQUENCER_STEPS; i++) { - sequencer_config.steps[i] = config_copy.steps[i]; - } - - for (int i = 0; i < SEQUENCER_TRACKS; i++) { - sequencer_config.track_notes[i] = config_copy.track_notes[i]; - } - - sequencer_config.tempo = config_copy.tempo; - sequencer_config.resolution = config_copy.resolution; - - sequencer_internal_state.active_tracks = state_copy.active_tracks; - sequencer_internal_state.current_track = state_copy.current_track; - sequencer_internal_state.current_step = state_copy.current_step; - sequencer_internal_state.timer = state_copy.timer; - } - - sequencer_config_t config_copy; - sequencer_state_t state_copy; -}; - -TEST_F(SequencerTest, TestOffByDefault) { - EXPECT_EQ(is_sequencer_on(), false); -} - -TEST_F(SequencerTest, TestOn) { - sequencer_config.enabled = false; - - sequencer_on(); - EXPECT_EQ(is_sequencer_on(), true); - - // sequencer_on is idempotent - sequencer_on(); - EXPECT_EQ(is_sequencer_on(), true); -} - -TEST_F(SequencerTest, TestOff) { - sequencer_config.enabled = true; - - sequencer_off(); - EXPECT_EQ(is_sequencer_on(), false); - - // sequencer_off is idempotent - sequencer_off(); - EXPECT_EQ(is_sequencer_on(), false); -} - -TEST_F(SequencerTest, TestToggle) { - sequencer_config.enabled = false; - - sequencer_toggle(); - EXPECT_EQ(is_sequencer_on(), true); - - sequencer_toggle(); - EXPECT_EQ(is_sequencer_on(), false); -} - -TEST_F(SequencerTest, TestNoActiveTrackByDefault) { - for (int i = 0; i < SEQUENCER_TRACKS; i++) { - EXPECT_EQ(is_sequencer_track_active(i), false); - } -} - -TEST_F(SequencerTest, TestGetActiveTracks) { - sequencer_internal_state.active_tracks = (1 << 7) + (1 << 6) + (1 << 3) + (1 << 1) + (1 << 0); - - EXPECT_EQ(is_sequencer_track_active(0), true); - EXPECT_EQ(is_sequencer_track_active(1), true); - EXPECT_EQ(is_sequencer_track_active(2), false); - EXPECT_EQ(is_sequencer_track_active(3), true); - EXPECT_EQ(is_sequencer_track_active(4), false); - EXPECT_EQ(is_sequencer_track_active(5), false); - EXPECT_EQ(is_sequencer_track_active(6), true); - EXPECT_EQ(is_sequencer_track_active(7), true); -} - -TEST_F(SequencerTest, TestGetActiveTracksOutOfBound) { - sequencer_set_track_activation(-1, true); - sequencer_set_track_activation(8, true); - - EXPECT_EQ(is_sequencer_track_active(-1), false); - EXPECT_EQ(is_sequencer_track_active(8), false); -} - -TEST_F(SequencerTest, TestToggleTrackActivation) { - sequencer_internal_state.active_tracks = (1 << 7) + (1 << 6) + (1 << 3) + (1 << 1) + (1 << 0); - - sequencer_toggle_track_activation(6); - - EXPECT_EQ(is_sequencer_track_active(0), true); - EXPECT_EQ(is_sequencer_track_active(1), true); - EXPECT_EQ(is_sequencer_track_active(2), false); - EXPECT_EQ(is_sequencer_track_active(3), true); - EXPECT_EQ(is_sequencer_track_active(4), false); - EXPECT_EQ(is_sequencer_track_active(5), false); - EXPECT_EQ(is_sequencer_track_active(6), false); - EXPECT_EQ(is_sequencer_track_active(7), true); -} - -TEST_F(SequencerTest, TestToggleSingleTrackActivation) { - sequencer_internal_state.active_tracks = (1 << 7) + (1 << 6) + (1 << 3) + (1 << 1) + (1 << 0); - - sequencer_toggle_single_active_track(2); - - EXPECT_EQ(is_sequencer_track_active(0), false); - EXPECT_EQ(is_sequencer_track_active(1), false); - EXPECT_EQ(is_sequencer_track_active(2), true); - EXPECT_EQ(is_sequencer_track_active(3), false); - EXPECT_EQ(is_sequencer_track_active(4), false); - EXPECT_EQ(is_sequencer_track_active(5), false); - EXPECT_EQ(is_sequencer_track_active(6), false); - EXPECT_EQ(is_sequencer_track_active(7), false); -} - -TEST_F(SequencerTest, TestStepOffByDefault) { - for (int i = 0; i < SEQUENCER_STEPS; i++) { - EXPECT_EQ(is_sequencer_step_on(i), false); - } -} - -TEST_F(SequencerTest, TestIsStepOffWithNoActiveTracks) { - sequencer_config.steps[3] = 0xFF; - EXPECT_EQ(is_sequencer_step_on(3), false); -} - -TEST_F(SequencerTest, TestIsStepOffWithGivenActiveTracks) { - sequencer_set_track_activation(2, true); - sequencer_set_track_activation(3, true); - - sequencer_config.steps[3] = (1 << 0) + (1 << 1); - - // No active tracks have the step enabled, so it is off - EXPECT_EQ(is_sequencer_step_on(3), false); -} - -TEST_F(SequencerTest, TestIsStepOnWithGivenActiveTracks) { - sequencer_set_track_activation(2, true); - sequencer_set_track_activation(3, true); - - sequencer_config.steps[3] = (1 << 2); - - // Track 2 has the step enabled, so it is on - EXPECT_EQ(is_sequencer_step_on(3), true); -} - -TEST_F(SequencerTest, TestIsStepOffForGivenTrack) { - sequencer_config.steps[3] = 0x00; - EXPECT_EQ(is_sequencer_step_on_for_track(3, 5), false); -} - -TEST_F(SequencerTest, TestIsStepOnForGivenTrack) { - sequencer_config.steps[3] = (1 << 5); - EXPECT_EQ(is_sequencer_step_on_for_track(3, 5), true); -} - -TEST_F(SequencerTest, TestSetStepOn) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = (1 << 5) + (1 << 2); - - sequencer_set_step(2, true); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 6) + (1 << 5) + (1 << 3) + (1 << 2)); -} - -TEST_F(SequencerTest, TestSetStepOff) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = (1 << 5) + (1 << 2); - - sequencer_set_step(2, false); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 5)); -} - -TEST_F(SequencerTest, TestToggleStepOff) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = (1 << 5) + (1 << 2); - - sequencer_toggle_step(2); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 5)); -} - -TEST_F(SequencerTest, TestToggleStepOn) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = 0; - - sequencer_toggle_step(2); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 6) + (1 << 3) + (1 << 2)); -} - -TEST_F(SequencerTest, TestSetAllStepsOn) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = (1 << 7) + (1 << 6); - sequencer_config.steps[4] = (1 << 3) + (1 << 1); - - sequencer_set_all_steps(true); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 7) + (1 << 6) + (1 << 3) + (1 << 2)); - EXPECT_EQ(sequencer_config.steps[4], (1 << 6) + (1 << 3) + (1 << 2) + (1 << 1)); -} - -TEST_F(SequencerTest, TestSetAllStepsOff) { - sequencer_internal_state.active_tracks = (1 << 6) + (1 << 3) + (1 << 2); - sequencer_config.steps[2] = (1 << 7) + (1 << 6); - sequencer_config.steps[4] = (1 << 3) + (1 << 1); - - sequencer_set_all_steps(false); - - EXPECT_EQ(sequencer_config.steps[2], (1 << 7)); - EXPECT_EQ(sequencer_config.steps[4], (1 << 1)); -} - -TEST_F(SequencerTest, TestSetTempoZero) { - sequencer_config.tempo = 123; - - sequencer_set_tempo(0); - - EXPECT_EQ(sequencer_config.tempo, 123); -} - -TEST_F(SequencerTest, TestIncreaseTempoMax) { - sequencer_config.tempo = UINT8_MAX; - - sequencer_increase_tempo(); - - EXPECT_EQ(sequencer_config.tempo, UINT8_MAX); -} - -TEST_F(SequencerTest, TestSetResolutionLowerBound) { - sequencer_config.resolution = SQ_RES_4; - - sequencer_set_resolution((sequencer_resolution_t)-1); - - EXPECT_EQ(sequencer_config.resolution, SQ_RES_4); -} - -TEST_F(SequencerTest, TestSetResolutionUpperBound) { - sequencer_config.resolution = SQ_RES_4; - - sequencer_set_resolution(SEQUENCER_RESOLUTIONS); - - EXPECT_EQ(sequencer_config.resolution, SQ_RES_4); -} - -TEST_F(SequencerTest, TestGetBeatDuration) { - EXPECT_EQ(get_beat_duration(60), 1000); - EXPECT_EQ(get_beat_duration(120), 500); - EXPECT_EQ(get_beat_duration(240), 250); - EXPECT_EQ(get_beat_duration(0), 1000); -} - -TEST_F(SequencerTest, TestGetStepDuration60) { - /** - * Resolution cheatsheet: - * 1/2 => 2 steps per 4 beats - * 1/2T => 3 steps per 4 beats - * 1/4 => 4 steps per 4 beats - * 1/4T => 6 steps per 4 beats - * 1/8 => 8 steps per 4 beats - * 1/8T => 12 steps per 4 beats - * 1/16 => 16 steps per 4 beats - * 1/16T => 24 steps per 4 beats - * 1/32 => 32 steps per 4 beats - * - * The number of steps for binary resolutions follows the powers of 2. - * The ternary variants are simply 1.5x faster. - */ - EXPECT_EQ(get_step_duration(60, SQ_RES_2), 2000); - EXPECT_EQ(get_step_duration(60, SQ_RES_4), 1000); - EXPECT_EQ(get_step_duration(60, SQ_RES_8), 500); - EXPECT_EQ(get_step_duration(60, SQ_RES_16), 250); - EXPECT_EQ(get_step_duration(60, SQ_RES_32), 125); - - EXPECT_EQ(get_step_duration(60, SQ_RES_2T), 1333); - EXPECT_EQ(get_step_duration(60, SQ_RES_4T), 666); - EXPECT_EQ(get_step_duration(60, SQ_RES_8T), 333); - EXPECT_EQ(get_step_duration(60, SQ_RES_16T), 166); -} - -TEST_F(SequencerTest, TestGetStepDuration120) { - /** - * Resolution cheatsheet: - * 1/2 => 2 steps per 4 beats - * 1/2T => 3 steps per 4 beats - * 1/4 => 4 steps per 4 beats - * 1/4T => 6 steps per 4 beats - * 1/8 => 8 steps per 4 beats - * 1/8T => 12 steps per 4 beats - * 1/16 => 16 steps per 4 beats - * 1/16T => 24 steps per 4 beats - * 1/32 => 32 steps per 4 beats - * - * The number of steps for binary resolutions follows the powers of 2. - * The ternary variants are simply 1.5x faster. - */ - EXPECT_EQ(get_step_duration(30, SQ_RES_2), 4000); - EXPECT_EQ(get_step_duration(30, SQ_RES_4), 2000); - EXPECT_EQ(get_step_duration(30, SQ_RES_8), 1000); - EXPECT_EQ(get_step_duration(30, SQ_RES_16), 500); - EXPECT_EQ(get_step_duration(30, SQ_RES_32), 250); - - EXPECT_EQ(get_step_duration(30, SQ_RES_2T), 2666); - EXPECT_EQ(get_step_duration(30, SQ_RES_4T), 1333); - EXPECT_EQ(get_step_duration(30, SQ_RES_8T), 666); - EXPECT_EQ(get_step_duration(30, SQ_RES_16T), 333); -} - -void setUpMatrixScanSequencerTest(void) { - sequencer_config.enabled = true; - sequencer_config.tempo = 120; - sequencer_config.resolution = SQ_RES_16; - - // Configure the notes for each track - sequencer_config.track_notes[0] = QK_MIDI_NOTE_C_0; - sequencer_config.track_notes[1] = QK_MIDI_NOTE_D_0; - sequencer_config.track_notes[2] = QK_MIDI_NOTE_E_0; - sequencer_config.track_notes[3] = QK_MIDI_NOTE_F_0; - sequencer_config.track_notes[4] = QK_MIDI_NOTE_G_0; - sequencer_config.track_notes[5] = QK_MIDI_NOTE_A_0; - sequencer_config.track_notes[6] = QK_MIDI_NOTE_B_0; - sequencer_config.track_notes[7] = QK_MIDI_NOTE_C_0; - - // Turn on some steps - sequencer_config.steps[0] = (1 << 0); - sequencer_config.steps[2] = (1 << 1) + (1 << 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldAttackFirstTrackOfFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_task(); - EXPECT_EQ(last_noteon, QK_MIDI_NOTE_C_0); - EXPECT_EQ(last_noteoff, 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldAttackSecondTrackAfterFirstTrackOfFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, 1); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_ATTACK); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldNotAttackInactiveTrackFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = 1; - - // Wait some time after the first track has been attacked - advance_time(SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(last_noteon, 0); - EXPECT_EQ(last_noteoff, 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldAttackThirdTrackAfterSecondTrackOfFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = 1; - - // Wait some time after the second track has been attacked - advance_time(2 * SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, 2); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_ATTACK); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldEnterReleasePhaseAfterLastTrackHasBeenProcessedFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = SEQUENCER_TRACKS - 1; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(last_noteon, 0); - EXPECT_EQ(last_noteoff, 0); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, SEQUENCER_TRACKS - 1); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_RELEASE); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldReleaseBackwards) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = SEQUENCER_TRACKS - 1; - sequencer_internal_state.phase = SEQUENCER_PHASE_RELEASE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, SEQUENCER_TRACKS - 2); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_RELEASE); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldNotReleaseInactiveTrackFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = SEQUENCER_TRACKS - 1; - sequencer_internal_state.phase = SEQUENCER_PHASE_RELEASE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - - sequencer_task(); - EXPECT_EQ(last_noteon, 0); - EXPECT_EQ(last_noteoff, 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldReleaseFirstTrackFirstStep) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = 0; - sequencer_internal_state.phase = SEQUENCER_PHASE_RELEASE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - // + all the other notes have been released - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(last_noteon, 0); - EXPECT_EQ(last_noteoff, QK_MIDI_NOTE_C_0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldEnterPausePhaseAfterRelease) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = 0; - sequencer_internal_state.phase = SEQUENCER_PHASE_RELEASE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - // + all the other notes have been released - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, 0); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_PAUSE); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldProcessFirstTrackOfSecondStepAfterPause) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 0; - sequencer_internal_state.current_track = 0; - sequencer_internal_state.phase = SEQUENCER_PHASE_PAUSE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - // + all the other notes have been released - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the step duration (one 16th at tempo=120 lasts 125ms) - advance_time(125); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 1); - EXPECT_EQ(sequencer_internal_state.current_track, 1); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_ATTACK); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldProcessSecondTrackTooEarly) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 2; - sequencer_internal_state.current_track = 1; - - sequencer_task(); - EXPECT_EQ(last_noteon, 0); - EXPECT_EQ(last_noteoff, 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldProcessSecondTrackOnTime) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = 2; - sequencer_internal_state.current_track = 1; - - // Wait until first track has been attacked - advance_time(SEQUENCER_TRACK_THROTTLE); - - sequencer_task(); - EXPECT_EQ(last_noteon, QK_MIDI_NOTE_D_0); - EXPECT_EQ(last_noteoff, 0); -} - -TEST_F(SequencerTest, TestMatrixScanSequencerShouldLoopOnceSequenceIsOver) { - setUpMatrixScanSequencerTest(); - - sequencer_internal_state.current_step = SEQUENCER_STEPS - 1; - sequencer_internal_state.current_track = 0; - sequencer_internal_state.phase = SEQUENCER_PHASE_PAUSE; - - // Wait until all notes have been attacked - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the release timeout - advance_time(SEQUENCER_PHASE_RELEASE_TIMEOUT); - // + all the other notes have been released - advance_time((SEQUENCER_TRACKS - 1) * SEQUENCER_TRACK_THROTTLE); - // + the step duration (one 16th at tempo=120 lasts 125ms) - advance_time(125); - - sequencer_task(); - EXPECT_EQ(sequencer_internal_state.current_step, 0); - EXPECT_EQ(sequencer_internal_state.current_track, 1); - EXPECT_EQ(sequencer_internal_state.phase, SEQUENCER_PHASE_ATTACK); -} diff --git a/quantum/sequencer/tests/testlist.mk b/quantum/sequencer/tests/testlist.mk deleted file mode 100644 index bb3899110922..000000000000 --- a/quantum/sequencer/tests/testlist.mk +++ /dev/null @@ -1 +0,0 @@ -TEST_LIST += sequencer diff --git a/quantum/split_common/eeprom-lefthand.eep b/quantum/split_common/eeprom-lefthand.eep deleted file mode 100644 index bda23cdb6e90..000000000000 --- a/quantum/split_common/eeprom-lefthand.eep +++ /dev/null @@ -1,2 +0,0 @@ -:0F000000000000000000000000000000000001F0 -:00000001FF diff --git a/quantum/split_common/eeprom-righthand.eep b/quantum/split_common/eeprom-righthand.eep deleted file mode 100644 index 549cd1ef0aa1..000000000000 --- a/quantum/split_common/eeprom-righthand.eep +++ /dev/null @@ -1,2 +0,0 @@ -:0F000000000000000000000000000000000000F1 -:00000001FF diff --git a/quantum/split_common/post_config.h b/quantum/split_common/post_config.h deleted file mode 100644 index 8f79beb6eda6..000000000000 --- a/quantum/split_common/post_config.h +++ /dev/null @@ -1,10 +0,0 @@ -#if defined(USE_I2C) -// When using I2C, using rgblight implicitly involves split support. -# if defined(RGBLIGHT_ENABLE) && !defined(RGBLIGHT_SPLIT) -# define RGBLIGHT_SPLIT -# endif - -# ifndef F_SCL -# define F_SCL 100000UL // SCL frequency -# endif -#endif diff --git a/quantum/split_common/split_util.c b/quantum/split_common/split_util.c deleted file mode 100644 index a43138345402..000000000000 --- a/quantum/split_common/split_util.c +++ /dev/null @@ -1,263 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 3 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 . - */ -#include "split_util.h" -#include "matrix.h" -#include "keyboard.h" -#include "timer.h" -#include "transport.h" -#include "quantum.h" -#include "wait.h" -#include "usb_util.h" - -#ifdef EE_HANDS -# include "eeconfig.h" -#endif - -#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT) -# include "rgblight.h" -#endif - -#ifndef SPLIT_USB_TIMEOUT -# define SPLIT_USB_TIMEOUT 2000 -#endif - -#ifndef SPLIT_USB_TIMEOUT_POLL -# define SPLIT_USB_TIMEOUT_POLL 10 -#endif - -// Max number of consecutive failed communications (one per scan cycle) before the communication is seen as disconnected. -// Set to 0 to disable the disconnection check altogether. -#ifndef SPLIT_MAX_CONNECTION_ERRORS -# define SPLIT_MAX_CONNECTION_ERRORS 10 -#endif // SPLIT_MAX_CONNECTION_ERRORS - -// How long (in milliseconds) to block all connection attempts after the communication has been flagged as disconnected. -// One communication attempt will be allowed everytime this amount of time has passed since the last attempt. If that attempt succeeds, the communication is seen as working again. -// Set to 0 to disable communication throttling while disconnected -#ifndef SPLIT_CONNECTION_CHECK_TIMEOUT -# define SPLIT_CONNECTION_CHECK_TIMEOUT 500 -#endif // SPLIT_CONNECTION_CHECK_TIMEOUT - -static uint8_t connection_errors = 0; - -volatile bool isLeftHand = true; - -#if defined(SPLIT_USB_DETECT) -_Static_assert((SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL) <= UINT16_MAX, "Please lower SPLIT_USB_TIMEOUT and/or increase SPLIT_USB_TIMEOUT_POLL."); -static bool usbIsActive(void) { - for (uint16_t i = 0; i < (SPLIT_USB_TIMEOUT / SPLIT_USB_TIMEOUT_POLL); i++) { - // This will return true if a USB connection has been established - if (usb_connected_state()) { - return true; - } - wait_ms(SPLIT_USB_TIMEOUT_POLL); - } - return false; -} -#else -static inline bool usbIsActive(void) { - return usb_vbus_state(); -} -#endif - -#if defined(SPLIT_WATCHDOG_ENABLE) -# if !defined(SPLIT_WATCHDOG_TIMEOUT) -# if defined(SPLIT_USB_TIMEOUT) -# define SPLIT_WATCHDOG_TIMEOUT (SPLIT_USB_TIMEOUT + 100) -# else -# define SPLIT_WATCHDOG_TIMEOUT 3000 -# endif -# endif -# if defined(SPLIT_USB_DETECT) -_Static_assert(SPLIT_USB_TIMEOUT < SPLIT_WATCHDOG_TIMEOUT, "SPLIT_WATCHDOG_TIMEOUT should not be below SPLIT_USB_TIMEOUT."); -# endif -_Static_assert(SPLIT_MAX_CONNECTION_ERRORS > 0, "SPLIT_WATCHDOG_ENABLE requires SPLIT_MAX_CONNECTION_ERRORS be above 0 for a functioning disconnection check."); - -static uint32_t split_watchdog_started = 0; -static bool split_watchdog_done = false; - -void split_watchdog_init(void) { - split_watchdog_started = timer_read32(); -} - -void split_watchdog_update(bool done) { - split_watchdog_done = done; -} - -bool split_watchdog_check(void) { - if (!is_transport_connected()) { - split_watchdog_done = false; - } - return split_watchdog_done; -} - -void split_watchdog_task(void) { - if (!split_watchdog_done && !is_keyboard_master()) { - if (timer_elapsed32(split_watchdog_started) > SPLIT_WATCHDOG_TIMEOUT) { - mcu_reset(); - } - } -} -#endif // defined(SPLIT_WATCHDOG_ENABLE) - -#ifdef SPLIT_HAND_MATRIX_GRID -void matrix_io_delay(void); - -static uint8_t peek_matrix_intersection(pin_t out_pin, pin_t in_pin) { - setPinInputHigh(in_pin); - setPinOutput(out_pin); - writePinLow(out_pin); - // It's almost unnecessary, but wait until it's down to low, just in case. - wait_us(1); - uint8_t pin_state = readPin(in_pin); - // Set out_pin to a setting that is less susceptible to noise. - setPinInputHigh(out_pin); - matrix_io_delay(); // Wait for the pull-up to go HIGH. - return pin_state; -} -#endif - -__attribute__((weak)) bool is_keyboard_left(void) { -#if defined(SPLIT_HAND_PIN) - // Test pin SPLIT_HAND_PIN for High/Low, if low it's right hand -# ifdef SPLIT_HAND_PIN_LOW_IS_LEFT - return !readPin(SPLIT_HAND_PIN); -# else - return readPin(SPLIT_HAND_PIN); -# endif -#elif defined(SPLIT_HAND_MATRIX_GRID) -# ifdef SPLIT_HAND_MATRIX_GRID_LOW_IS_RIGHT - return peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); -# else - return !peek_matrix_intersection(SPLIT_HAND_MATRIX_GRID); -# endif -#elif defined(EE_HANDS) - return eeconfig_read_handedness(); -#elif defined(MASTER_RIGHT) - return !is_keyboard_master(); -#endif - - return is_keyboard_master(); -} - -__attribute__((weak)) bool is_keyboard_master(void) { - static enum { UNKNOWN, MASTER, SLAVE } usbstate = UNKNOWN; - - // only check once, as this is called often - if (usbstate == UNKNOWN) { - usbstate = usbIsActive() ? MASTER : SLAVE; - - // Avoid NO_USB_STARTUP_CHECK - Disable USB as the previous checks seem to enable it somehow - if (usbstate == SLAVE) { - usb_disconnect(); - } - } - - return (usbstate == MASTER); -} - -// this code runs before the keyboard is fully initialized -void split_pre_init(void) { -#if defined(SPLIT_HAND_PIN) - setPinInput(SPLIT_HAND_PIN); - wait_us(100); -#elif defined(EE_HANDS) - if (!eeconfig_is_enabled()) { - eeconfig_init(); - } - // TODO: Remove once ARM has a way to configure EECONFIG_HANDEDNESS within the emulated eeprom via dfu-util or another tool -# if defined(INIT_EE_HANDS_LEFT) || defined(INIT_EE_HANDS_RIGHT) -# if defined(INIT_EE_HANDS_LEFT) -# pragma message "Faking EE_HANDS for left hand" - const bool should_be_left = true; -# else -# pragma message "Faking EE_HANDS for right hand" - const bool should_be_left = false; -# endif - bool is_left = eeconfig_read_handedness(); - if (is_left != should_be_left) { - eeconfig_update_handedness(should_be_left); - } -# endif // defined(INIT_EE_HANDS_LEFT) || defined(INIT_EE_HANDS_RIGHT) -#endif - isLeftHand = is_keyboard_left(); - -#if defined(RGBLIGHT_ENABLE) && defined(RGBLED_SPLIT) - uint8_t num_rgb_leds_split[2] = RGBLED_SPLIT; - if (isLeftHand) { - rgblight_set_clipping_range(0, num_rgb_leds_split[0]); - } else { - rgblight_set_clipping_range(num_rgb_leds_split[0], num_rgb_leds_split[1]); - } -#endif - - if (is_keyboard_master()) { -#if defined(USE_I2C) && defined(SSD1306OLED) - matrix_master_OLED_init(); -#endif - transport_master_init(); - } -} - -// this code runs after the keyboard is fully initialized -// - avoids race condition during matrix_init_quantum where slave can start -// receiving before the init process has completed -void split_post_init(void) { - if (!is_keyboard_master()) { - transport_slave_init(); -#if defined(SPLIT_WATCHDOG_ENABLE) - split_watchdog_init(); -#endif - } -} - -bool is_transport_connected(void) { - return connection_errors < SPLIT_MAX_CONNECTION_ERRORS; -} - -bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { -#if SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 - // Throttle transaction attempts if target doesn't seem to be connected - // Without this, a solo half becomes unusable due to constant read timeouts - static uint16_t connection_check_timer = 0; - const bool is_disconnected = !is_transport_connected(); - if (is_disconnected && timer_elapsed(connection_check_timer) < SPLIT_CONNECTION_CHECK_TIMEOUT) { - return false; - } -#endif // SPLIT_MAX_CONNECTION_ERRORS > 0 && SPLIT_CONNECTION_CHECK_TIMEOUT > 0 - - __attribute__((unused)) bool okay = transport_master(master_matrix, slave_matrix); -#if SPLIT_MAX_CONNECTION_ERRORS > 0 - if (!okay) { - if (connection_errors < UINT8_MAX) { - connection_errors++; - } -# if SPLIT_CONNECTION_CHECK_TIMEOUT > 0 - bool connected = is_transport_connected(); - if (!connected) { - connection_check_timer = timer_read(); - dprintln("Target disconnected, throttling connection attempts"); - } - return connected; - } else if (is_disconnected) { - dprintln("Target connected"); -# endif // SPLIT_CONNECTION_CHECK_TIMEOUT > 0 - } - - connection_errors = 0; -#endif // SPLIT_MAX_CONNECTION_ERRORS > 0 - return true; -} diff --git a/quantum/split_common/split_util.h b/quantum/split_common/split_util.h deleted file mode 100644 index 5c9a260a14ab..000000000000 --- a/quantum/split_common/split_util.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once - -#include -#include -#include - -#include "matrix.h" - -extern volatile bool isLeftHand; - -void matrix_master_OLED_init(void); -void split_pre_init(void); -void split_post_init(void); - -bool transport_master_if_connected(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); -bool is_transport_connected(void); - -void split_watchdog_update(bool done); -void split_watchdog_task(void); -bool split_watchdog_check(void); \ No newline at end of file diff --git a/quantum/split_common/transaction_id_define.h b/quantum/split_common/transaction_id_define.h deleted file mode 100644 index 4d4d2b957084..000000000000 --- a/quantum/split_common/transaction_id_define.h +++ /dev/null @@ -1,124 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#pragma once - -enum serial_transaction_id { -#ifdef USE_I2C - I2C_EXECUTE_CALLBACK, -#endif // USE_I2C - - GET_SLAVE_MATRIX_CHECKSUM, - GET_SLAVE_MATRIX_DATA, - -#ifdef SPLIT_TRANSPORT_MIRROR - PUT_MASTER_MATRIX, -#endif // SPLIT_TRANSPORT_MIRROR - -#ifdef ENCODER_ENABLE - GET_ENCODERS_CHECKSUM, - GET_ENCODERS_DATA, -#endif // ENCODER_ENABLE - -#ifndef DISABLE_SYNC_TIMER - PUT_SYNC_TIMER, -#endif // DISABLE_SYNC_TIMER - -#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - PUT_LAYER_STATE, - PUT_DEFAULT_LAYER_STATE, -#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -#ifdef SPLIT_LED_STATE_ENABLE - PUT_LED_STATE, -#endif // SPLIT_LED_STATE_ENABLE - -#ifdef SPLIT_MODS_ENABLE - PUT_MODS, -#endif // SPLIT_MODS_ENABLE - -#ifdef BACKLIGHT_ENABLE - PUT_BACKLIGHT, -#endif // BACKLIGHT_ENABLE - -#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - PUT_RGBLIGHT, -#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - PUT_LED_MATRIX, -#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - PUT_RGB_MATRIX, -#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - PUT_WPM, -#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - PUT_OLED, -#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - -#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - PUT_ST7565, -#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - -#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - GET_POINTING_CHECKSUM, - GET_POINTING_DATA, - PUT_POINTING_CPI, -#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -#if defined(SPLIT_WATCHDOG_ENABLE) - PUT_WATCHDOG, -#endif // defined(SPLIT_WATCHDOG_ENABLE) - -#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - PUT_HAPTIC, -#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - -#if defined(SPLIT_ACTIVITY_ENABLE) - PUT_ACTIVITY, -#endif // SPLIT_ACTIVITY_ENABLE - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - PUT_RPC_INFO, - PUT_RPC_REQ_DATA, - EXECUTE_RPC, - GET_RPC_RESP_DATA, -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - -// keyboard-specific -#ifdef SPLIT_TRANSACTION_IDS_KB - SPLIT_TRANSACTION_IDS_KB, -#endif // SPLIT_TRANSACTION_IDS_KB - -// user/keymap-specific -#ifdef SPLIT_TRANSACTION_IDS_USER - SPLIT_TRANSACTION_IDS_USER, -#endif // SPLIT_TRANSACTION_IDS_USER - -#if defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - PUT_DETECTED_OS, -#endif // defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - - NUM_TOTAL_TRANSACTIONS -}; - -// Ensure we only use 5 bits for transaction -_Static_assert(NUM_TOTAL_TRANSACTIONS <= (1 << 5), "Max number of usable transactions exceeded"); diff --git a/quantum/split_common/transactions.c b/quantum/split_common/transactions.c deleted file mode 100644 index 8cd018a6ec07..000000000000 --- a/quantum/split_common/transactions.c +++ /dev/null @@ -1,1012 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#include -#include - -#include "crc.h" -#include "debug.h" -#include "matrix.h" -#include "quantum.h" -#include "transactions.h" -#include "transport.h" -#include "transaction_id_define.h" -#include "split_util.h" -#include "synchronization_util.h" - -#define SYNC_TIMER_OFFSET 2 - -#ifndef FORCED_SYNC_THROTTLE_MS -# define FORCED_SYNC_THROTTLE_MS 100 -#endif // FORCED_SYNC_THROTTLE_MS - -#define sizeof_member(type, member) sizeof(((type *)NULL)->member) - -#define trans_initiator2target_initializer_cb(member, cb) \ - { sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), 0, 0, cb } -#define trans_initiator2target_initializer(member) trans_initiator2target_initializer_cb(member, NULL) - -#define trans_target2initiator_initializer_cb(member, cb) \ - { 0, 0, sizeof_member(split_shared_memory_t, member), offsetof(split_shared_memory_t, member), cb } -#define trans_target2initiator_initializer(member) trans_target2initiator_initializer_cb(member, NULL) - -#define transport_write(id, data, length) transport_execute_transaction(id, data, length, NULL, 0) -#define transport_read(id, data, length) transport_execute_transaction(id, NULL, 0, data, length) - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) -// Forward-declare the RPC callback handlers -void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); -void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - -//////////////////////////////////////////////////// -// Helpers - -static bool transaction_handler_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[], const char *prefix, bool (*handler)(matrix_row_t master_matrix[], matrix_row_t slave_matrix[])) { - int num_retries = is_transport_connected() ? 10 : 1; - for (int iter = 1; iter <= num_retries; ++iter) { - if (iter > 1) { - for (int i = 0; i < iter * iter; ++i) { - wait_us(10); - } - } - bool this_okay = true; - this_okay = handler(master_matrix, slave_matrix); - if (this_okay) return true; - } - dprintf("Failed to execute %s\n", prefix); - return false; -} - -#define TRANSACTION_HANDLER_MASTER(prefix) \ - do { \ - if (!transaction_handler_master(master_matrix, slave_matrix, #prefix, &prefix##_handlers_master)) return false; \ - } while (0) - -/** - * @brief Constructs a transaction handler that doesn't acquire a lock to the - * split shared memory. Therefore the locking and unlocking has to be done - * manually inside the handler. Use this macro only if the handler is - * non-deterministic in runtime and thus needs a manual lock unlock - * implementation to hold the lock for the shortest possible time. - */ -#define TRANSACTION_HANDLER_SLAVE(prefix) \ - do { \ - prefix##_handlers_slave(master_matrix, slave_matrix); \ - } while (0) - -/** - * @brief Constructs a transaction handler that automatically acquires a lock to - * safely access the split shared memory and releases the lock again after - * processing the handler. Use this macro if the handler is fast and - * deterministic in runtime and thus holds the lock only for a very short time. - * If not fallback to manually locking and unlocking inside the handler. - */ -#define TRANSACTION_HANDLER_SLAVE_AUTOLOCK(prefix) \ - do { \ - split_shared_memory_lock(); \ - prefix##_handlers_slave(master_matrix, slave_matrix); \ - split_shared_memory_unlock(); \ - } while (0) - -inline static bool read_if_checksum_mismatch(int8_t trans_id_checksum, int8_t trans_id_retrieve, uint32_t *last_update, void *destination, const void *equiv_shmem, size_t length) { - uint8_t curr_checksum; - bool okay = transport_read(trans_id_checksum, &curr_checksum, sizeof(curr_checksum)); - if (okay && (timer_elapsed32(*last_update) >= FORCED_SYNC_THROTTLE_MS || curr_checksum != crc8(equiv_shmem, length))) { - okay &= transport_read(trans_id_retrieve, destination, length); - okay &= curr_checksum == crc8(equiv_shmem, length); - if (okay) { - *last_update = timer_read32(); - } - } else { - memcpy(destination, equiv_shmem, length); - } - return okay; -} - -inline static bool send_if_condition(int8_t trans_id, uint32_t *last_update, bool condition, void *source, size_t length) { - bool okay = true; - if (timer_elapsed32(*last_update) >= FORCED_SYNC_THROTTLE_MS || condition) { - okay &= transport_write(trans_id, source, length); - if (okay) { - *last_update = timer_read32(); - } - } - return okay; -} - -inline static bool send_if_data_mismatch(int8_t trans_id, uint32_t *last_update, void *source, const void *equiv_shmem, size_t length) { - // Just run a memcmp to compare the source and equivalent shmem location - return send_if_condition(trans_id, last_update, (memcmp(source, equiv_shmem, length) != 0), source, length); -} - -//////////////////////////////////////////////////// -// Slave matrix - -static bool slave_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - static matrix_row_t last_matrix[(MATRIX_ROWS) / 2] = {0}; // last successfully-read matrix, so we can replicate if there are checksum errors - matrix_row_t temp_matrix[(MATRIX_ROWS) / 2]; // holding area while we test whether or not checksum is correct - - bool okay = read_if_checksum_mismatch(GET_SLAVE_MATRIX_CHECKSUM, GET_SLAVE_MATRIX_DATA, &last_update, temp_matrix, split_shmem->smatrix.matrix, sizeof(split_shmem->smatrix.matrix)); - if (okay) { - // Checksum matches the received data, save as the last matrix state - memcpy(last_matrix, temp_matrix, sizeof(temp_matrix)); - } - // Copy out the last-known-good matrix state to the slave matrix - memcpy(slave_matrix, last_matrix, sizeof(last_matrix)); - return okay; -} - -static void slave_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - memcpy(split_shmem->smatrix.matrix, slave_matrix, sizeof(split_shmem->smatrix.matrix)); - split_shmem->smatrix.checksum = crc8(split_shmem->smatrix.matrix, sizeof(split_shmem->smatrix.matrix)); -} - -// clang-format off -#define TRANSACTIONS_SLAVE_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(slave_matrix) -#define TRANSACTIONS_SLAVE_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(slave_matrix) -#define TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS \ - [GET_SLAVE_MATRIX_CHECKSUM] = trans_target2initiator_initializer(smatrix.checksum), \ - [GET_SLAVE_MATRIX_DATA] = trans_target2initiator_initializer(smatrix.matrix), -// clang-format on - -//////////////////////////////////////////////////// -// Master matrix - -#ifdef SPLIT_TRANSPORT_MIRROR - -static bool master_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - return send_if_data_mismatch(PUT_MASTER_MATRIX, &last_update, master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); -} - -static void master_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - // Always copy to the master matrix - memcpy(master_matrix, split_shmem->mmatrix.matrix, sizeof(split_shmem->mmatrix.matrix)); -} - -# define TRANSACTIONS_MASTER_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(master_matrix) -# define TRANSACTIONS_MASTER_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(master_matrix) -# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS [PUT_MASTER_MATRIX] = trans_initiator2target_initializer(mmatrix.matrix), - -#else // SPLIT_TRANSPORT_MIRROR - -# define TRANSACTIONS_MASTER_MATRIX_MASTER() -# define TRANSACTIONS_MASTER_MATRIX_SLAVE() -# define TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS - -#endif // SPLIT_TRANSPORT_MIRROR - -//////////////////////////////////////////////////// -// Encoders - -#ifdef ENCODER_ENABLE - -static bool encoder_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - uint8_t temp_state[NUM_ENCODERS_MAX_PER_SIDE]; - - bool okay = read_if_checksum_mismatch(GET_ENCODERS_CHECKSUM, GET_ENCODERS_DATA, &last_update, temp_state, split_shmem->encoders.state, sizeof(temp_state)); - if (okay) encoder_update_raw(temp_state); - return okay; -} - -static void encoder_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - uint8_t encoder_state[NUM_ENCODERS_MAX_PER_SIDE]; - encoder_state_raw(encoder_state); - // Always prepare the encoder state for read. - memcpy(split_shmem->encoders.state, encoder_state, sizeof(encoder_state)); - // Now update the checksum given that the encoders has been written to - split_shmem->encoders.checksum = crc8(encoder_state, sizeof(encoder_state)); -} - -// clang-format off -# define TRANSACTIONS_ENCODERS_MASTER() TRANSACTION_HANDLER_MASTER(encoder) -# define TRANSACTIONS_ENCODERS_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(encoder) -# define TRANSACTIONS_ENCODERS_REGISTRATIONS \ - [GET_ENCODERS_CHECKSUM] = trans_target2initiator_initializer(encoders.checksum), \ - [GET_ENCODERS_DATA] = trans_target2initiator_initializer(encoders.state), -// clang-format on - -#else // ENCODER_ENABLE - -# define TRANSACTIONS_ENCODERS_MASTER() -# define TRANSACTIONS_ENCODERS_SLAVE() -# define TRANSACTIONS_ENCODERS_REGISTRATIONS - -#endif // ENCODER_ENABLE - -//////////////////////////////////////////////////// -// Sync timer - -#ifndef DISABLE_SYNC_TIMER - -static bool sync_timer_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - - bool okay = true; - if (timer_elapsed32(last_update) >= FORCED_SYNC_THROTTLE_MS) { - uint32_t sync_timer = sync_timer_read32() + SYNC_TIMER_OFFSET; - okay &= transport_write(PUT_SYNC_TIMER, &sync_timer, sizeof(sync_timer)); - if (okay) { - last_update = timer_read32(); - } - } - return okay; -} - -static void sync_timer_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_sync_timer = 0; - if (last_sync_timer != split_shmem->sync_timer) { - last_sync_timer = split_shmem->sync_timer; - sync_timer_update(last_sync_timer); - } -} - -# define TRANSACTIONS_SYNC_TIMER_MASTER() TRANSACTION_HANDLER_MASTER(sync_timer) -# define TRANSACTIONS_SYNC_TIMER_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(sync_timer) -# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS [PUT_SYNC_TIMER] = trans_initiator2target_initializer(sync_timer), - -#else // DISABLE_SYNC_TIMER - -# define TRANSACTIONS_SYNC_TIMER_MASTER() -# define TRANSACTIONS_SYNC_TIMER_SLAVE() -# define TRANSACTIONS_SYNC_TIMER_REGISTRATIONS - -#endif // DISABLE_SYNC_TIMER - -//////////////////////////////////////////////////// -// Layer state - -#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -static bool layer_state_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_layer_state_update = 0; - static uint32_t last_default_layer_state_update = 0; - - bool okay = send_if_condition(PUT_LAYER_STATE, &last_layer_state_update, (layer_state != split_shmem->layers.layer_state), &layer_state, sizeof(layer_state)); - if (okay) { - okay &= send_if_condition(PUT_DEFAULT_LAYER_STATE, &last_default_layer_state_update, (default_layer_state != split_shmem->layers.default_layer_state), &default_layer_state, sizeof(default_layer_state)); - } - return okay; -} - -static void layer_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - layer_state = split_shmem->layers.layer_state; - default_layer_state = split_shmem->layers.default_layer_state; -} - -// clang-format off -# define TRANSACTIONS_LAYER_STATE_MASTER() TRANSACTION_HANDLER_MASTER(layer_state) -# define TRANSACTIONS_LAYER_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(layer_state) -# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS \ - [PUT_LAYER_STATE] = trans_initiator2target_initializer(layers.layer_state), \ - [PUT_DEFAULT_LAYER_STATE] = trans_initiator2target_initializer(layers.default_layer_state), -// clang-format on - -#else // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -# define TRANSACTIONS_LAYER_STATE_MASTER() -# define TRANSACTIONS_LAYER_STATE_SLAVE() -# define TRANSACTIONS_LAYER_STATE_REGISTRATIONS - -#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -//////////////////////////////////////////////////// -// LED state - -#ifdef SPLIT_LED_STATE_ENABLE - -static bool led_state_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - uint8_t led_state = host_keyboard_leds(); - return send_if_data_mismatch(PUT_LED_STATE, &last_update, &led_state, &split_shmem->led_state, sizeof(led_state)); -} - -static void led_state_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - void set_split_host_keyboard_leds(uint8_t led_state); - set_split_host_keyboard_leds(split_shmem->led_state); -} - -# define TRANSACTIONS_LED_STATE_MASTER() TRANSACTION_HANDLER_MASTER(led_state) -# define TRANSACTIONS_LED_STATE_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(led_state) -# define TRANSACTIONS_LED_STATE_REGISTRATIONS [PUT_LED_STATE] = trans_initiator2target_initializer(led_state), - -#else // SPLIT_LED_STATE_ENABLE - -# define TRANSACTIONS_LED_STATE_MASTER() -# define TRANSACTIONS_LED_STATE_SLAVE() -# define TRANSACTIONS_LED_STATE_REGISTRATIONS - -#endif // SPLIT_LED_STATE_ENABLE - -//////////////////////////////////////////////////// -// Mods - -#ifdef SPLIT_MODS_ENABLE - -static bool mods_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - bool mods_need_sync = timer_elapsed32(last_update) >= FORCED_SYNC_THROTTLE_MS; - split_mods_sync_t new_mods; - new_mods.real_mods = get_mods(); - if (!mods_need_sync && new_mods.real_mods != split_shmem->mods.real_mods) { - mods_need_sync = true; - } - - new_mods.weak_mods = get_weak_mods(); - if (!mods_need_sync && new_mods.weak_mods != split_shmem->mods.weak_mods) { - mods_need_sync = true; - } - -# ifndef NO_ACTION_ONESHOT - new_mods.oneshot_mods = get_oneshot_mods(); - if (!mods_need_sync && new_mods.oneshot_mods != split_shmem->mods.oneshot_mods) { - mods_need_sync = true; - } -# endif // NO_ACTION_ONESHOT - - bool okay = true; - if (mods_need_sync) { - okay &= transport_write(PUT_MODS, &new_mods, sizeof(new_mods)); - if (okay) { - last_update = timer_read32(); - } - } - - return okay; -} - -static void mods_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - split_mods_sync_t mods; - memcpy(&mods, &split_shmem->mods, sizeof(split_mods_sync_t)); - split_shared_memory_unlock(); - - set_mods(mods.real_mods); - set_weak_mods(mods.weak_mods); -# ifndef NO_ACTION_ONESHOT - set_oneshot_mods(mods.oneshot_mods); -# endif -} - -# define TRANSACTIONS_MODS_MASTER() TRANSACTION_HANDLER_MASTER(mods) -# define TRANSACTIONS_MODS_SLAVE() TRANSACTION_HANDLER_SLAVE(mods) -# define TRANSACTIONS_MODS_REGISTRATIONS [PUT_MODS] = trans_initiator2target_initializer(mods), - -#else // SPLIT_MODS_ENABLE - -# define TRANSACTIONS_MODS_MASTER() -# define TRANSACTIONS_MODS_SLAVE() -# define TRANSACTIONS_MODS_REGISTRATIONS - -#endif // SPLIT_MODS_ENABLE - -//////////////////////////////////////////////////// -// Backlight - -#ifdef BACKLIGHT_ENABLE - -static bool backlight_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - uint8_t level = is_backlight_enabled() ? get_backlight_level() : 0; - return send_if_condition(PUT_BACKLIGHT, &last_update, (level != split_shmem->backlight_level), &level, sizeof(level)); -} - -static void backlight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - uint8_t backlight_level = split_shmem->backlight_level; - split_shared_memory_unlock(); - - backlight_level_noeeprom(backlight_level); -} - -# define TRANSACTIONS_BACKLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(backlight) -# define TRANSACTIONS_BACKLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(backlight) -# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS [PUT_BACKLIGHT] = trans_initiator2target_initializer(backlight_level), - -#else // BACKLIGHT_ENABLE - -# define TRANSACTIONS_BACKLIGHT_MASTER() -# define TRANSACTIONS_BACKLIGHT_SLAVE() -# define TRANSACTIONS_BACKLIGHT_REGISTRATIONS - -#endif // BACKLIGHT_ENABLE - -//////////////////////////////////////////////////// -// RGBLIGHT - -#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -static bool rgblight_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - rgblight_syncinfo_t rgblight_sync; - rgblight_get_syncinfo(&rgblight_sync); - if (send_if_condition(PUT_RGBLIGHT, &last_update, (rgblight_sync.status.change_flags != 0), &rgblight_sync, sizeof(rgblight_sync))) { - rgblight_clear_change_flags(); - } else { - return false; - } - return true; -} - -static void rgblight_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - // Update the RGB with the new data - rgblight_syncinfo_t rgblight_sync; - memcpy(&rgblight_sync, &split_shmem->rgblight_sync, sizeof(rgblight_syncinfo_t)); - split_shmem->rgblight_sync.status.change_flags = 0; - split_shared_memory_unlock(); - - if (rgblight_sync.status.change_flags != 0) { - rgblight_update_sync(&rgblight_sync, false); - } -} - -# define TRANSACTIONS_RGBLIGHT_MASTER() TRANSACTION_HANDLER_MASTER(rgblight) -# define TRANSACTIONS_RGBLIGHT_SLAVE() TRANSACTION_HANDLER_SLAVE(rgblight) -# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS [PUT_RGBLIGHT] = trans_initiator2target_initializer(rgblight_sync), - -#else // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -# define TRANSACTIONS_RGBLIGHT_MASTER() -# define TRANSACTIONS_RGBLIGHT_SLAVE() -# define TRANSACTIONS_RGBLIGHT_REGISTRATIONS - -#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -//////////////////////////////////////////////////// -// LED Matrix - -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -static bool led_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - led_matrix_sync_t led_matrix_sync; - memcpy(&led_matrix_sync.led_matrix, &led_matrix_eeconfig, sizeof(led_eeconfig_t)); - led_matrix_sync.led_suspend_state = led_matrix_get_suspend_state(); - return send_if_data_mismatch(PUT_LED_MATRIX, &last_update, &led_matrix_sync, &split_shmem->led_matrix_sync, sizeof(led_matrix_sync)); -} - -static void led_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - memcpy(&led_matrix_eeconfig, &split_shmem->led_matrix_sync.led_matrix, sizeof(led_eeconfig_t)); - bool led_suspend_state = split_shmem->led_matrix_sync.led_suspend_state; - split_shared_memory_unlock(); - - led_matrix_set_suspend_state(led_suspend_state); -} - -# define TRANSACTIONS_LED_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(led_matrix) -# define TRANSACTIONS_LED_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(led_matrix) -# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS [PUT_LED_MATRIX] = trans_initiator2target_initializer(led_matrix_sync), - -#else // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -# define TRANSACTIONS_LED_MATRIX_MASTER() -# define TRANSACTIONS_LED_MATRIX_SLAVE() -# define TRANSACTIONS_LED_MATRIX_REGISTRATIONS - -#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -//////////////////////////////////////////////////// -// RGB Matrix - -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - -static bool rgb_matrix_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - rgb_matrix_sync_t rgb_matrix_sync; - memcpy(&rgb_matrix_sync.rgb_matrix, &rgb_matrix_config, sizeof(rgb_config_t)); - rgb_matrix_sync.rgb_suspend_state = rgb_matrix_get_suspend_state(); - return send_if_data_mismatch(PUT_RGB_MATRIX, &last_update, &rgb_matrix_sync, &split_shmem->rgb_matrix_sync, sizeof(rgb_matrix_sync)); -} - -static void rgb_matrix_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - memcpy(&rgb_matrix_config, &split_shmem->rgb_matrix_sync.rgb_matrix, sizeof(rgb_config_t)); - bool rgb_suspend_state = split_shmem->rgb_matrix_sync.rgb_suspend_state; - split_shared_memory_unlock(); - - rgb_matrix_set_suspend_state(rgb_suspend_state); -} - -# define TRANSACTIONS_RGB_MATRIX_MASTER() TRANSACTION_HANDLER_MASTER(rgb_matrix) -# define TRANSACTIONS_RGB_MATRIX_SLAVE() TRANSACTION_HANDLER_SLAVE(rgb_matrix) -# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS [PUT_RGB_MATRIX] = trans_initiator2target_initializer(rgb_matrix_sync), - -#else // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - -# define TRANSACTIONS_RGB_MATRIX_MASTER() -# define TRANSACTIONS_RGB_MATRIX_SLAVE() -# define TRANSACTIONS_RGB_MATRIX_REGISTRATIONS - -#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - -//////////////////////////////////////////////////// -// WPM - -#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - -static bool wpm_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - uint8_t current_wpm = get_current_wpm(); - return send_if_condition(PUT_WPM, &last_update, (current_wpm != split_shmem->current_wpm), ¤t_wpm, sizeof(current_wpm)); -} - -static void wpm_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - set_current_wpm(split_shmem->current_wpm); -} - -# define TRANSACTIONS_WPM_MASTER() TRANSACTION_HANDLER_MASTER(wpm) -# define TRANSACTIONS_WPM_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(wpm) -# define TRANSACTIONS_WPM_REGISTRATIONS [PUT_WPM] = trans_initiator2target_initializer(current_wpm), - -#else // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - -# define TRANSACTIONS_WPM_MASTER() -# define TRANSACTIONS_WPM_SLAVE() -# define TRANSACTIONS_WPM_REGISTRATIONS - -#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - -//////////////////////////////////////////////////// -// OLED - -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - -static bool oled_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - bool current_oled_state = is_oled_on(); - return send_if_condition(PUT_OLED, &last_update, (current_oled_state != split_shmem->current_oled_state), ¤t_oled_state, sizeof(current_oled_state)); -} - -static void oled_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - uint8_t current_oled_state = split_shmem->current_oled_state; - split_shared_memory_unlock(); - - if (current_oled_state) { - oled_on(); - } else { - oled_off(); - } -} - -# define TRANSACTIONS_OLED_MASTER() TRANSACTION_HANDLER_MASTER(oled) -# define TRANSACTIONS_OLED_SLAVE() TRANSACTION_HANDLER_SLAVE(oled) -# define TRANSACTIONS_OLED_REGISTRATIONS [PUT_OLED] = trans_initiator2target_initializer(current_oled_state), - -#else // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - -# define TRANSACTIONS_OLED_MASTER() -# define TRANSACTIONS_OLED_SLAVE() -# define TRANSACTIONS_OLED_REGISTRATIONS - -#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - -//////////////////////////////////////////////////// -// ST7565 - -#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - -static bool st7565_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - bool current_st7565_state = st7565_is_on(); - return send_if_condition(PUT_ST7565, &last_update, (current_st7565_state != split_shmem->current_st7565_state), ¤t_st7565_state, sizeof(current_st7565_state)); -} - -static void st7565_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_shared_memory_lock(); - uint8_t current_st7565_state = split_shmem->current_st7565_state; - split_shared_memory_unlock(); - - if (current_st7565_state) { - st7565_on(); - } else { - st7565_off(); - } -} - -# define TRANSACTIONS_ST7565_MASTER() TRANSACTION_HANDLER_MASTER(st7565) -# define TRANSACTIONS_ST7565_SLAVE() TRANSACTION_HANDLER_SLAVE(st7565) -# define TRANSACTIONS_ST7565_REGISTRATIONS [PUT_ST7565] = trans_initiator2target_initializer(current_st7565_state), - -#else // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - -# define TRANSACTIONS_ST7565_MASTER() -# define TRANSACTIONS_ST7565_SLAVE() -# define TRANSACTIONS_ST7565_REGISTRATIONS - -#endif // defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - -//////////////////////////////////////////////////// -// POINTING - -#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -static bool pointing_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { -# if defined(POINTING_DEVICE_LEFT) - if (is_keyboard_left()) { - return true; - } -# elif defined(POINTING_DEVICE_RIGHT) - if (!is_keyboard_left()) { - return true; - } -# endif - static uint32_t last_update = 0; - static uint16_t last_cpi = 0; - report_mouse_t temp_state; - uint16_t temp_cpi; - bool okay = read_if_checksum_mismatch(GET_POINTING_CHECKSUM, GET_POINTING_DATA, &last_update, &temp_state, &split_shmem->pointing.report, sizeof(temp_state)); - if (okay) pointing_device_set_shared_report(temp_state); - temp_cpi = pointing_device_get_shared_cpi(); - if (temp_cpi && last_cpi != temp_cpi) { - split_shmem->pointing.cpi = temp_cpi; - okay = transport_write(PUT_POINTING_CPI, &split_shmem->pointing.cpi, sizeof(split_shmem->pointing.cpi)); - if (okay) { - last_cpi = temp_cpi; - } - } - return okay; -} - -extern const pointing_device_driver_t pointing_device_driver; - -static void pointing_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { -# if defined(POINTING_DEVICE_LEFT) - if (!is_keyboard_left()) { - return; - } -# elif defined(POINTING_DEVICE_RIGHT) - if (is_keyboard_left()) { - return; - } -# endif -# if (POINTING_DEVICE_TASK_THROTTLE_MS > 0) - static uint32_t last_exec = 0; - if (timer_elapsed32(last_exec) < POINTING_DEVICE_TASK_THROTTLE_MS) { - return; - } - last_exec = timer_read32(); -# endif - - uint16_t temp_cpi = !pointing_device_driver.get_cpi ? 0 : pointing_device_driver.get_cpi(); // check for NULL - - split_shared_memory_lock(); - split_slave_pointing_sync_t pointing; - memcpy(&pointing, &split_shmem->pointing, sizeof(split_slave_pointing_sync_t)); - split_shared_memory_unlock(); - - if (pointing.cpi && pointing.cpi != temp_cpi && pointing_device_driver.set_cpi) { - pointing_device_driver.set_cpi(pointing.cpi); - } - - pointing.report = pointing_device_driver.get_report((report_mouse_t){0}); - // Now update the checksum given that the pointing has been written to - pointing.checksum = crc8(&pointing.report, sizeof(report_mouse_t)); - - split_shared_memory_lock(); - memcpy(&split_shmem->pointing, &pointing, sizeof(split_slave_pointing_sync_t)); - split_shared_memory_unlock(); -} - -# define TRANSACTIONS_POINTING_MASTER() TRANSACTION_HANDLER_MASTER(pointing) -# define TRANSACTIONS_POINTING_SLAVE() TRANSACTION_HANDLER_SLAVE(pointing) -# define TRANSACTIONS_POINTING_REGISTRATIONS [GET_POINTING_CHECKSUM] = trans_target2initiator_initializer(pointing.checksum), [GET_POINTING_DATA] = trans_target2initiator_initializer(pointing.report), [PUT_POINTING_CPI] = trans_initiator2target_initializer(pointing.cpi), - -#else // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -# define TRANSACTIONS_POINTING_MASTER() -# define TRANSACTIONS_POINTING_SLAVE() -# define TRANSACTIONS_POINTING_REGISTRATIONS - -#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -//////////////////////////////////////////////////// -// WATCHDOG - -#if defined(SPLIT_WATCHDOG_ENABLE) - -static bool watchdog_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - bool okay = true; - if (!split_watchdog_check()) { - okay = transport_write(PUT_WATCHDOG, &okay, sizeof(okay)); - split_watchdog_update(okay); - } - return okay; -} - -static void watchdog_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - split_watchdog_update(split_shmem->watchdog_pinged); -} - -# define TRANSACTIONS_WATCHDOG_MASTER() TRANSACTION_HANDLER_MASTER(watchdog) -# define TRANSACTIONS_WATCHDOG_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(watchdog) -# define TRANSACTIONS_WATCHDOG_REGISTRATIONS [PUT_WATCHDOG] = trans_initiator2target_initializer(watchdog_pinged), - -#else // defined(SPLIT_WATCHDOG_ENABLE) - -# define TRANSACTIONS_WATCHDOG_MASTER() -# define TRANSACTIONS_WATCHDOG_SLAVE() -# define TRANSACTIONS_WATCHDOG_REGISTRATIONS - -#endif // defined(SPLIT_WATCHDOG_ENABLE) - -#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - -uint8_t split_haptic_play = 0xFF; -extern haptic_config_t haptic_config; - -static bool haptic_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - split_slave_haptic_sync_t haptic_sync; - - memcpy(&haptic_sync.haptic_config, &haptic_config, sizeof(haptic_config_t)); - haptic_sync.haptic_play = split_haptic_play; - - bool okay = send_if_data_mismatch(PUT_HAPTIC, &last_update, &haptic_sync, &split_shmem->haptic_sync, sizeof(haptic_sync)); - - split_haptic_play = 0xFF; - - return okay; -} - -static void haptic_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - memcpy(&haptic_config, &split_shmem->haptic_sync.haptic_config, sizeof(haptic_config_t)); - - if (split_shmem->haptic_sync.haptic_play != 0xFF) { - haptic_set_mode(split_shmem->haptic_sync.haptic_play); - haptic_play(); - } -} - -// clang-format off -# define TRANSACTIONS_HAPTIC_MASTER() TRANSACTION_HANDLER_MASTER(haptic) -# define TRANSACTIONS_HAPTIC_SLAVE() TRANSACTION_HANDLER_SLAVE(haptic) -# define TRANSACTIONS_HAPTIC_REGISTRATIONS [PUT_HAPTIC] = trans_initiator2target_initializer(haptic_sync), -// clang-format on - -#else // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - -# define TRANSACTIONS_HAPTIC_MASTER() -# define TRANSACTIONS_HAPTIC_SLAVE() -# define TRANSACTIONS_HAPTIC_REGISTRATIONS - -#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - -#if defined(SPLIT_ACTIVITY_ENABLE) - -static bool activity_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_update = 0; - split_slave_activity_sync_t activity_sync; - activity_sync.matrix_timestamp = last_matrix_activity_time(); - activity_sync.encoder_timestamp = last_encoder_activity_time(); - activity_sync.pointing_device_timestamp = last_pointing_device_activity_time(); - return send_if_data_mismatch(PUT_ACTIVITY, &last_update, &activity_sync, &split_shmem->activity_sync, sizeof(activity_sync)); -} - -static void activity_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - set_activity_timestamps(split_shmem->activity_sync.matrix_timestamp, split_shmem->activity_sync.encoder_timestamp, split_shmem->activity_sync.pointing_device_timestamp); -} - -// clang-format off -# define TRANSACTIONS_ACTIVITY_MASTER() TRANSACTION_HANDLER_MASTER(activity) -# define TRANSACTIONS_ACTIVITY_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(activity) -# define TRANSACTIONS_ACTIVITY_REGISTRATIONS [PUT_ACTIVITY] = trans_initiator2target_initializer(activity_sync), -// clang-format on - -#else // defined(SPLIT_ACTIVITY_ENABLE) - -# define TRANSACTIONS_ACTIVITY_MASTER() -# define TRANSACTIONS_ACTIVITY_SLAVE() -# define TRANSACTIONS_ACTIVITY_REGISTRATIONS - -#endif // defined(SPLIT_ACTIVITY_ENABLE) - -//////////////////////////////////////////////////// -// Detected OS - -#if defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - -static bool detected_os_handlers_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - static uint32_t last_detected_os_update = 0; - os_variant_t detected_os = detected_host_os(); - bool okay = send_if_condition(PUT_DETECTED_OS, &last_detected_os_update, (detected_os != split_shmem->detected_os), &detected_os, sizeof(os_variant_t)); - return okay; -} - -static void detected_os_handlers_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - slave_update_detected_host_os(split_shmem->detected_os); -} - -# define TRANSACTIONS_DETECTED_OS_MASTER() TRANSACTION_HANDLER_MASTER(detected_os) -# define TRANSACTIONS_DETECTED_OS_SLAVE() TRANSACTION_HANDLER_SLAVE_AUTOLOCK(detected_os) -# define TRANSACTIONS_DETECTED_OS_REGISTRATIONS [PUT_DETECTED_OS] = trans_initiator2target_initializer(detected_os), - -#else // defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - -# define TRANSACTIONS_DETECTED_OS_MASTER() -# define TRANSACTIONS_DETECTED_OS_SLAVE() -# define TRANSACTIONS_DETECTED_OS_REGISTRATIONS - -#endif // defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - -//////////////////////////////////////////////////// - -split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS] = { - // Set defaults - [0 ...(NUM_TOTAL_TRANSACTIONS - 1)] = {0, 0, 0, 0, 0}, - -#ifdef USE_I2C - [I2C_EXECUTE_CALLBACK] = trans_initiator2target_initializer(transaction_id), -#endif // USE_I2C - - // clang-format off - TRANSACTIONS_SLAVE_MATRIX_REGISTRATIONS - TRANSACTIONS_MASTER_MATRIX_REGISTRATIONS - TRANSACTIONS_ENCODERS_REGISTRATIONS - TRANSACTIONS_SYNC_TIMER_REGISTRATIONS - TRANSACTIONS_LAYER_STATE_REGISTRATIONS - TRANSACTIONS_LED_STATE_REGISTRATIONS - TRANSACTIONS_MODS_REGISTRATIONS - TRANSACTIONS_BACKLIGHT_REGISTRATIONS - TRANSACTIONS_RGBLIGHT_REGISTRATIONS - TRANSACTIONS_LED_MATRIX_REGISTRATIONS - TRANSACTIONS_RGB_MATRIX_REGISTRATIONS - TRANSACTIONS_WPM_REGISTRATIONS - TRANSACTIONS_OLED_REGISTRATIONS - TRANSACTIONS_ST7565_REGISTRATIONS - TRANSACTIONS_POINTING_REGISTRATIONS - TRANSACTIONS_WATCHDOG_REGISTRATIONS - TRANSACTIONS_HAPTIC_REGISTRATIONS - TRANSACTIONS_ACTIVITY_REGISTRATIONS - TRANSACTIONS_DETECTED_OS_REGISTRATIONS -// clang-format on - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - [PUT_RPC_INFO] = trans_initiator2target_initializer_cb(rpc_info, slave_rpc_info_callback), - [PUT_RPC_REQ_DATA] = trans_initiator2target_initializer(rpc_m2s_buffer), - [EXECUTE_RPC] = trans_initiator2target_initializer_cb(rpc_info.payload.transaction_id, slave_rpc_exec_callback), - [GET_RPC_RESP_DATA] = trans_target2initiator_initializer(rpc_s2m_buffer), -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) -}; - -bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - TRANSACTIONS_SLAVE_MATRIX_MASTER(); - TRANSACTIONS_MASTER_MATRIX_MASTER(); - TRANSACTIONS_ENCODERS_MASTER(); - TRANSACTIONS_SYNC_TIMER_MASTER(); - TRANSACTIONS_LAYER_STATE_MASTER(); - TRANSACTIONS_LED_STATE_MASTER(); - TRANSACTIONS_MODS_MASTER(); - TRANSACTIONS_BACKLIGHT_MASTER(); - TRANSACTIONS_RGBLIGHT_MASTER(); - TRANSACTIONS_LED_MATRIX_MASTER(); - TRANSACTIONS_RGB_MATRIX_MASTER(); - TRANSACTIONS_WPM_MASTER(); - TRANSACTIONS_OLED_MASTER(); - TRANSACTIONS_ST7565_MASTER(); - TRANSACTIONS_POINTING_MASTER(); - TRANSACTIONS_WATCHDOG_MASTER(); - TRANSACTIONS_HAPTIC_MASTER(); - TRANSACTIONS_ACTIVITY_MASTER(); - TRANSACTIONS_DETECTED_OS_MASTER(); - return true; -} - -void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - TRANSACTIONS_SLAVE_MATRIX_SLAVE(); - TRANSACTIONS_MASTER_MATRIX_SLAVE(); - TRANSACTIONS_ENCODERS_SLAVE(); - TRANSACTIONS_SYNC_TIMER_SLAVE(); - TRANSACTIONS_LAYER_STATE_SLAVE(); - TRANSACTIONS_LED_STATE_SLAVE(); - TRANSACTIONS_MODS_SLAVE(); - TRANSACTIONS_BACKLIGHT_SLAVE(); - TRANSACTIONS_RGBLIGHT_SLAVE(); - TRANSACTIONS_LED_MATRIX_SLAVE(); - TRANSACTIONS_RGB_MATRIX_SLAVE(); - TRANSACTIONS_WPM_SLAVE(); - TRANSACTIONS_OLED_SLAVE(); - TRANSACTIONS_ST7565_SLAVE(); - TRANSACTIONS_POINTING_SLAVE(); - TRANSACTIONS_WATCHDOG_SLAVE(); - TRANSACTIONS_HAPTIC_SLAVE(); - TRANSACTIONS_ACTIVITY_SLAVE(); - TRANSACTIONS_DETECTED_OS_SLAVE(); -} - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - -void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback) { - // Prevent invoking RPC on QMK core sync data - if (transaction_id <= GET_RPC_RESP_DATA) return; - - // Set the callback - split_transaction_table[transaction_id].slave_callback = callback; - split_transaction_table[transaction_id].initiator2target_offset = offsetof(split_shared_memory_t, rpc_m2s_buffer); - split_transaction_table[transaction_id].target2initiator_offset = offsetof(split_shared_memory_t, rpc_s2m_buffer); -} - -bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { - // Prevent transaction attempts while transport is disconnected - if (!is_transport_connected()) { - return false; - } - // Prevent invoking RPC on QMK core sync data - if (transaction_id <= GET_RPC_RESP_DATA) return false; - // Prevent sizing issues - if (initiator2target_buffer_size > RPC_M2S_BUFFER_SIZE) return false; - if (target2initiator_buffer_size > RPC_S2M_BUFFER_SIZE) return false; - - // Prepare the metadata block - rpc_sync_info_t info = {.payload = {.transaction_id = transaction_id, .m2s_length = initiator2target_buffer_size, .s2m_length = target2initiator_buffer_size}}; - info.checksum = crc8(&info.payload, sizeof(info.payload)); - - // Make sure the local side knows that we're not sending the full block of data - split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = initiator2target_buffer_size; - split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = target2initiator_buffer_size; - - // Run through the sequence: - // * set the transaction ID and lengths - // * send the request data - // * execute RPC callback - // * retrieve the response data - if (!transport_write(PUT_RPC_INFO, &info, sizeof(info))) { - return false; - } - if (!transport_write(PUT_RPC_REQ_DATA, initiator2target_buffer, initiator2target_buffer_size)) { - return false; - } - if (!transport_write(EXECUTE_RPC, &transaction_id, sizeof(transaction_id))) { - return false; - } - if (!transport_read(GET_RPC_RESP_DATA, target2initiator_buffer, target2initiator_buffer_size)) { - return false; - } - return true; -} - -void slave_rpc_info_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { - // The RPC info block contains the intended transaction ID, as well as the sizes for both inbound and outbound data. - // Ignore the args -- the `split_shmem` already has the info, we just need to act upon it. - // We must keep the `split_transaction_table` non-const, so that it is able to be modified at runtime. - - split_transaction_table[PUT_RPC_REQ_DATA].initiator2target_buffer_size = split_shmem->rpc_info.payload.m2s_length; - split_transaction_table[GET_RPC_RESP_DATA].target2initiator_buffer_size = split_shmem->rpc_info.payload.s2m_length; -} - -void slave_rpc_exec_callback(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer) { - // We can assume that the buffer lengths are correctly set, now, given that sequentially the rpc_info callback was already executed. - // Go through the rpc_info and execute _that_ transaction's callback, with the scratch buffers as inputs. - // As a safety precaution we check that the received payload matches its checksum first. - if (crc8(&split_shmem->rpc_info.payload, sizeof(split_shmem->rpc_info.payload)) != split_shmem->rpc_info.checksum) { - return; - } - - int8_t transaction_id = split_shmem->rpc_info.payload.transaction_id; - if (transaction_id < NUM_TOTAL_TRANSACTIONS) { - split_transaction_desc_t *trans = &split_transaction_table[transaction_id]; - if (trans->slave_callback) { - trans->slave_callback(split_shmem->rpc_info.payload.m2s_length, split_shmem->rpc_m2s_buffer, split_shmem->rpc_info.payload.s2m_length, split_shmem->rpc_s2m_buffer); - } - } -} - -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) diff --git a/quantum/split_common/transactions.h b/quantum/split_common/transactions.h deleted file mode 100644 index e38ec79ce910..000000000000 --- a/quantum/split_common/transactions.h +++ /dev/null @@ -1,53 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#pragma once - -#include "stdint.h" -#include "stdbool.h" - -#include "matrix.h" -#include "transaction_id_define.h" -#include "transport.h" - -typedef void (*slave_callback_t)(uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); - -// Split transaction Descriptor -typedef struct _split_transaction_desc_t { - uint8_t initiator2target_buffer_size; - uint16_t initiator2target_offset; - uint8_t target2initiator_buffer_size; - uint16_t target2initiator_offset; - slave_callback_t slave_callback; -} split_transaction_desc_t; - -// Forward declaration for the split transactions -extern split_transaction_desc_t split_transaction_table[NUM_TOTAL_TRANSACTIONS]; - -#define split_shmem_offset_ptr(offset) (((uint8_t *)split_shmem) + (offset)) -#define split_trans_initiator2target_buffer(trans) (split_shmem_offset_ptr((trans)->initiator2target_offset)) -#define split_trans_target2initiator_buffer(trans) (split_shmem_offset_ptr((trans)->target2initiator_offset)) - -// returns false if valid data not received from slave -bool transactions_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); -void transactions_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); - -void transaction_register_rpc(int8_t transaction_id, slave_callback_t callback); - -bool transaction_rpc_exec(int8_t transaction_id, uint8_t initiator2target_buffer_size, const void *initiator2target_buffer, uint8_t target2initiator_buffer_size, void *target2initiator_buffer); - -#define transaction_rpc_send(transaction_id, initiator2target_buffer_size, initiator2target_buffer) transaction_rpc_exec(transaction_id, initiator2target_buffer_size, initiator2target_buffer, 0, NULL) -#define transaction_rpc_recv(transaction_id, target2initiator_buffer_size, target2initiator_buffer) transaction_rpc_exec(transaction_id, 0, NULL, target2initiator_buffer_size, target2initiator_buffer) diff --git a/quantum/split_common/transport.c b/quantum/split_common/transport.c deleted file mode 100644 index aade3c98d7a8..000000000000 --- a/quantum/split_common/transport.c +++ /dev/null @@ -1,130 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#include -#include - -#include "transactions.h" -#include "transport.h" -#include "transaction_id_define.h" -#include "atomic_util.h" - -#ifdef USE_I2C - -# ifndef SLAVE_I2C_TIMEOUT -# define SLAVE_I2C_TIMEOUT 100 -# endif // SLAVE_I2C_TIMEOUT - -# ifndef SLAVE_I2C_ADDRESS -# define SLAVE_I2C_ADDRESS 0x32 -# endif - -# include "i2c_master.h" -# include "i2c_slave.h" - -// Ensure the I2C buffer has enough space -_Static_assert(sizeof(split_shared_memory_t) <= I2C_SLAVE_REG_COUNT, "split_shared_memory_t too large for I2C_SLAVE_REG_COUNT"); - -split_shared_memory_t *const split_shmem = (split_shared_memory_t *)i2c_slave_reg; - -void transport_master_init(void) { - i2c_init(); -} -void transport_slave_init(void) { - i2c_slave_init(SLAVE_I2C_ADDRESS); -} - -i2c_status_t transport_trigger_callback(int8_t id) { - // If there's no callback, indicate that we were successful - if (!split_transaction_table[id].slave_callback) { - return I2C_STATUS_SUCCESS; - } - - // Kick off the "callback executor", now that data has been written to the slave - split_shmem->transaction_id = id; - split_transaction_desc_t *trans = &split_transaction_table[I2C_EXECUTE_CALLBACK]; - return i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), trans->initiator2target_buffer_size, SLAVE_I2C_TIMEOUT); -} - -bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) { - i2c_status_t status; - split_transaction_desc_t *trans = &split_transaction_table[id]; - if (initiator2target_length > 0) { - size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length; - memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len); - if ((status = i2c_writeReg(SLAVE_I2C_ADDRESS, trans->initiator2target_offset, split_trans_initiator2target_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) { - return false; - } - } - - // If we need to execute a callback on the slave, do so - if ((status = transport_trigger_callback(id)) < 0) { - return false; - } - - if (target2initiator_length > 0) { - size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length; - if ((status = i2c_readReg(SLAVE_I2C_ADDRESS, trans->target2initiator_offset, split_trans_target2initiator_buffer(trans), len, SLAVE_I2C_TIMEOUT)) < 0) { - return false; - } - memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len); - } - - return true; -} - -#else // USE_I2C - -# include "serial.h" - -static split_shared_memory_t shared_memory; -split_shared_memory_t *const split_shmem = &shared_memory; - -void transport_master_init(void) { - soft_serial_initiator_init(); -} -void transport_slave_init(void) { - soft_serial_target_init(); -} - -bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length) { - split_transaction_desc_t *trans = &split_transaction_table[id]; - if (initiator2target_length > 0) { - size_t len = trans->initiator2target_buffer_size < initiator2target_length ? trans->initiator2target_buffer_size : initiator2target_length; - memcpy(split_trans_initiator2target_buffer(trans), initiator2target_buf, len); - } - - if (!soft_serial_transaction(id)) { - return false; - } - - if (target2initiator_length > 0) { - size_t len = trans->target2initiator_buffer_size < target2initiator_length ? trans->target2initiator_buffer_size : target2initiator_length; - memcpy(target2initiator_buf, split_trans_target2initiator_buffer(trans), len); - } - - return true; -} - -#endif // USE_I2C - -bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - return transactions_master(master_matrix, slave_matrix); -} - -void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]) { - transactions_slave(master_matrix, slave_matrix); -} diff --git a/quantum/split_common/transport.h b/quantum/split_common/transport.h deleted file mode 100644 index a3d6f1dfe956..000000000000 --- a/quantum/split_common/transport.h +++ /dev/null @@ -1,235 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#pragma once - -#include "stdint.h" -#include "stdbool.h" - -#include "progmem.h" -#include "action_layer.h" -#include "matrix.h" - -#ifndef RPC_M2S_BUFFER_SIZE -# define RPC_M2S_BUFFER_SIZE 32 -#endif // RPC_M2S_BUFFER_SIZE - -#ifndef RPC_S2M_BUFFER_SIZE -# define RPC_S2M_BUFFER_SIZE 32 -#endif // RPC_S2M_BUFFER_SIZE - -void transport_master_init(void); -void transport_slave_init(void); - -// returns false if valid data not received from slave -bool transport_master(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); -void transport_slave(matrix_row_t master_matrix[], matrix_row_t slave_matrix[]); - -bool transport_execute_transaction(int8_t id, const void *initiator2target_buf, uint16_t initiator2target_length, void *target2initiator_buf, uint16_t target2initiator_length); - -#ifdef ENCODER_ENABLE -# include "encoder.h" -#endif // ENCODER_ENABLE - -#ifdef BACKLIGHT_ENABLE -# include "backlight.h" -#endif // BACKLIGHT_ENABLE - -#ifdef RGBLIGHT_ENABLE -# include "rgblight.h" -#endif // RGBLIGHT_ENABLE - -typedef struct _split_slave_matrix_sync_t { - uint8_t checksum; - matrix_row_t matrix[(MATRIX_ROWS) / 2]; -} split_slave_matrix_sync_t; - -#ifdef SPLIT_TRANSPORT_MIRROR -typedef struct _split_master_matrix_sync_t { - matrix_row_t matrix[(MATRIX_ROWS) / 2]; -} split_master_matrix_sync_t; -#endif // SPLIT_TRANSPORT_MIRROR - -#ifdef ENCODER_ENABLE -typedef struct _split_slave_encoder_sync_t { - uint8_t checksum; - uint8_t state[NUM_ENCODERS_MAX_PER_SIDE]; -} split_slave_encoder_sync_t; -#endif // ENCODER_ENABLE - -#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) -typedef struct _split_layers_sync_t { - layer_state_t layer_state; - layer_state_t default_layer_state; -} split_layers_sync_t; -#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) -# include "led_matrix.h" - -typedef struct _led_matrix_sync_t { - led_eeconfig_t led_matrix; - bool led_suspend_state; -} led_matrix_sync_t; -#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) -# include "rgb_matrix.h" - -typedef struct _rgb_matrix_sync_t { - rgb_config_t rgb_matrix; - bool rgb_suspend_state; -} rgb_matrix_sync_t; -#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - -#ifdef SPLIT_MODS_ENABLE -typedef struct _split_mods_sync_t { - uint8_t real_mods; - uint8_t weak_mods; -# ifndef NO_ACTION_ONESHOT - uint8_t oneshot_mods; -# endif // NO_ACTION_ONESHOT -} split_mods_sync_t; -#endif // SPLIT_MODS_ENABLE - -#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) -# include "pointing_device.h" -typedef struct _split_slave_pointing_sync_t { - uint8_t checksum; - report_mouse_t report; - uint16_t cpi; -} split_slave_pointing_sync_t; -#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) -# include "haptic.h" -typedef struct _split_slave_haptic_sync_t { - haptic_config_t haptic_config; - uint8_t haptic_play; -} split_slave_haptic_sync_t; -#endif // defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - -#if defined(SPLIT_ACTIVITY_ENABLE) -# include "keyboard.h" -typedef struct _split_slave_activity_sync_t { - uint32_t matrix_timestamp; - uint32_t encoder_timestamp; - uint32_t pointing_device_timestamp; -} split_slave_activity_sync_t; -#endif // defined(SPLIT_ACTIVITY_ENABLE) - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) -typedef struct _rpc_sync_info_t { - uint8_t checksum; - struct { - int8_t transaction_id; - uint8_t m2s_length; - uint8_t s2m_length; - } payload; -} rpc_sync_info_t; -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - -#if defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) -# include "os_detection.h" -#endif // defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - -typedef struct _split_shared_memory_t { -#ifdef USE_I2C - int8_t transaction_id; -#endif // USE_I2C - - split_slave_matrix_sync_t smatrix; - -#ifdef SPLIT_TRANSPORT_MIRROR - split_master_matrix_sync_t mmatrix; -#endif // SPLIT_TRANSPORT_MIRROR - -#ifdef ENCODER_ENABLE - split_slave_encoder_sync_t encoders; -#endif // ENCODER_ENABLE - -#ifndef DISABLE_SYNC_TIMER - uint32_t sync_timer; -#endif // DISABLE_SYNC_TIMER - -#if !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - split_layers_sync_t layers; -#endif // !defined(NO_ACTION_LAYER) && defined(SPLIT_LAYER_STATE_ENABLE) - -#ifdef SPLIT_LED_STATE_ENABLE - uint8_t led_state; -#endif // SPLIT_LED_STATE_ENABLE - -#ifdef SPLIT_MODS_ENABLE - split_mods_sync_t mods; -#endif // SPLIT_MODS_ENABLE - -#ifdef BACKLIGHT_ENABLE - uint8_t backlight_level; -#endif // BACKLIGHT_ENABLE - -#if defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - rgblight_syncinfo_t rgblight_sync; -#endif // defined(RGBLIGHT_ENABLE) && defined(RGBLIGHT_SPLIT) - -#if defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - led_matrix_sync_t led_matrix_sync; -#endif // defined(LED_MATRIX_ENABLE) && defined(LED_MATRIX_SPLIT) - -#if defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - rgb_matrix_sync_t rgb_matrix_sync; -#endif // defined(RGB_MATRIX_ENABLE) && defined(RGB_MATRIX_SPLIT) - -#if defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - uint8_t current_wpm; -#endif // defined(WPM_ENABLE) && defined(SPLIT_WPM_ENABLE) - -#if defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - uint8_t current_oled_state; -#endif // defined(OLED_ENABLE) && defined(SPLIT_OLED_ENABLE) - -#if defined(ST7565_ENABLE) && defined(SPLIT_ST7565_ENABLE) - uint8_t current_st7565_state; -#endif // ST7565_ENABLE(OLED_ENABLE) && defined(SPLIT_ST7565_ENABLE) - -#if defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - split_slave_pointing_sync_t pointing; -#endif // defined(POINTING_DEVICE_ENABLE) && defined(SPLIT_POINTING_ENABLE) - -#if defined(SPLIT_WATCHDOG_ENABLE) - bool watchdog_pinged; -#endif // defined(SPLIT_WATCHDOG_ENABLE) - -#if defined(HAPTIC_ENABLE) && defined(SPLIT_HAPTIC_ENABLE) - split_slave_haptic_sync_t haptic_sync; -#endif // defined(HAPTIC_ENABLE) - -#if defined(SPLIT_ACTIVITY_ENABLE) - split_slave_activity_sync_t activity_sync; -#endif // defined(SPLIT_ACTIVITY_ENABLE) - -#if defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - rpc_sync_info_t rpc_info; - uint8_t rpc_m2s_buffer[RPC_M2S_BUFFER_SIZE]; - uint8_t rpc_s2m_buffer[RPC_S2M_BUFFER_SIZE]; -#endif // defined(SPLIT_TRANSACTION_IDS_KB) || defined(SPLIT_TRANSACTION_IDS_USER) - -#if defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) - os_variant_t detected_os; -#endif // defined(OS_DETECTION_ENABLE) && defined(SPLIT_DETECTED_OS_ENABLE) -} split_shared_memory_t; - -extern split_shared_memory_t *const split_shmem; diff --git a/quantum/sync_timer.c b/quantum/sync_timer.c deleted file mode 100644 index 217891233f02..000000000000 --- a/quantum/sync_timer.c +++ /dev/null @@ -1,60 +0,0 @@ -/* -Copyright (C) 2020 Ryan Caltabiano - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -If you happen to meet one of the copyright holders in a bar you are obligated -to buy them one pint of beer. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#include "sync_timer.h" -#include "keyboard.h" - -#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) -volatile int32_t sync_timer_ms; - -void sync_timer_init(void) { - sync_timer_ms = 0; -} - -void sync_timer_update(uint32_t time) { - if (is_keyboard_master()) return; - sync_timer_ms = time - timer_read32(); -} - -uint16_t sync_timer_read(void) { - if (is_keyboard_master()) return timer_read(); - return sync_timer_read32(); -} - -uint32_t sync_timer_read32(void) { - if (is_keyboard_master()) return timer_read32(); - return sync_timer_ms + timer_read32(); -} - -uint16_t sync_timer_elapsed(uint16_t last) { - if (is_keyboard_master()) return timer_elapsed(last); - return TIMER_DIFF_16(sync_timer_read(), last); -} - -uint32_t sync_timer_elapsed32(uint32_t last) { - if (is_keyboard_master()) return timer_elapsed32(last); - return TIMER_DIFF_32(sync_timer_read32(), last); -} -#endif diff --git a/quantum/sync_timer.h b/quantum/sync_timer.h deleted file mode 100644 index 9ddef45bb263..000000000000 --- a/quantum/sync_timer.h +++ /dev/null @@ -1,54 +0,0 @@ -/* -Copyright (C) 2020 Ryan Caltabiano - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -If you happen to meet one of the copyright holders in a bar you are obligated -to buy them one pint of beer. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ - -#pragma once - -#include -#include "timer.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(SPLIT_KEYBOARD) && !defined(DISABLE_SYNC_TIMER) -void sync_timer_init(void); -void sync_timer_update(uint32_t time); -uint16_t sync_timer_read(void); -uint32_t sync_timer_read32(void); -uint16_t sync_timer_elapsed(uint16_t last); -uint32_t sync_timer_elapsed32(uint32_t last); -#else -# define sync_timer_init() -# define sync_timer_clear() -# define sync_timer_update(t) -# define sync_timer_read() timer_read() -# define sync_timer_read32() timer_read32() -# define sync_timer_elapsed(t) timer_elapsed(t) -# define sync_timer_elapsed32(t) timer_elapsed32(t) -#endif - -#ifdef __cplusplus -} -#endif diff --git a/quantum/tri_layer.c b/quantum/tri_layer.c deleted file mode 100644 index a5e3f8cb477f..000000000000 --- a/quantum/tri_layer.c +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "tri_layer.h" -#include - -static uint8_t tri_layer_lower_layer = TRI_LAYER_LOWER_LAYER; -static uint8_t tri_layer_upper_layer = TRI_LAYER_UPPER_LAYER; -static uint8_t tri_layer_adjust_layer = TRI_LAYER_ADJUST_LAYER; - -void set_tri_layer_lower_layer(uint8_t layer) { - tri_layer_lower_layer = layer; -} - -void set_tri_layer_upper_layer(uint8_t layer) { - tri_layer_upper_layer = layer; -} - -void set_tri_layer_adjust_layer(uint8_t layer) { - tri_layer_adjust_layer = layer; -} - -void set_tri_layer_layers(uint8_t lower, uint8_t raise, uint8_t adjust) { - tri_layer_lower_layer = lower; - tri_layer_upper_layer = raise; - tri_layer_adjust_layer = adjust; -} - -uint8_t get_tri_layer_lower_layer(void) { - return tri_layer_lower_layer; -} - -uint8_t get_tri_layer_upper_layer(void) { - return tri_layer_upper_layer; -} - -uint8_t get_tri_layer_adjust_layer(void) { - return tri_layer_adjust_layer; -} diff --git a/quantum/tri_layer.h b/quantum/tri_layer.h deleted file mode 100644 index 3341ebffb288..000000000000 --- a/quantum/tri_layer.h +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2023 QMK -// SPDX-License-Identifier: GPL-2.0-or-later - -#include - -#ifndef TRI_LAYER_LOWER_LAYER -# define TRI_LAYER_LOWER_LAYER 1 -#endif -#ifndef TRI_LAYER_UPPER_LAYER -# define TRI_LAYER_UPPER_LAYER 2 -#endif -#ifndef TRI_LAYER_ADJUST_LAYER -# define TRI_LAYER_ADJUST_LAYER 3 -#endif - -/** - * @brief Set the tri layer lower layer index - * - * @param layer - */ -void set_tri_layer_lower_layer(uint8_t layer); -/** - * @brief Set the tri layer upper layer index - * - * @param layer - */ -void set_tri_layer_upper_layer(uint8_t layer); -/** - * @brief Set the tri layer adjust layer index - * - * @param layer - */ -void set_tri_layer_adjust_layer(uint8_t layer); -/** - * @brief Set the tri layer indices - * - * @param lower - * @param upper - * @param adjust - */ -void set_tri_layer_layers(uint8_t lower, uint8_t upper, uint8_t adjust); -/** - * @brief Get the tri layer lower layer index - * - * @return uint8_t - */ -uint8_t get_tri_layer_lower_layer(void); -/** - * @brief Get the tri layer upper layer index - * - * @return uint8_t - */ -uint8_t get_tri_layer_upper_layer(void); -/** - * @brief Get the tri layer adjust layer index - * - * @return uint8_t - */ -uint8_t get_tri_layer_adjust_layer(void); diff --git a/quantum/unicode/unicode.c b/quantum/unicode/unicode.c deleted file mode 100644 index 35cb62e70045..000000000000 --- a/quantum/unicode/unicode.c +++ /dev/null @@ -1,386 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#include "unicode.h" - -#include "eeprom.h" -#include "eeconfig.h" -#include "action.h" -#include "action_util.h" -#include "host.h" -#include "keycode.h" -#include "wait.h" -#include "send_string.h" -#include "utf8.h" - -#if defined(AUDIO_ENABLE) -# include "audio.h" -#endif - -#if defined(UNICODE_ENABLE) + defined(UNICODEMAP_ENABLE) + defined(UCIS_ENABLE) > 1 -# error "Cannot enable more than one Unicode method (UNICODE, UNICODEMAP, UCIS) at the same time" -#endif - -// Keycodes used for starting Unicode input on different platforms -#ifndef UNICODE_KEY_MAC -# define UNICODE_KEY_MAC KC_LEFT_ALT -#endif -#ifndef UNICODE_KEY_LNX -# define UNICODE_KEY_LNX LCTL(LSFT(KC_U)) -#endif -#ifndef UNICODE_KEY_WINC -# define UNICODE_KEY_WINC KC_RIGHT_ALT -#endif - -// Comma-delimited, ordered list of input modes selected for use (e.g. in cycle) -// Example: #define UNICODE_SELECTED_MODES UNICODE_MODE_WINCOMPOSE, UNICODE_MODE_LINUX -#ifndef UNICODE_SELECTED_MODES -# define UNICODE_SELECTED_MODES -1 -#endif - -// Whether input mode changes in cycle should be written to EEPROM -#ifndef UNICODE_CYCLE_PERSIST -# define UNICODE_CYCLE_PERSIST true -#endif - -// Delay between starting Unicode input and sending a sequence, in ms -#ifndef UNICODE_TYPE_DELAY -# define UNICODE_TYPE_DELAY 10 -#endif - -unicode_config_t unicode_config; -uint8_t unicode_saved_mods; -led_t unicode_saved_led_state; - -#if UNICODE_SELECTED_MODES != -1 -static uint8_t selected[] = {UNICODE_SELECTED_MODES}; -static int8_t selected_count = ARRAY_SIZE(selected); -static int8_t selected_index; -#endif - -/** \brief unicode input mode set at user level - * - * Run user code on unicode input mode change - */ -__attribute__((weak)) void unicode_input_mode_set_user(uint8_t input_mode) {} - -/** \brief unicode input mode set at keyboard level - * - * Run keyboard code on unicode input mode change - */ -__attribute__((weak)) void unicode_input_mode_set_kb(uint8_t input_mode) { - unicode_input_mode_set_user(input_mode); -} - -#ifdef AUDIO_ENABLE -# ifdef UNICODE_SONG_MAC -static float song_mac[][2] = UNICODE_SONG_MAC; -# endif -# ifdef UNICODE_SONG_LNX -static float song_lnx[][2] = UNICODE_SONG_LNX; -# endif -# ifdef UNICODE_SONG_WIN -static float song_win[][2] = UNICODE_SONG_WIN; -# endif -# ifdef UNICODE_SONG_BSD -static float song_bsd[][2] = UNICODE_SONG_BSD; -# endif -# ifdef UNICODE_SONG_WINC -static float song_winc[][2] = UNICODE_SONG_WINC; -# endif -# ifdef UNICODE_SONG_EMACS -static float song_emacs[][2] = UNICODE_SONG_EMACS; -# endif - -static void unicode_play_song(uint8_t mode) { - switch (mode) { -# ifdef UNICODE_SONG_MAC - case UNICODE_MODE_MACOS: - PLAY_SONG(song_mac); - break; -# endif -# ifdef UNICODE_SONG_LNX - case UNICODE_MODE_LINUX: - PLAY_SONG(song_lnx); - break; -# endif -# ifdef UNICODE_SONG_WIN - case UNICODE_MODE_WINDOWS: - PLAY_SONG(song_win); - break; -# endif -# ifdef UNICODE_SONG_BSD - case UNICODE_MODE_BSD: - PLAY_SONG(song_bsd); - break; -# endif -# ifdef UNICODE_SONG_WINC - case UNICODE_MODE_WINCOMPOSE: - PLAY_SONG(song_winc); - break; -# endif -# ifdef UNICODE_SONG_EMACS - case UNICODE_MODE_EMACS: - PLAY_SONG(song_emacs); - break; -# endif - } -} -#endif - -void unicode_input_mode_init(void) { - unicode_config.raw = eeprom_read_byte(EECONFIG_UNICODEMODE); -#if UNICODE_SELECTED_MODES != -1 -# if UNICODE_CYCLE_PERSIST - // Find input_mode in selected modes - int8_t i; - for (i = 0; i < selected_count; i++) { - if (selected[i] == unicode_config.input_mode) { - selected_index = i; - break; - } - } - if (i == selected_count) { - // Not found: input_mode isn't selected, change to one that is - unicode_config.input_mode = selected[selected_index = 0]; - } -# else - // Always change to the first selected input mode - unicode_config.input_mode = selected[selected_index = 0]; -# endif -#endif - unicode_input_mode_set_kb(unicode_config.input_mode); - dprintf("Unicode input mode init to: %u\n", unicode_config.input_mode); -} - -uint8_t get_unicode_input_mode(void) { - return unicode_config.input_mode; -} - -void set_unicode_input_mode(uint8_t mode) { - unicode_config.input_mode = mode; - persist_unicode_input_mode(); -#ifdef AUDIO_ENABLE - unicode_play_song(mode); -#endif - unicode_input_mode_set_kb(mode); - dprintf("Unicode input mode set to: %u\n", unicode_config.input_mode); -} - -void cycle_unicode_input_mode(int8_t offset) { -#if UNICODE_SELECTED_MODES != -1 - selected_index = (selected_index + offset) % selected_count; - if (selected_index < 0) { - selected_index += selected_count; - } - unicode_config.input_mode = selected[selected_index]; -# if UNICODE_CYCLE_PERSIST - persist_unicode_input_mode(); -# endif -# ifdef AUDIO_ENABLE - unicode_play_song(unicode_config.input_mode); -# endif - unicode_input_mode_set_kb(unicode_config.input_mode); - dprintf("Unicode input mode cycle to: %u\n", unicode_config.input_mode); -#endif -} - -void persist_unicode_input_mode(void) { - eeprom_update_byte(EECONFIG_UNICODEMODE, unicode_config.input_mode); -} - -__attribute__((weak)) void unicode_input_start(void) { - unicode_saved_led_state = host_keyboard_led_state(); - - // Note the order matters here! - // Need to do this before we mess around with the mods, or else - // UNICODE_KEY_LNX (which is usually Ctrl-Shift-U) might not work - // correctly in the shifted case. - if (unicode_config.input_mode == UNICODE_MODE_LINUX && unicode_saved_led_state.caps_lock) { - tap_code(KC_CAPS_LOCK); - } - - unicode_saved_mods = get_mods(); // Save current mods - clear_mods(); // Unregister mods to start from a clean state - clear_weak_mods(); - - switch (unicode_config.input_mode) { - case UNICODE_MODE_MACOS: - register_code(UNICODE_KEY_MAC); - break; - case UNICODE_MODE_LINUX: - tap_code16(UNICODE_KEY_LNX); - break; - case UNICODE_MODE_WINDOWS: - // For increased reliability, use numpad keys for inputting digits - if (!unicode_saved_led_state.num_lock) { - tap_code(KC_NUM_LOCK); - } - register_code(KC_LEFT_ALT); - wait_ms(UNICODE_TYPE_DELAY); - tap_code(KC_KP_PLUS); - break; - case UNICODE_MODE_WINCOMPOSE: - tap_code(UNICODE_KEY_WINC); - tap_code(KC_U); - break; - case UNICODE_MODE_EMACS: - // The usual way to type unicode in emacs is C-x-8 then the unicode number in hex - tap_code16(LCTL(KC_X)); - tap_code16(KC_8); - tap_code16(KC_ENTER); - break; - } - - wait_ms(UNICODE_TYPE_DELAY); -} - -__attribute__((weak)) void unicode_input_finish(void) { - switch (unicode_config.input_mode) { - case UNICODE_MODE_MACOS: - unregister_code(UNICODE_KEY_MAC); - break; - case UNICODE_MODE_LINUX: - tap_code(KC_SPACE); - if (unicode_saved_led_state.caps_lock) { - tap_code(KC_CAPS_LOCK); - } - break; - case UNICODE_MODE_WINDOWS: - unregister_code(KC_LEFT_ALT); - if (!unicode_saved_led_state.num_lock) { - tap_code(KC_NUM_LOCK); - } - break; - case UNICODE_MODE_WINCOMPOSE: - tap_code(KC_ENTER); - break; - case UNICODE_MODE_EMACS: - tap_code16(KC_ENTER); - break; - } - - set_mods(unicode_saved_mods); // Reregister previously set mods -} - -__attribute__((weak)) void unicode_input_cancel(void) { - switch (unicode_config.input_mode) { - case UNICODE_MODE_MACOS: - unregister_code(UNICODE_KEY_MAC); - break; - case UNICODE_MODE_LINUX: - tap_code(KC_ESCAPE); - if (unicode_saved_led_state.caps_lock) { - tap_code(KC_CAPS_LOCK); - } - break; - case UNICODE_MODE_WINCOMPOSE: - tap_code(KC_ESCAPE); - break; - case UNICODE_MODE_WINDOWS: - unregister_code(KC_LEFT_ALT); - if (!unicode_saved_led_state.num_lock) { - tap_code(KC_NUM_LOCK); - } - break; - case UNICODE_MODE_EMACS: - tap_code16(LCTL(KC_G)); // C-g cancels - break; - } - - set_mods(unicode_saved_mods); // Reregister previously set mods -} - -// clang-format off - -static void send_nibble_wrapper(uint8_t digit) { - if (unicode_config.input_mode == UNICODE_MODE_WINDOWS) { - uint8_t kc = digit < 10 - ? KC_KP_1 + (10 + digit - 1) % 10 - : KC_A + (digit - 10); - tap_code(kc); - return; - } - send_nibble(digit); -} - -// clang-format on - -void register_hex(uint16_t hex) { - for (int i = 3; i >= 0; i--) { - uint8_t digit = ((hex >> (i * 4)) & 0xF); - send_nibble_wrapper(digit); - } -} - -void register_hex32(uint32_t hex) { - bool first_digit = true; - bool needs_leading_zero = (unicode_config.input_mode == UNICODE_MODE_WINCOMPOSE); - for (int i = 7; i >= 0; i--) { - // Work out the digit we're going to transmit - uint8_t digit = ((hex >> (i * 4)) & 0xF); - - // If we're still searching for the first digit, and found one - // that needs a leading zero sent out, send the zero. - if (first_digit && needs_leading_zero && digit > 9) { - send_nibble_wrapper(0); - } - - // Always send digits (including zero) if we're down to the last - // two bytes of nibbles. - bool must_send = i < 4; - - // If we've found a digit worth transmitting, do so. - if (digit != 0 || !first_digit || must_send) { - send_nibble_wrapper(digit); - first_digit = false; - } - } -} - -void register_unicode(uint32_t code_point) { - if (code_point > 0x10FFFF || (code_point > 0xFFFF && unicode_config.input_mode == UNICODE_MODE_WINDOWS)) { - // Code point out of range, do nothing - return; - } - - unicode_input_start(); - if (code_point > 0xFFFF && unicode_config.input_mode == UNICODE_MODE_MACOS) { - // Convert code point to UTF-16 surrogate pair on macOS - code_point -= 0x10000; - uint32_t lo = code_point & 0x3FF, hi = (code_point & 0xFFC00) >> 10; - register_hex32(hi + 0xD800); - register_hex32(lo + 0xDC00); - } else { - register_hex32(code_point); - } - unicode_input_finish(); -} - -void send_unicode_string(const char *str) { - if (!str) { - return; - } - - while (*str) { - int32_t code_point = 0; - str = decode_utf8(str, &code_point); - - if (code_point >= 0) { - register_unicode(code_point); - } - } -} diff --git a/quantum/unicode/unicode.h b/quantum/unicode/unicode.h deleted file mode 100644 index 06505d87c0c9..000000000000 --- a/quantum/unicode/unicode.h +++ /dev/null @@ -1,168 +0,0 @@ -/* Copyright 2022 - * - * 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 . - */ - -#pragma once - -#include - -#include "quantum.h" - -typedef union { - uint8_t raw; - struct { - uint8_t input_mode : 8; - }; -} unicode_config_t; - -_Static_assert(sizeof(unicode_config_t) == sizeof(uint8_t), "Unicode EECONFIG out of spec."); - -extern unicode_config_t unicode_config; - -enum unicode_input_modes { - UNICODE_MODE_MACOS, // macOS using Unicode Hex Input - UNICODE_MODE_LINUX, // Linux using IBus - UNICODE_MODE_WINDOWS, // Windows using EnableHexNumpad - UNICODE_MODE_BSD, // BSD (not implemented) - UNICODE_MODE_WINCOMPOSE, // Windows using WinCompose (https://github.com/samhocevar/wincompose) - UNICODE_MODE_EMACS, // Emacs is an operating system in search of a good text editor - - UNICODE_MODE_COUNT // Number of available input modes (always leave at the end) -}; - -void unicode_input_mode_init(void); -uint8_t get_unicode_input_mode(void); -void set_unicode_input_mode(uint8_t mode); -void cycle_unicode_input_mode(int8_t offset); -void persist_unicode_input_mode(void); - -void unicode_input_mode_set_user(uint8_t input_mode); -void unicode_input_mode_set_kb(uint8_t input_mode); - -void unicode_input_start(void); -void unicode_input_finish(void); -void unicode_input_cancel(void); - -void register_hex(uint16_t hex); -void register_hex32(uint32_t hex); -void register_unicode(uint32_t code_point); - -void send_unicode_string(const char *str); - -// clang-format off - -#define UC_BSPC UC(0x0008) // (backspace) - -#define UC_SPC UC(0x0020) // (space) -#define UC_EXLM UC(0x0021) // ! -#define UC_DQUT UC(0x0022) // " -#define UC_HASH UC(0x0023) // # -#define UC_DLR UC(0x0024) // $ -#define UC_PERC UC(0x0025) // % -#define UC_AMPR UC(0x0026) // & -#define UC_QUOT UC(0x0027) // ' -#define UC_LPRN UC(0x0028) // ( -#define UC_RPRN UC(0x0029) // ) -#define UC_ASTR UC(0x002A) // * -#define UC_PLUS UC(0x002B) // + -#define UC_COMM UC(0x002C) // , -#define UC_DASH UC(0x002D) // - -#define UC_DOT UC(0x002E) // . -#define UC_SLSH UC(0x002F) // / - -#define UC_0 UC(0x0030) // 0 -#define UC_1 UC(0x0031) // 1 -#define UC_2 UC(0x0032) // 2 -#define UC_3 UC(0x0033) // 3 -#define UC_4 UC(0x0034) // 4 -#define UC_5 UC(0x0035) // 5 -#define UC_6 UC(0x0036) // 6 -#define UC_7 UC(0x0037) // 7 -#define UC_8 UC(0x0038) // 8 -#define UC_9 UC(0x0039) // 9 -#define UC_COLN UC(0x003A) // : -#define UC_SCLN UC(0x003B) // ; -#define UC_LT UC(0x003C) // < -#define UC_EQL UC(0x003D) // = -#define UC_GT UC(0x003E) // > -#define UC_QUES UC(0x003F) // ? - -#define UC_AT UC(0x0040) // @ -#define UC_A UC(0x0041) // A -#define UC_B UC(0x0042) // B -#define UC_C UC(0x0043) // C -#define UC_D UC(0x0044) // D -#define UC_E UC(0x0045) // E -#define UC_F UC(0x0046) // F -#define UC_G UC(0x0047) // G -#define UC_H UC(0x0048) // H -#define UC_I UC(0x0049) // I -#define UC_J UC(0x004A) // J -#define UC_K UC(0x004B) // K -#define UC_L UC(0x004C) // L -#define UC_M UC(0x004D) // M -#define UC_N UC(0x004E) // N -#define UC_O UC(0x004F) // O - -#define UC_P UC(0x0050) // P -#define UC_Q UC(0x0051) // Q -#define UC_R UC(0x0052) // R -#define UC_S UC(0x0053) // S -#define UC_T UC(0x0054) // T -#define UC_U UC(0x0055) // U -#define UC_V UC(0x0056) // V -#define UC_W UC(0x0057) // W -#define UC_X UC(0x0058) // X -#define UC_Y UC(0x0059) // Y -#define UC_Z UC(0x005A) // Z -#define UC_LBRC UC(0x005B) // [ -#define UC_BSLS UC(0x005C) // (backslash) -#define UC_RBRC UC(0x005D) // ] -#define UC_CIRM UC(0x005E) // ^ -#define UC_UNDR UC(0x005F) // _ - -#define UC_GRV UC(0x0060) // ` -#define UC_a UC(0x0061) // a -#define UC_b UC(0x0062) // b -#define UC_c UC(0x0063) // c -#define UC_d UC(0x0064) // d -#define UC_e UC(0x0065) // e -#define UC_f UC(0x0066) // f -#define UC_g UC(0x0067) // g -#define UC_h UC(0x0068) // h -#define UC_i UC(0x0069) // i -#define UC_j UC(0x006A) // j -#define UC_k UC(0x006B) // k -#define UC_l UC(0x006C) // l -#define UC_m UC(0x006D) // m -#define UC_n UC(0x006E) // n -#define UC_o UC(0x006F) // o - -#define UC_p UC(0x0070) // p -#define UC_q UC(0x0071) // q -#define UC_r UC(0x0072) // r -#define UC_s UC(0x0073) // s -#define UC_t UC(0x0074) // t -#define UC_u UC(0x0075) // u -#define UC_v UC(0x0076) // v -#define UC_w UC(0x0077) // w -#define UC_x UC(0x0078) // x -#define UC_y UC(0x0079) // y -#define UC_z UC(0x007A) // z -#define UC_LCBR UC(0x007B) // { -#define UC_PIPE UC(0x007C) // | -#define UC_RCBR UC(0x007D) // } -#define UC_TILD UC(0x007E) // ~ -#define UC_DEL UC(0x007F) // (delete) diff --git a/quantum/unicode/utf8.c b/quantum/unicode/utf8.c deleted file mode 100644 index 4b2cd4d8d4a5..000000000000 --- a/quantum/unicode/utf8.c +++ /dev/null @@ -1,46 +0,0 @@ -/* Copyright 2021 QMK - * - * 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 . - */ - -#include "utf8.h" - -// Borrowed from https://nullprogram.com/blog/2017/10/06/ -const char *decode_utf8(const char *str, int32_t *code_point) { - const char *next; - - if (str[0] < 0x80) { // U+0000-007F - *code_point = str[0]; - next = str + 1; - } else if ((str[0] & 0xE0) == 0xC0) { // U+0080-07FF - *code_point = ((int32_t)(str[0] & 0x1F) << 6) | ((int32_t)(str[1] & 0x3F) << 0); - next = str + 2; - } else if ((str[0] & 0xF0) == 0xE0) { // U+0800-FFFF - *code_point = ((int32_t)(str[0] & 0x0F) << 12) | ((int32_t)(str[1] & 0x3F) << 6) | ((int32_t)(str[2] & 0x3F) << 0); - next = str + 3; - } else if ((str[0] & 0xF8) == 0xF0 && (str[0] <= 0xF4)) { // U+10000-10FFFF - *code_point = ((int32_t)(str[0] & 0x07) << 18) | ((int32_t)(str[1] & 0x3F) << 12) | ((int32_t)(str[2] & 0x3F) << 6) | ((int32_t)(str[3] & 0x3F) << 0); - next = str + 4; - } else { - *code_point = -1; - next = str + 1; - } - - // part of a UTF-16 surrogate pair - invalid - if (*code_point >= 0xD800 && *code_point <= 0xDFFF) { - *code_point = -1; - } - - return next; -} diff --git a/quantum/util.h b/quantum/util.h deleted file mode 100644 index 9c034cc404f7..000000000000 --- a/quantum/util.h +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2022 Stefan Kerkmann (KarlK90) -// Copyright 2011 Jun Wako -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "bitwise.h" - -// convert to string -#define STR(s) XSTR(s) -#define XSTR(s) #s - -#if !defined(MIN) -# define MIN(x, y) (((x) < (y)) ? (x) : (y)) -#endif - -#if !defined(MAX) -# define MAX(x, y) (((x) > (y)) ? (x) : (y)) -#endif - -#if !defined(CEILING) -/** - * @brief Computes the rounded up result of a division of two integers at - * compile time. - */ -# define CEILING(dividend, divisor) (((dividend) + (divisor)-1) / (divisor)) -#endif - -#if !defined(IS_ARRAY) -/** - * @brief Returns true if the value is an array, false if it's a pointer. - * - * This macro is ill-formed for scalars, which is OK for its intended use in - * ARRAY_SIZE. - */ -# define IS_ARRAY(value) (!__builtin_types_compatible_p(typeof((value)), typeof(&(value)[0]))) -#endif - -#if !defined(ARRAY_SIZE) -/** - * @brief Computes the number of elements of the given array at compile time. - * - * This Macro can only be used for statically allocated arrays that have not - * been decayed into a pointer. This is detected at compile time, though the - * error message for scalar values is poor. - */ -# define ARRAY_SIZE(array) (__builtin_choose_expr(IS_ARRAY((array)), sizeof((array)) / sizeof((array)[0]), (void)0)) -#endif diff --git a/quantum/variable_trace.c b/quantum/variable_trace.c deleted file mode 100644 index 00562bc9200a..000000000000 --- a/quantum/variable_trace.c +++ /dev/null @@ -1,123 +0,0 @@ -/* Copyright 2016 Fred Sundvik - * - * 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 . - */ - -#include "variable_trace.h" -#include -#include - -#ifdef NO_PRINT -# error "You need undef NO_PRINT to use the variable trace feature" -#endif - -#ifndef CONSOLE_ENABLE -# error "The console needs to be enabled in the makefile to use the variable trace feature" -#endif - -#define NUM_TRACED_VARIABLES 1 -#ifndef MAX_VARIABLE_TRACE_SIZE -# define MAX_VARIABLE_TRACE_SIZE 4 -#endif - -typedef struct { - const char* name; - void* addr; - unsigned size; - const char* func; - int line; - uint8_t last_value[MAX_VARIABLE_TRACE_SIZE]; - -} traced_variable_t; - -static traced_variable_t traced_variables[NUM_TRACED_VARIABLES]; - -void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line) { - verify_traced_variables(func, line); - if (size > MAX_VARIABLE_TRACE_SIZE) { -#if defined(__AVR__) - xprintf("Traced variable \"%S\" exceeds the maximum size %d\n", name, size); -#else - xprintf("Traced variable \"%s\" exceeds the maximum size %d\n", name, size); -#endif - size = MAX_VARIABLE_TRACE_SIZE; - } - int index = -1; - for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { - if (index == -1 && traced_variables[i].addr == NULL) { - index = i; - } else if (strcmp_P(name, traced_variables[i].name) == 0) { - index = i; - break; - } - } - - if (index == -1) { - xprintf("You can only trace %d variables at the same time\n", NUM_TRACED_VARIABLES); - return; - } - - traced_variable_t* t = &traced_variables[index]; - t->name = name; - t->addr = addr; - t->size = size; - t->func = func; - t->line = line; - memcpy(&t->last_value[0], addr, size); -} - -void remove_traced_variable(const char* name, const char* func, int line) { - verify_traced_variables(func, line); - for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { - if (strcmp_P(name, traced_variables[i].name) == 0) { - traced_variables[i].name = 0; - traced_variables[i].addr = NULL; - break; - } - } -} - -void verify_traced_variables(const char* func, int line) { - for (int i = 0; i < NUM_TRACED_VARIABLES; i++) { - traced_variable_t* t = &traced_variables[i]; - if (t->addr != NULL && t->name != NULL) { - if (memcmp(t->last_value, t->addr, t->size) != 0) { -#if defined(__AVR__) - xprintf("Traced variable \"%S\" has been modified\n", t->name); - xprintf("Between %S:%d\n", t->func, t->line); - xprintf("And %S:%d\n", func, line); - -#else - xprintf("Traced variable \"%s\" has been modified\n", t->name); - xprintf("Between %s:%d\n", t->func, t->line); - xprintf("And %s:%d\n", func, line); -#endif - xprintf("Previous value "); - for (int j = 0; j < t->size; j++) { - print_hex8(t->last_value[j]); - } - xprintf("\nNew value "); - uint8_t* addr = (uint8_t*)(t->addr); - for (int j = 0; j < t->size; j++) { - print_hex8(addr[j]); - } - xprintf("\n"); - memcpy(t->last_value, addr, t->size); - } - } - - t->func = func; - t->line = line; - } -} diff --git a/quantum/variable_trace.h b/quantum/variable_trace.h deleted file mode 100644 index f4d1253800cd..000000000000 --- a/quantum/variable_trace.h +++ /dev/null @@ -1,47 +0,0 @@ -/* Copyright 2016 Fred Sundvik - * - * 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 . - */ - -#pragma once - -// For more information about the variable tracing see the readme. - -#include "print.h" - -#ifdef NUM_TRACED_VARIABLES - -// Start tracing a variable at the memory address addr -// The name can be anything and is used only for reporting -// The size should usually be the same size as the variable you are interested in -# define ADD_TRACED_VARIABLE(name, addr, size) add_traced_variable(PSTR(name), (void*)addr, size, PSTR(__FILE__), __LINE__) - -// Stop tracing the variable with the given name -# define REMOVE_TRACED_VARIABLE(name) remove_traced_variable(PSTR(name), PSTR(__FILE__), __LINE__) - -// Call to get messages when the variable has been changed -# define VERIFY_TRACED_VARIABLES() verify_traced_variables(PSTR(__FILE__), __LINE__) - -#else - -# define ADD_TRACED_VARIABLE(name, addr, size) -# define REMOVE_TRACED_VARIABLE(name) -# define VERIFY_TRACED_VARIABLES() - -#endif - -// Don't call directly, use the macros instead -void add_traced_variable(const char* name, void* addr, unsigned size, const char* func, int line); -void remove_traced_variable(const char* name, const char* func, int line); -void verify_traced_variables(const char* func, int line); diff --git a/quantum/velocikey.c b/quantum/velocikey.c deleted file mode 100644 index 03e91911f6c6..000000000000 --- a/quantum/velocikey.c +++ /dev/null @@ -1,40 +0,0 @@ -#include "velocikey.h" -#include "timer.h" -#include "eeconfig.h" -#include "eeprom.h" -#include "util.h" - -#define TYPING_SPEED_MAX_VALUE 200 -uint8_t typing_speed = 0; - -bool velocikey_enabled(void) { - return eeprom_read_byte(EECONFIG_VELOCIKEY) == 1; -} - -void velocikey_toggle(void) { - if (velocikey_enabled()) - eeprom_update_byte(EECONFIG_VELOCIKEY, 0); - else - eeprom_update_byte(EECONFIG_VELOCIKEY, 1); -} - -void velocikey_accelerate(void) { - if (typing_speed < TYPING_SPEED_MAX_VALUE) typing_speed += (TYPING_SPEED_MAX_VALUE / 100); -} - -void velocikey_decelerate(void) { - static uint16_t decay_timer = 0; - - if (timer_elapsed(decay_timer) > 500 || decay_timer == 0) { - if (typing_speed > 0) typing_speed -= 1; - // Decay a little faster at half of max speed - if (typing_speed > TYPING_SPEED_MAX_VALUE / 2) typing_speed -= 1; - // Decay even faster at 3/4 of max speed - if (typing_speed > TYPING_SPEED_MAX_VALUE / 4 * 3) typing_speed -= 2; - decay_timer = timer_read(); - } -} - -uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue) { - return MAX(minValue, maxValue - (maxValue - minValue) * ((float)typing_speed / TYPING_SPEED_MAX_VALUE)); -} diff --git a/quantum/velocikey.h b/quantum/velocikey.h deleted file mode 100644 index c375f82f7180..000000000000 --- a/quantum/velocikey.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include -#include - -bool velocikey_enabled(void); -void velocikey_toggle(void); -void velocikey_accelerate(void); -void velocikey_decelerate(void); -uint8_t velocikey_match_speed(uint8_t minValue, uint8_t maxValue); diff --git a/quantum/via.c b/quantum/via.c deleted file mode 100644 index c54e37a17516..000000000000 --- a/quantum/via.c +++ /dev/null @@ -1,760 +0,0 @@ -/* Copyright 2019 Jason Williams (Wilba) - * - * 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 . - */ - -#ifndef RAW_ENABLE -# error "RAW_ENABLE is not enabled" -#endif - -#ifndef DYNAMIC_KEYMAP_ENABLE -# error "DYNAMIC_KEYMAP_ENABLE is not enabled" -#endif - -#include "quantum.h" - -#include "via.h" - -#include "raw_hid.h" -#include "dynamic_keymap.h" -#include "eeprom.h" -#include "version.h" // for QMK_BUILDDATE used in EEPROM magic - -#if defined(RGB_MATRIX_ENABLE) -# include -#endif - -// Can be called in an overriding via_init_kb() to test if keyboard level code usage of -// EEPROM is invalid and use/save defaults. -bool via_eeprom_is_valid(void) { - char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" - uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); - uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); - uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); - - return (eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0) == magic0 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1) == magic1 && eeprom_read_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2) == magic2); -} - -// Sets VIA/keyboard level usage of EEPROM to valid/invalid -// Keyboard level code (eg. via_init_kb()) should not call this -void via_eeprom_set_valid(bool valid) { - char * p = QMK_BUILDDATE; // e.g. "2019-11-05-11:29:54" - uint8_t magic0 = ((p[2] & 0x0F) << 4) | (p[3] & 0x0F); - uint8_t magic1 = ((p[5] & 0x0F) << 4) | (p[6] & 0x0F); - uint8_t magic2 = ((p[8] & 0x0F) << 4) | (p[9] & 0x0F); - - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 0, valid ? magic0 : 0xFF); - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 1, valid ? magic1 : 0xFF); - eeprom_update_byte((void *)VIA_EEPROM_MAGIC_ADDR + 2, valid ? magic2 : 0xFF); -} - -// Override this at the keyboard code level to check -// VIA's EEPROM valid state and reset to defaults as needed. -// Used by keyboards that store their own state in EEPROM, -// for backlight, rotary encoders, etc. -// The override should not set via_eeprom_set_valid(true) as -// the caller also needs to check the valid state. -__attribute__((weak)) void via_init_kb(void) {} - -// Called by QMK core to initialize dynamic keymaps etc. -void via_init(void) { - // Let keyboard level test EEPROM valid state, - // but not set it valid, it is done here. - via_init_kb(); - via_set_layout_options_kb(via_get_layout_options()); - - // If the EEPROM has the magic, the data is good. - // OK to load from EEPROM. - if (!via_eeprom_is_valid()) { - eeconfig_init_via(); - } -} - -void eeconfig_init_via(void) { - // set the magic number to false, in case this gets interrupted - via_eeprom_set_valid(false); - // This resets the layout options - via_set_layout_options(VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT); - // This resets the keymaps in EEPROM to what is in flash. - dynamic_keymap_reset(); - // This resets the macros in EEPROM to nothing. - dynamic_keymap_macro_reset(); - // Save the magic number last, in case saving was interrupted - via_eeprom_set_valid(true); -} - -// This is generalized so the layout options EEPROM usage can be -// variable, between 1 and 4 bytes. -uint32_t via_get_layout_options(void) { - uint32_t value = 0; - // Start at the most significant byte - void *source = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR); - for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { - value = value << 8; - value |= eeprom_read_byte(source); - source++; - } - return value; -} - -__attribute__((weak)) void via_set_layout_options_kb(uint32_t value) {} - -void via_set_layout_options(uint32_t value) { - via_set_layout_options_kb(value); - // Start at the least significant byte - void *target = (void *)(VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE - 1); - for (uint8_t i = 0; i < VIA_EEPROM_LAYOUT_OPTIONS_SIZE; i++) { - eeprom_update_byte(target, value & 0xFF); - value = value >> 8; - target--; - } -} - -#if defined(AUDIO_ENABLE) -float via_device_indication_song[][2] = SONG(STARTUP_SOUND); -#endif // AUDIO_ENABLE - -// Used by VIA to tell a device to flash LEDs (or do something else) when that -// device becomes the active device being configured, on startup or switching -// between devices. This function will be called six times, at 200ms interval, -// with an incrementing value starting at zero. Since this function is called -// an even number of times, it can call a toggle function and leave things in -// the original state. -__attribute__((weak)) void via_set_device_indication(uint8_t value) { -#if defined(BACKLIGHT_ENABLE) - backlight_toggle(); -#endif // BACKLIGHT_ENABLE -#if defined(RGBLIGHT_ENABLE) - rgblight_toggle_noeeprom(); -#endif // RGBLIGHT_ENABLE -#if defined(RGB_MATRIX_ENABLE) - rgb_matrix_toggle_noeeprom(); -#endif // RGB_MATRIX_ENABLE -#if defined(AUDIO_ENABLE) - if (value == 0) { - wait_ms(10); - PLAY_SONG(via_device_indication_song); - } -#endif // AUDIO_ENABLE -} - -// Called by QMK core to process VIA-specific keycodes. -bool process_record_via(uint16_t keycode, keyrecord_t *record) { - // Handle macros - if (record->event.pressed) { - if (keycode >= QK_MACRO && keycode <= QK_MACRO_MAX) { - uint8_t id = keycode - QK_MACRO; - dynamic_keymap_macro_send(id); - return false; - } - } - - return true; -} - -// -// via_custom_value_command() has the default handling of custom values for Core modules. -// If a keyboard is using the default Core modules, it does not need to be overridden, -// the VIA keyboard definition will have matching channel/IDs. -// -// If a keyboard has some extra custom values, then via_custom_value_command_kb() can be -// overridden to handle the extra custom values, leaving via_custom_value_command() to -// handle the custom values for Core modules. -// -// If a keyboard has custom values and code that are overlapping with Core modules, -// then via_custom_value_command() can be overridden and call the same functions -// as the default implementation, or do whatever else is required. -// -// DO NOT call raw_hid_send() in the override function. -// - -// This is the default handler for "extra" custom values, i.e. keyboard-specific custom values -// that are not handled by via_custom_value_command(). -__attribute__((weak)) void via_custom_value_command_kb(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *command_id = &(data[0]); - // Return the unhandled state - *command_id = id_unhandled; -} - -// This is the default handler for custom value commands. -// It routes commands with channel IDs to command handlers as such: -// -// id_qmk_backlight_channel -> via_qmk_backlight_command() -// id_qmk_rgblight_channel -> via_qmk_rgblight_command() -// id_qmk_rgb_matrix_channel -> via_qmk_rgb_matrix_command() -// id_qmk_audio_channel -> via_qmk_audio_command() -// -__attribute__((weak)) void via_custom_value_command(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *channel_id = &(data[1]); - -#if defined(BACKLIGHT_ENABLE) - if (*channel_id == id_qmk_backlight_channel) { - via_qmk_backlight_command(data, length); - return; - } -#endif // BACKLIGHT_ENABLE - -#if defined(RGBLIGHT_ENABLE) - if (*channel_id == id_qmk_rgblight_channel) { - via_qmk_rgblight_command(data, length); - return; - } -#endif // RGBLIGHT_ENABLE - -#if defined(RGB_MATRIX_ENABLE) - if (*channel_id == id_qmk_rgb_matrix_channel) { - via_qmk_rgb_matrix_command(data, length); - return; - } -#endif // RGBLIGHT_ENABLE - -#if defined(AUDIO_ENABLE) - if (*channel_id == id_qmk_audio_channel) { - via_qmk_audio_command(data, length); - return; - } -#endif // AUDIO_ENABLE - - (void)channel_id; // force use of variable - - // If we haven't returned before here, then let the keyboard level code - // handle this, if it is overridden, otherwise by default, this will - // return the unhandled state. - via_custom_value_command_kb(data, length); -} - -// Keyboard level code can override this, but shouldn't need to. -// Controlling custom features should be done by overriding -// via_custom_value_command_kb() instead. -__attribute__((weak)) bool via_command_kb(uint8_t *data, uint8_t length) { - return false; -} - -void raw_hid_receive(uint8_t *data, uint8_t length) { - uint8_t *command_id = &(data[0]); - uint8_t *command_data = &(data[1]); - - // If via_command_kb() returns true, the command was fully - // handled, including calling raw_hid_send() - if (via_command_kb(data, length)) { - return; - } - - switch (*command_id) { - case id_get_protocol_version: { - command_data[0] = VIA_PROTOCOL_VERSION >> 8; - command_data[1] = VIA_PROTOCOL_VERSION & 0xFF; - break; - } - case id_get_keyboard_value: { - switch (command_data[0]) { - case id_uptime: { - uint32_t value = timer_read32(); - command_data[1] = (value >> 24) & 0xFF; - command_data[2] = (value >> 16) & 0xFF; - command_data[3] = (value >> 8) & 0xFF; - command_data[4] = value & 0xFF; - break; - } - case id_layout_options: { - uint32_t value = via_get_layout_options(); - command_data[1] = (value >> 24) & 0xFF; - command_data[2] = (value >> 16) & 0xFF; - command_data[3] = (value >> 8) & 0xFF; - command_data[4] = value & 0xFF; - break; - } - case id_switch_matrix_state: { - uint8_t offset = command_data[1]; - uint8_t rows = 28 / ((MATRIX_COLS + 7) / 8); - uint8_t i = 2; - for (uint8_t row = 0; row < rows && row + offset < MATRIX_ROWS; row++) { - matrix_row_t value = matrix_get_row(row + offset); -#if (MATRIX_COLS > 24) - command_data[i++] = (value >> 24) & 0xFF; -#endif -#if (MATRIX_COLS > 16) - command_data[i++] = (value >> 16) & 0xFF; -#endif -#if (MATRIX_COLS > 8) - command_data[i++] = (value >> 8) & 0xFF; -#endif - command_data[i++] = value & 0xFF; - } - break; - } - case id_firmware_version: { - uint32_t value = VIA_FIRMWARE_VERSION; - command_data[1] = (value >> 24) & 0xFF; - command_data[2] = (value >> 16) & 0xFF; - command_data[3] = (value >> 8) & 0xFF; - command_data[4] = value & 0xFF; - break; - } - default: { - // The value ID is not known - // Return the unhandled state - *command_id = id_unhandled; - break; - } - } - break; - } - case id_set_keyboard_value: { - switch (command_data[0]) { - case id_layout_options: { - uint32_t value = ((uint32_t)command_data[1] << 24) | ((uint32_t)command_data[2] << 16) | ((uint32_t)command_data[3] << 8) | (uint32_t)command_data[4]; - via_set_layout_options(value); - break; - } - case id_device_indication: { - uint8_t value = command_data[1]; - via_set_device_indication(value); - break; - } - default: { - // The value ID is not known - // Return the unhandled state - *command_id = id_unhandled; - break; - } - } - break; - } - case id_dynamic_keymap_get_keycode: { - uint16_t keycode = dynamic_keymap_get_keycode(command_data[0], command_data[1], command_data[2]); - command_data[3] = keycode >> 8; - command_data[4] = keycode & 0xFF; - break; - } - case id_dynamic_keymap_set_keycode: { - dynamic_keymap_set_keycode(command_data[0], command_data[1], command_data[2], (command_data[3] << 8) | command_data[4]); - break; - } - case id_dynamic_keymap_reset: { - dynamic_keymap_reset(); - break; - } - case id_custom_set_value: - case id_custom_get_value: - case id_custom_save: { - via_custom_value_command(data, length); - break; - } -#ifdef VIA_EEPROM_ALLOW_RESET - case id_eeprom_reset: { - via_eeprom_set_valid(false); - eeconfig_init_via(); - break; - } -#endif - case id_dynamic_keymap_macro_get_count: { - command_data[0] = dynamic_keymap_macro_get_count(); - break; - } - case id_dynamic_keymap_macro_get_buffer_size: { - uint16_t size = dynamic_keymap_macro_get_buffer_size(); - command_data[0] = size >> 8; - command_data[1] = size & 0xFF; - break; - } - case id_dynamic_keymap_macro_get_buffer: { - uint16_t offset = (command_data[0] << 8) | command_data[1]; - uint16_t size = command_data[2]; // size <= 28 - dynamic_keymap_macro_get_buffer(offset, size, &command_data[3]); - break; - } - case id_dynamic_keymap_macro_set_buffer: { - uint16_t offset = (command_data[0] << 8) | command_data[1]; - uint16_t size = command_data[2]; // size <= 28 - dynamic_keymap_macro_set_buffer(offset, size, &command_data[3]); - break; - } - case id_dynamic_keymap_macro_reset: { - dynamic_keymap_macro_reset(); - break; - } - case id_dynamic_keymap_get_layer_count: { - command_data[0] = dynamic_keymap_get_layer_count(); - break; - } - case id_dynamic_keymap_get_buffer: { - uint16_t offset = (command_data[0] << 8) | command_data[1]; - uint16_t size = command_data[2]; // size <= 28 - dynamic_keymap_get_buffer(offset, size, &command_data[3]); - break; - } - case id_dynamic_keymap_set_buffer: { - uint16_t offset = (command_data[0] << 8) | command_data[1]; - uint16_t size = command_data[2]; // size <= 28 - dynamic_keymap_set_buffer(offset, size, &command_data[3]); - break; - } -#ifdef ENCODER_MAP_ENABLE - case id_dynamic_keymap_get_encoder: { - uint16_t keycode = dynamic_keymap_get_encoder(command_data[0], command_data[1], command_data[2] != 0); - command_data[3] = keycode >> 8; - command_data[4] = keycode & 0xFF; - break; - } - case id_dynamic_keymap_set_encoder: { - dynamic_keymap_set_encoder(command_data[0], command_data[1], command_data[2] != 0, (command_data[3] << 8) | command_data[4]); - break; - } -#endif - default: { - // The command ID is not known - // Return the unhandled state - *command_id = id_unhandled; - break; - } - } - - // Return the same buffer, optionally with values changed - // (i.e. returning state to the host, or the unhandled state). - raw_hid_send(data, length); -} - -#if defined(BACKLIGHT_ENABLE) - -void via_qmk_backlight_command(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *command_id = &(data[0]); - uint8_t *value_id_and_data = &(data[2]); - - switch (*command_id) { - case id_custom_set_value: { - via_qmk_backlight_set_value(value_id_and_data); - break; - } - case id_custom_get_value: { - via_qmk_backlight_get_value(value_id_and_data); - break; - } - case id_custom_save: { - via_qmk_backlight_save(); - break; - } - default: { - *command_id = id_unhandled; - break; - } - } -} - -# if BACKLIGHT_LEVELS == 0 -# error BACKLIGHT_LEVELS == 0 -# endif - -void via_qmk_backlight_get_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_backlight_brightness: { - // level / BACKLIGHT_LEVELS * 255 - value_data[0] = ((uint16_t)get_backlight_level() * UINT8_MAX) / BACKLIGHT_LEVELS; - break; - } - case id_qmk_backlight_effect: { -# ifdef BACKLIGHT_BREATHING - value_data[0] = is_backlight_breathing() ? 1 : 0; -# else - value_data[0] = 0; -# endif - break; - } - } -} - -void via_qmk_backlight_set_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_backlight_brightness: { - // level / 255 * BACKLIGHT_LEVELS - backlight_level_noeeprom(((uint16_t)value_data[0] * BACKLIGHT_LEVELS) / UINT8_MAX); - break; - } - case id_qmk_backlight_effect: { -# ifdef BACKLIGHT_BREATHING - if (value_data[0] == 0) { - backlight_disable_breathing(); - } else { - backlight_enable_breathing(); - } -# endif - break; - } - } -} - -void via_qmk_backlight_save(void) { - eeconfig_update_backlight_current(); -} - -#endif // BACKLIGHT_ENABLE - -#if defined(RGBLIGHT_ENABLE) -# ifndef RGBLIGHT_LIMIT_VAL -# define RGBLIGHT_LIMIT_VAL 255 -# endif - -void via_qmk_rgblight_command(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *command_id = &(data[0]); - uint8_t *value_id_and_data = &(data[2]); - - switch (*command_id) { - case id_custom_set_value: { - via_qmk_rgblight_set_value(value_id_and_data); - break; - } - case id_custom_get_value: { - via_qmk_rgblight_get_value(value_id_and_data); - break; - } - case id_custom_save: { - via_qmk_rgblight_save(); - break; - } - default: { - *command_id = id_unhandled; - break; - } - } -} - -void via_qmk_rgblight_get_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_rgblight_brightness: { - value_data[0] = ((uint16_t)rgblight_get_val() * UINT8_MAX) / RGBLIGHT_LIMIT_VAL; - break; - } - case id_qmk_rgblight_effect: { - value_data[0] = rgblight_is_enabled() ? rgblight_get_mode() : 0; - break; - } - case id_qmk_rgblight_effect_speed: { - value_data[0] = rgblight_get_speed(); - break; - } - case id_qmk_rgblight_color: { - value_data[0] = rgblight_get_hue(); - value_data[1] = rgblight_get_sat(); - break; - } - } -} - -void via_qmk_rgblight_set_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_rgblight_brightness: { - rgblight_sethsv_noeeprom(rgblight_get_hue(), rgblight_get_sat(), ((uint16_t)value_data[0] * RGBLIGHT_LIMIT_VAL) / UINT8_MAX); - break; - } - case id_qmk_rgblight_effect: { - if (value_data[0] == 0) { - rgblight_disable_noeeprom(); - } else { - rgblight_enable_noeeprom(); - rgblight_mode_noeeprom(value_data[0]); - } - break; - } - case id_qmk_rgblight_effect_speed: { - rgblight_set_speed_noeeprom(value_data[0]); - break; - } - case id_qmk_rgblight_color: { - rgblight_sethsv_noeeprom(value_data[0], value_data[1], rgblight_get_val()); - break; - } - } -} - -void via_qmk_rgblight_save(void) { - eeconfig_update_rgblight_current(); -} - -#endif // QMK_RGBLIGHT_ENABLE - -#if defined(RGB_MATRIX_ENABLE) - -# if !defined(RGB_MATRIX_MAXIMUM_BRIGHTNESS) || RGB_MATRIX_MAXIMUM_BRIGHTNESS > UINT8_MAX -# undef RGB_MATRIX_MAXIMUM_BRIGHTNESS -# define RGB_MATRIX_MAXIMUM_BRIGHTNESS UINT8_MAX -# endif - -void via_qmk_rgb_matrix_command(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *command_id = &(data[0]); - uint8_t *value_id_and_data = &(data[2]); - - switch (*command_id) { - case id_custom_set_value: { - via_qmk_rgb_matrix_set_value(value_id_and_data); - break; - } - case id_custom_get_value: { - via_qmk_rgb_matrix_get_value(value_id_and_data); - break; - } - case id_custom_save: { - via_qmk_rgb_matrix_save(); - break; - } - default: { - *command_id = id_unhandled; - break; - } - } -} - -void via_qmk_rgb_matrix_get_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - - switch (*value_id) { - case id_qmk_rgb_matrix_brightness: { - value_data[0] = ((uint16_t)rgb_matrix_get_val() * UINT8_MAX) / RGB_MATRIX_MAXIMUM_BRIGHTNESS; - break; - } - case id_qmk_rgb_matrix_effect: { - value_data[0] = rgb_matrix_is_enabled() ? rgb_matrix_get_mode() : 0; - break; - } - case id_qmk_rgb_matrix_effect_speed: { - value_data[0] = rgb_matrix_get_speed(); - break; - } - case id_qmk_rgb_matrix_color: { - value_data[0] = rgb_matrix_get_hue(); - value_data[1] = rgb_matrix_get_sat(); - break; - } - } -} - -void via_qmk_rgb_matrix_set_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_rgb_matrix_brightness: { - rgb_matrix_sethsv_noeeprom(rgb_matrix_get_hue(), rgb_matrix_get_sat(), scale8(value_data[0], RGB_MATRIX_MAXIMUM_BRIGHTNESS)); - break; - } - case id_qmk_rgb_matrix_effect: { - if (value_data[0] == 0) { - rgb_matrix_disable_noeeprom(); - } else { - rgb_matrix_enable_noeeprom(); - rgb_matrix_mode_noeeprom(value_data[0]); - } - break; - } - case id_qmk_rgb_matrix_effect_speed: { - rgb_matrix_set_speed_noeeprom(value_data[0]); - break; - } - case id_qmk_rgb_matrix_color: { - rgb_matrix_sethsv_noeeprom(value_data[0], value_data[1], rgb_matrix_get_val()); - break; - } - } -} - -void via_qmk_rgb_matrix_save(void) { - eeconfig_update_rgb_matrix(); -} - -#endif // RGB_MATRIX_ENABLE - -#if defined(AUDIO_ENABLE) - -extern audio_config_t audio_config; - -void via_qmk_audio_command(uint8_t *data, uint8_t length) { - // data = [ command_id, channel_id, value_id, value_data ] - uint8_t *command_id = &(data[0]); - uint8_t *value_id_and_data = &(data[2]); - - switch (*command_id) { - case id_custom_set_value: { - via_qmk_audio_set_value(value_id_and_data); - break; - } - case id_custom_get_value: { - via_qmk_audio_get_value(value_id_and_data); - break; - } - case id_custom_save: { - via_qmk_audio_save(); - break; - } - default: { - *command_id = id_unhandled; - break; - } - } -} - -void via_qmk_audio_get_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_audio_enable: { - value_data[0] = audio_config.enable ? 1 : 0; - break; - } - case id_qmk_audio_clicky_enable: { - value_data[0] = audio_config.clicky_enable ? 1 : 0; - break; - } - } -} - -void via_qmk_audio_set_value(uint8_t *data) { - // data = [ value_id, value_data ] - uint8_t *value_id = &(data[0]); - uint8_t *value_data = &(data[1]); - switch (*value_id) { - case id_qmk_audio_enable: { - audio_config.enable = value_data[0] ? 1 : 0; - break; - } - case id_qmk_audio_clicky_enable: { - audio_config.clicky_enable = value_data[0] ? 1 : 0; - break; - } - } -} - -void via_qmk_audio_save(void) { - eeconfig_update_audio(audio_config.raw); -} - -#endif // QMK_AUDIO_ENABLE diff --git a/quantum/via.h b/quantum/via.h deleted file mode 100644 index ab4eb0502818..000000000000 --- a/quantum/via.h +++ /dev/null @@ -1,190 +0,0 @@ -/* Copyright 2019 Jason Williams (Wilba) - * - * 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 . - */ - -#pragma once - -#include "eeconfig.h" // for EECONFIG_SIZE - -// Keyboard level code can change where VIA stores the magic. -// The magic is the build date YYMMDD encoded as BCD in 3 bytes, -// thus installing firmware built on a different date to the one -// already installed can be detected and the EEPROM data is reset. -// The only reason this is important is in case EEPROM usage changes -// and the EEPROM was not explicitly reset by bootmagic lite. -#ifndef VIA_EEPROM_MAGIC_ADDR -# define VIA_EEPROM_MAGIC_ADDR (EECONFIG_SIZE) -#endif - -#define VIA_EEPROM_LAYOUT_OPTIONS_ADDR (VIA_EEPROM_MAGIC_ADDR + 3) - -// Changing the layout options size after release will invalidate EEPROM, -// but this is something that should be set correctly on initial implementation. -// 1 byte is enough for most uses (i.e. 8 binary states, or 6 binary + 1 ternary/quaternary ) -#ifndef VIA_EEPROM_LAYOUT_OPTIONS_SIZE -# define VIA_EEPROM_LAYOUT_OPTIONS_SIZE 1 -#endif - -// Allow override of the layout options default value. -// This requires advanced knowledge of how VIA stores layout options -// and is only really useful for setting a boolean layout option -// state to true by default. -#ifndef VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT -# define VIA_EEPROM_LAYOUT_OPTIONS_DEFAULT 0x00000000 -#endif - -// The end of the EEPROM memory used by VIA -// By default, dynamic keymaps will start at this if there is no -// custom config -#define VIA_EEPROM_CUSTOM_CONFIG_ADDR (VIA_EEPROM_LAYOUT_OPTIONS_ADDR + VIA_EEPROM_LAYOUT_OPTIONS_SIZE) - -#ifndef VIA_EEPROM_CUSTOM_CONFIG_SIZE -# define VIA_EEPROM_CUSTOM_CONFIG_SIZE 0 -#endif - -#define VIA_EEPROM_CONFIG_END (VIA_EEPROM_CUSTOM_CONFIG_ADDR + VIA_EEPROM_CUSTOM_CONFIG_SIZE) - -// This is changed only when the command IDs change, -// so VIA Configurator can detect compatible firmware. -#define VIA_PROTOCOL_VERSION 0x000C - -// This is a version number for the firmware for the keyboard. -// It can be used to ensure the VIA keyboard definition and the firmware -// have the same version, especially if there are changes to custom values. -// Define this in config.h to override and bump this number. -// This is *not* required if the keyboard is only using basic functionality -// and not using custom values for lighting, rotary encoders, etc. -#ifndef VIA_FIRMWARE_VERSION -# define VIA_FIRMWARE_VERSION 0x00000000 -#endif - -enum via_command_id { - id_get_protocol_version = 0x01, // always 0x01 - id_get_keyboard_value = 0x02, - id_set_keyboard_value = 0x03, - id_dynamic_keymap_get_keycode = 0x04, - id_dynamic_keymap_set_keycode = 0x05, - id_dynamic_keymap_reset = 0x06, - id_custom_set_value = 0x07, - id_custom_get_value = 0x08, - id_custom_save = 0x09, - id_eeprom_reset = 0x0A, - id_bootloader_jump = 0x0B, - id_dynamic_keymap_macro_get_count = 0x0C, - id_dynamic_keymap_macro_get_buffer_size = 0x0D, - id_dynamic_keymap_macro_get_buffer = 0x0E, - id_dynamic_keymap_macro_set_buffer = 0x0F, - id_dynamic_keymap_macro_reset = 0x10, - id_dynamic_keymap_get_layer_count = 0x11, - id_dynamic_keymap_get_buffer = 0x12, - id_dynamic_keymap_set_buffer = 0x13, - id_dynamic_keymap_get_encoder = 0x14, - id_dynamic_keymap_set_encoder = 0x15, - id_unhandled = 0xFF, -}; - -enum via_keyboard_value_id { - id_uptime = 0x01, - id_layout_options = 0x02, - id_switch_matrix_state = 0x03, - id_firmware_version = 0x04, - id_device_indication = 0x05, -}; - -enum via_channel_id { - id_custom_channel = 0, - id_qmk_backlight_channel = 1, - id_qmk_rgblight_channel = 2, - id_qmk_rgb_matrix_channel = 3, - id_qmk_audio_channel = 4, -}; - -enum via_qmk_backlight_value { - id_qmk_backlight_brightness = 1, - id_qmk_backlight_effect = 2, -}; - -enum via_qmk_rgblight_value { - id_qmk_rgblight_brightness = 1, - id_qmk_rgblight_effect = 2, - id_qmk_rgblight_effect_speed = 3, - id_qmk_rgblight_color = 4, -}; - -enum via_qmk_rgb_matrix_value { - id_qmk_rgb_matrix_brightness = 1, - id_qmk_rgb_matrix_effect = 2, - id_qmk_rgb_matrix_effect_speed = 3, - id_qmk_rgb_matrix_color = 4, -}; - -enum via_qmk_audio_value { - id_qmk_audio_enable = 1, - id_qmk_audio_clicky_enable = 2, -}; - -// Can be called in an overriding via_init_kb() to test if keyboard level code usage of -// EEPROM is invalid and use/save defaults. -bool via_eeprom_is_valid(void); - -// Sets VIA/keyboard level usage of EEPROM to valid/invalid -// Keyboard level code (eg. via_init_kb()) should not call this -void via_eeprom_set_valid(bool valid); - -// Called by QMK core to initialize dynamic keymaps etc. -void eeconfig_init_via(void); -void via_init(void); - -// Used by VIA to store and retrieve the layout options. -uint32_t via_get_layout_options(void); -void via_set_layout_options(uint32_t value); -void via_set_layout_options_kb(uint32_t value); - -// Used by VIA to tell a device to flash LEDs (or do something else) when that -// device becomes the active device being configured, on startup or switching -// between devices. -void via_set_device_indication(uint8_t value); - -// Called by QMK core to process VIA-specific keycodes. -bool process_record_via(uint16_t keycode, keyrecord_t *record); - -// These are made external so that keyboard level custom value handlers can use them. -#if defined(BACKLIGHT_ENABLE) -void via_qmk_backlight_command(uint8_t *data, uint8_t length); -void via_qmk_backlight_set_value(uint8_t *data); -void via_qmk_backlight_get_value(uint8_t *data); -void via_qmk_backlight_save(void); -#endif - -#if defined(RGBLIGHT_ENABLE) -void via_qmk_rgblight_command(uint8_t *data, uint8_t length); -void via_qmk_rgblight_set_value(uint8_t *data); -void via_qmk_rgblight_get_value(uint8_t *data); -void via_qmk_rgblight_save(void); -#endif - -#if defined(RGB_MATRIX_ENABLE) -void via_qmk_rgb_matrix_command(uint8_t *data, uint8_t length); -void via_qmk_rgb_matrix_set_value(uint8_t *data); -void via_qmk_rgb_matrix_get_value(uint8_t *data); -void via_qmk_rgb_matrix_save(void); -#endif - -#if defined(AUDIO_ENABLE) -void via_qmk_audio_command(uint8_t *data, uint8_t length); -void via_qmk_audio_set_value(uint8_t *data); -void via_qmk_audio_get_value(uint8_t *data); -void via_qmk_audio_save(void); -#endif \ No newline at end of file diff --git a/quantum/virtser.h b/quantum/virtser.h deleted file mode 100644 index df7e87984c80..000000000000 --- a/quantum/virtser.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -void virtser_init(void); - -/* Define this function in your code to process incoming bytes */ -void virtser_recv(const uint8_t ch); - -/* Call this to send a character over the Virtual Serial Device */ -void virtser_send(const uint8_t byte); diff --git a/quantum/wear_leveling/tests/backing_mocks.cpp b/quantum/wear_leveling/tests/backing_mocks.cpp deleted file mode 100644 index 1dbb26f8e7dd..000000000000 --- a/quantum/wear_leveling/tests/backing_mocks.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Backing Store Mock implementation -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -void MockBackingStore::reset_instance() { - for (auto&& e : backing_storage) - e.reset(); - - locked = true; - - backing_erasure_count = 0; - backing_max_write_count = 0; - backing_total_write_count = 0; - - backing_init_invoke_count = 0; - backing_unlock_invoke_count = 0; - backing_erase_invoke_count = 0; - backing_write_invoke_count = 0; - backing_lock_invoke_count = 0; - - init_success_callback = [](std::uint64_t) { return true; }; - erase_success_callback = [](std::uint64_t) { return true; }; - unlock_success_callback = [](std::uint64_t) { return true; }; - write_success_callback = [](std::uint64_t, std::uint32_t) { return true; }; - lock_success_callback = [](std::uint64_t) { return true; }; - - write_log.clear(); -} - -bool MockBackingStore::init(void) { - ++backing_init_invoke_count; - - if (init_success_callback) { - return init_success_callback(backing_init_invoke_count); - } - return true; -} - -bool MockBackingStore::unlock(void) { - ++backing_unlock_invoke_count; - - EXPECT_TRUE(is_locked()) << "Attempted to unlock but was not locked"; - locked = false; - - if (unlock_success_callback) { - return unlock_success_callback(backing_unlock_invoke_count); - } - return true; -} - -bool MockBackingStore::erase(void) { - ++backing_erase_invoke_count; - - // Erase each slot - for (std::size_t i = 0; i < backing_storage.size(); ++i) { - // Drop out of erase early with failure if we need to - if (erase_success_callback && !erase_success_callback(backing_erase_invoke_count)) { - append_log(true); - return false; - } - - backing_storage[i].erase(); - } - - // Keep track of the erase in the write log so that we can verify during tests - append_log(true); - - ++backing_erasure_count; - return true; -} - -bool MockBackingStore::write(uint32_t address, backing_store_int_t value) { - ++backing_write_invoke_count; - - // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE - EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size"; - EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access"; - EXPECT_FALSE(is_locked()) << "Write was attempted without being unlocked first"; - - // Drop out of write early with failure if we need to - if (write_success_callback && !write_success_callback(backing_write_invoke_count, address)) { - return false; - } - - // Write the complement as we're simulating flash memory -- 0xFF means 0x00 - std::size_t index = address / BACKING_STORE_WRITE_SIZE; - backing_storage[index].set(~value); - - // Keep track of the write log so that we can verify during tests - append_log(address, value); - - // Keep track of the total number of writes into the backing store - ++backing_total_write_count; - - return true; -} - -bool MockBackingStore::lock(void) { - ++backing_lock_invoke_count; - - EXPECT_FALSE(is_locked()) << "Attempted to lock but was not unlocked"; - locked = true; - - if (lock_success_callback) { - return lock_success_callback(backing_lock_invoke_count); - } - return true; -} - -bool MockBackingStore::read(uint32_t address, backing_store_int_t& value) const { - // precondition: value's buffer size already matches BACKING_STORE_WRITE_SIZE - EXPECT_TRUE(address % BACKING_STORE_WRITE_SIZE == 0) << "Supplied address was not aligned with the backing store integral size"; - EXPECT_TRUE(address + BACKING_STORE_WRITE_SIZE <= WEAR_LEVELING_BACKING_SIZE) << "Address would result of out-of-bounds access"; - - // Read and take the complement as we're simulating flash memory -- 0xFF means 0x00 - std::size_t index = address / BACKING_STORE_WRITE_SIZE; - value = ~backing_storage[index].get(); - - return true; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// Backing Implementation -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - -extern "C" bool backing_store_init(void) { - return MockBackingStore::Instance().init(); -} - -extern "C" bool backing_store_unlock(void) { - return MockBackingStore::Instance().unlock(); -} - -extern "C" bool backing_store_erase(void) { - return MockBackingStore::Instance().erase(); -} - -extern "C" bool backing_store_write(uint32_t address, backing_store_int_t value) { - return MockBackingStore::Instance().write(address, value); -} - -extern "C" bool backing_store_lock(void) { - return MockBackingStore::Instance().lock(); -} - -extern "C" bool backing_store_read(uint32_t address, backing_store_int_t* value) { - return MockBackingStore::Instance().read(address, *value); -} diff --git a/quantum/wear_leveling/tests/backing_mocks.hpp b/quantum/wear_leveling/tests/backing_mocks.hpp deleted file mode 100644 index e7af7895f3c8..000000000000 --- a/quantum/wear_leveling/tests/backing_mocks.hpp +++ /dev/null @@ -1,210 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once -#include -#include -#include -#include -#include -#include -#include - -extern "C" { -#include "fnv.h" -#include "wear_leveling.h" -#include "wear_leveling_internal.h" -}; - -// Maximum number of mock write log entries to keep -using MOCK_WRITE_LOG_MAX_ENTRIES = std::integral_constant; -// Complement to the backing store integral, for emulating flash erases of all bytes=0xFF -using BACKING_STORE_INTEGRAL_COMPLEMENT = std::integral_constant; -// Total number of elements stored in the backing arrays -using BACKING_STORE_ELEMENT_COUNT = std::integral_constant; - -class MockBackingStoreElement { - private: - backing_store_int_t value; - std::size_t writes; - std::size_t erases; - - public: - MockBackingStoreElement() : value(BACKING_STORE_INTEGRAL_COMPLEMENT::value), writes(0), erases(0) {} - void reset() { - erase(); - writes = 0; - erases = 0; - } - void erase() { - if (!is_erased()) { - ++erases; - } - value = BACKING_STORE_INTEGRAL_COMPLEMENT::value; - } - backing_store_int_t get() const { - return value; - } - void set(const backing_store_int_t& v) { - EXPECT_TRUE(is_erased()) << "Attempted write at index which isn't empty."; - value = v; - ++writes; - } - std::size_t num_writes() const { - return writes; - } - std::size_t num_erases() const { - return erases; - } - bool is_erased() const { - return value == BACKING_STORE_INTEGRAL_COMPLEMENT::value; - } -}; - -struct MockBackingStoreLogEntry { - MockBackingStoreLogEntry(uint32_t address, backing_store_int_t value) : address(address), value(value), erased(false) {} - MockBackingStoreLogEntry(bool erased) : address(0), value(0), erased(erased) {} - uint32_t address = 0; // The address of the operation - backing_store_int_t value = 0; // The value of the operation - bool erased = false; // Whether the entire backing store was erased -}; - -class MockBackingStore { - private: - MockBackingStore() { - reset_instance(); - } - - // Type containing each of the entries and the write counts - using storage_t = std::array; - - // Whether the backing store is locked - bool locked; - // The actual data stored in the emulated flash - storage_t backing_storage; - // The number of erase cycles that have occurred - std::uint64_t backing_erasure_count; - // The max number of writes to an element of the backing store - std::uint64_t backing_max_write_count; - // The total number of writes to all elements of the backing store - std::uint64_t backing_total_write_count; - // The write log for the backing store - std::vector write_log; - - // The number of times each API was invoked - std::uint64_t backing_init_invoke_count; - std::uint64_t backing_unlock_invoke_count; - std::uint64_t backing_erase_invoke_count; - std::uint64_t backing_write_invoke_count; - std::uint64_t backing_lock_invoke_count; - - // Whether init should succeed - std::function init_success_callback; - // Whether erase should succeed - std::function erase_success_callback; - // Whether unlocks should succeed - std::function unlock_success_callback; - // Whether writes should succeed - std::function write_success_callback; - // Whether locks should succeed - std::function lock_success_callback; - - template - void append_log(Args&&... args) { - if (write_log.size() < MOCK_WRITE_LOG_MAX_ENTRIES::value) { - write_log.emplace_back(std::forward(args)...); - } - } - - public: - static MockBackingStore& Instance() { - static MockBackingStore instance; - return instance; - } - - std::uint64_t erasure_count() const { - return backing_erasure_count; - } - std::uint64_t max_write_count() const { - return backing_max_write_count; - } - std::uint64_t total_write_count() const { - return backing_total_write_count; - } - - // The number of times each API was invoked - std::uint64_t init_invoke_count() const { - return backing_init_invoke_count; - } - std::uint64_t unlock_invoke_count() const { - return backing_unlock_invoke_count; - } - std::uint64_t erase_invoke_count() const { - return backing_erase_invoke_count; - } - std::uint64_t write_invoke_count() const { - return backing_write_invoke_count; - } - std::uint64_t lock_invoke_count() const { - return backing_lock_invoke_count; - } - - // Clear out the internal data for the next run - void reset_instance(); - - bool is_locked() const { - return locked; - } - - // APIs for the backing store - bool init(); - bool unlock(); - bool erase(); - bool write(std::uint32_t address, backing_store_int_t value); - bool lock(); - bool read(std::uint32_t address, backing_store_int_t& value) const; - - // Control over when init/writes/erases should succeed - void set_init_callback(std::function callback) { - init_success_callback = callback; - } - void set_erase_callback(std::function callback) { - erase_success_callback = callback; - } - void set_unlock_callback(std::function callback) { - unlock_success_callback = callback; - } - void set_write_callback(std::function callback) { - write_success_callback = callback; - } - void set_lock_callback(std::function callback) { - lock_success_callback = callback; - } - - auto storage_begin() const -> decltype(backing_storage.begin()) { - return backing_storage.begin(); - } - auto storage_end() const -> decltype(backing_storage.end()) { - return backing_storage.end(); - } - - auto storage_begin() -> decltype(backing_storage.begin()) { - return backing_storage.begin(); - } - auto storage_end() -> decltype(backing_storage.end()) { - return backing_storage.end(); - } - - auto log_begin() -> decltype(write_log.begin()) { - return write_log.begin(); - } - auto log_end() -> decltype(write_log.end()) { - return write_log.end(); - } - - auto log_begin() const -> decltype(write_log.begin()) { - return write_log.begin(); - } - auto log_end() const -> decltype(write_log.end()) { - return write_log.end(); - } -}; diff --git a/quantum/wear_leveling/tests/rules.mk b/quantum/wear_leveling/tests/rules.mk deleted file mode 100644 index 4d7a96404965..000000000000 --- a/quantum/wear_leveling/tests/rules.mk +++ /dev/null @@ -1,66 +0,0 @@ -wear_leveling_common_DEFS := \ - -DWEAR_LEVELING_TESTS -wear_leveling_common_SRC := \ - $(LIB_PATH)/fnv/qmk_fnv_type_validation.c \ - $(LIB_PATH)/fnv/hash_32a.c \ - $(LIB_PATH)/fnv/hash_64a.c \ - $(QUANTUM_PATH)/wear_leveling/wear_leveling.c \ - $(QUANTUM_PATH)/wear_leveling/tests/backing_mocks.cpp -wear_leveling_common_INC := \ - $(LIB_PATH)/fnv \ - $(QUANTUM_PATH)/wear_leveling - -wear_leveling_general_DEFS := \ - $(wear_leveling_common_DEFS) \ - -DBACKING_STORE_WRITE_SIZE=2 \ - -DWEAR_LEVELING_BACKING_SIZE=48 \ - -DWEAR_LEVELING_LOGICAL_SIZE=16 -wear_leveling_general_SRC := \ - $(wear_leveling_common_SRC) \ - $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_general.cpp -wear_leveling_general_INC := \ - $(wear_leveling_common_INC) - -wear_leveling_2byte_optimized_writes_DEFS := \ - $(wear_leveling_common_DEFS) \ - -DBACKING_STORE_WRITE_SIZE=2 \ - -DWEAR_LEVELING_BACKING_SIZE=65536 \ - -DWEAR_LEVELING_LOGICAL_SIZE=32768 -wear_leveling_2byte_optimized_writes_SRC := \ - $(wear_leveling_common_SRC) \ - $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp -wear_leveling_2byte_optimized_writes_INC := \ - $(wear_leveling_common_INC) - -wear_leveling_2byte_DEFS := \ - $(wear_leveling_common_DEFS) \ - -DBACKING_STORE_WRITE_SIZE=2 \ - -DWEAR_LEVELING_BACKING_SIZE=48 \ - -DWEAR_LEVELING_LOGICAL_SIZE=16 -wear_leveling_2byte_SRC := \ - $(wear_leveling_common_SRC) \ - $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_2byte.cpp -wear_leveling_2byte_INC := \ - $(wear_leveling_common_INC) - -wear_leveling_4byte_DEFS := \ - $(wear_leveling_common_DEFS) \ - -DBACKING_STORE_WRITE_SIZE=4 \ - -DWEAR_LEVELING_BACKING_SIZE=48 \ - -DWEAR_LEVELING_LOGICAL_SIZE=16 -wear_leveling_4byte_SRC := \ - $(wear_leveling_common_SRC) \ - $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_4byte.cpp -wear_leveling_4byte_INC := \ - $(wear_leveling_common_INC) - -wear_leveling_8byte_DEFS := \ - $(wear_leveling_common_DEFS) \ - -DBACKING_STORE_WRITE_SIZE=8 \ - -DWEAR_LEVELING_BACKING_SIZE=48 \ - -DWEAR_LEVELING_LOGICAL_SIZE=16 -wear_leveling_8byte_SRC := \ - $(wear_leveling_common_SRC) \ - $(QUANTUM_PATH)/wear_leveling/tests/wear_leveling_8byte.cpp -wear_leveling_8byte_INC := \ - $(wear_leveling_common_INC) \ No newline at end of file diff --git a/quantum/wear_leveling/tests/testlist.mk b/quantum/wear_leveling/tests/testlist.mk deleted file mode 100644 index 32cfc178b4ee..000000000000 --- a/quantum/wear_leveling/tests/testlist.mk +++ /dev/null @@ -1,6 +0,0 @@ -TEST_LIST += \ - wear_leveling_general \ - wear_leveling_2byte_optimized_writes \ - wear_leveling_2byte \ - wear_leveling_4byte \ - wear_leveling_8byte diff --git a/quantum/wear_leveling/tests/wear_leveling_2byte.cpp b/quantum/wear_leveling/tests/wear_leveling_2byte.cpp deleted file mode 100644 index b749c32b04d4..000000000000 --- a/quantum/wear_leveling/tests/wear_leveling_2byte.cpp +++ /dev/null @@ -1,228 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -class WearLeveling2Byte : public ::testing::Test { - protected: - void SetUp() override { - MockBackingStore::Instance().reset_instance(); - wear_leveling_init(); - } -}; - -static std::array verify_data; - -static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { - memcpy(&verify_data[address], value, length); - return wear_leveling_write(address, value, length); -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. - */ -TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. - */ -TEST_F(WearLeveling2Byte, FirstWriteOccursAfterHash_AfterErase) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - wear_leveling_erase(); - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the - * base logical area. - */ -TEST_F(WearLeveling2Byte, ConsolidationOverflow) { - auto& inst = MockBackingStore::Instance(); - - // Generate a test block of data which forces OPTIMIZED_64 writes - std::array testvalue; - - // Write the data - std::iota(testvalue.begin(), testvalue.end(), 0x20); - EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; - uint8_t dummy = 0x40; - EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; - - // All writes are at address<64, so each logical byte written will generate 1 write log entry, thus 1 backing store write. - // Expected log: - // [0..11]: optimised64, backing address 0x18, logical address 0x00 - // [12]: erase - // [13..20]: consolidated data, backing address 0x00, logical address 0x00 - // [21..24]: FNV1a_64 result, backing address 0x10 - // [25]: optimised64, backing address 0x18, logical address 0x04 - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 26); - - // Verify the backing store writes for the write log - std::size_t index; - write_log_entry_t e; - for (index = 0; index < 12; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; - } - - // Verify the backing store erase - { - index = 12; - auto write_iter = inst.log_begin() + index; - e.raw16[0] = write_iter->value; - EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; - } - - // Verify the backing store writes for consolidation - for (index = 13; index < 21; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, (index - 13) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; - } - - // Verify the FNV1a_64 write - { - EXPECT_EQ((inst.log_begin() + 21)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; - e.raw16[0] = (inst.log_begin() + 21)->value; - e.raw16[1] = (inst.log_begin() + 22)->value; - e.raw16[2] = (inst.log_begin() + 23)->value; - e.raw16[3] = (inst.log_begin() + 24)->value; - EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current - } - - // Verify the final write - EXPECT_EQ((inst.log_begin() + 25)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; - - // Verify the data is what we expected - std::array readback; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; - - // Re-init and re-read, verifying the reload capability - EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; -} - -/** - * This test verifies multibyte readback gets canceled with an out-of-bounds address. - */ -TEST_F(WearLeveling2Byte, PlaybackReadbackMultibyte_OOB) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - (logstart + 2)->set(0); - (logstart + 3)->set(0); - - // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry0.raw8[3] = 0x11; - entry0.raw8[4] = 0x12; - (logstart + 4)->set(~entry0.raw16[0]); - (logstart + 5)->set(~entry0.raw16[1]); - (logstart + 6)->set(~entry0.raw16[2]); - - // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) - auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); - entry1.raw8[3] = 0x13; - entry1.raw8[4] = 0x14; - (logstart + 7)->set(~entry1.raw16[0]); - (logstart + 8)->set(~entry1.raw16[1]); - (logstart + 9)->set(~entry1.raw16[2]); - - // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x01 - auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry2.raw8[3] = 0x15; - entry2.raw8[4] = 0x16; - (logstart + 10)->set(~entry2.raw16[0]); - (logstart + 11)->set(~entry2.raw16[1]); - (logstart + 12)->set(~entry2.raw16[2]); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; - EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; - - uint8_t buf[2]; - wear_leveling_read(0x01, buf, sizeof(buf)); - EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; - EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; -} - -/** - * This test verifies optimized 64 readback gets canceled with an out-of-bounds address. - */ -TEST_F(WearLeveling2Byte, PlaybackReadbackOptimized64_OOB) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - (logstart + 2)->set(0); - (logstart + 3)->set(0); - - // Set up a 1-byte logical write of 0x11 at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); - (logstart + 4)->set(~entry0.raw16[0]); - - // Set up a 1-byte logical write of 0x11 at logical offset 0x30 (out of bounds) - auto entry1 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x30, 0x11); - (logstart + 5)->set(~entry1.raw16[0]); - - // Set up a 1-byte logical write of 0x12 at logical offset 0x01 - auto entry2 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x12); - (logstart + 6)->set(~entry2.raw16[0]); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; - EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; - uint8_t tmp; - wear_leveling_read(0x01, &tmp, sizeof(tmp)); - EXPECT_EQ(tmp, 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; -} - -/** - * This test verifies word 0/1 readback gets canceled with an out-of-bounds address. - */ -TEST_F(WearLeveling2Byte, PlaybackReadbackWord01_OOB) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - (logstart + 2)->set(0); - (logstart + 3)->set(0); - - // Set up a 1-byte logical write of 1 at logical offset 0x02 - auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1); - (logstart + 4)->set(~entry0.raw16[0]); - - // Set up a 1-byte logical write of 1 at logical offset 0x1000 (out of bounds) - auto entry1 = LOG_ENTRY_MAKE_WORD_01(0x1000, 1); - (logstart + 5)->set(~entry1.raw16[0]); - - // Set up a 1-byte logical write of 0 at logical offset 0x02 - auto entry2 = LOG_ENTRY_MAKE_WORD_01(0x02, 0); - (logstart + 6)->set(~entry2.raw16[0]); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; - EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; - uint8_t tmp; - wear_leveling_read(0x02, &tmp, sizeof(tmp)); - EXPECT_EQ(tmp, 1) << "Readback should have maintained the previous pre-failure value from the write log"; -} diff --git a/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp b/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp deleted file mode 100644 index 0b03113c89ff..000000000000 --- a/quantum/wear_leveling/tests/wear_leveling_2byte_optimized_writes.cpp +++ /dev/null @@ -1,295 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -class WearLeveling2ByteOptimizedWrites : public ::testing::Test { - protected: - void SetUp() override { - MockBackingStore::Instance().reset_instance(); - wear_leveling_init(); - } -}; - -static std::array verify_data; - -static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { - memcpy(&verify_data[address], value, length); - return wear_leveling_write(address, value, length); -} - -/** - * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. - */ -TEST_F(WearLeveling2ByteOptimizedWrites, MultibyteBackingStoreWriteCounts) { - auto& inst = MockBackingStore::Instance(); - - for (std::size_t length = 1; length <= 5; ++length) { - // Clear things out - std::fill(verify_data.begin(), verify_data.end(), 0); - inst.reset_instance(); - wear_leveling_init(); - - // Generate a test block of data - std::vector testvalue(length); - std::iota(testvalue.begin(), testvalue.end(), 0x20); - - // Write the data - EXPECT_EQ(test_write(2000, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - - std::size_t expected; - if (length > 3) { - expected = 4; - } else if (length > 1) { - expected = 3; - } else { - expected = 2; - } - - // Check that we got the expected number of write log entries - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected); - } -} - -/** - * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to even addresses only. - * - Addresses <16384 will result in a single optimised backing write - * - Higher addresses will result in a multibyte write of 3 backing writes - */ -TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToEvenAddresses) { - auto& inst = MockBackingStore::Instance(); - - // Only attempt writes for each address up to a limit that would NOT force a consolidated data write. - std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1 - std::size_t final_address; - for (uint32_t address = 0; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) { - // Clear things out - std::fill(verify_data.begin(), verify_data.end(), 0); - inst.reset_instance(); - wear_leveling_init(); - - // Loop through all the addresses in this range - std::size_t expected = 0; - for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) { - // If we're about to exceed the limit of the logical store, skip the writes - if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) { - break; - } - - // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs. - uint16_t val = 1; - EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - val = 0; - EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - - std::size_t backing_store_writes_expected = 0; - if (address + offset < 16384) { - // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes - backing_store_writes_expected = 2; - } else { - // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data - backing_store_writes_expected = 6; - } - - // Keep track of the total number of expected writes to the backing store - expected += backing_store_writes_expected; - - // Verify we're at the correct number of writes - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset); - - // Verify that the write log entries we expect are actually present - std::size_t write_index = expected - backing_store_writes_expected; - auto write_iter = inst.log_begin() + write_index; - write_log_entry_t e; - if (address + offset < 16384) { - // A U16 value of 0/1 at an even address <16384 will result in 1 backing write each, so we need 2 backing writes for 2 logical writes - for (std::size_t i = 0; i < 2; ++i) { - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_WORD_01) << "Invalid write log entry type at " << (address + offset); - ++write_iter; - } - } else { - // Multibyte write - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type at " << (address + offset); - EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length at " << (address + offset); - ++write_iter; - } - - // Keep track of the final address written, so we can verify the entire logical range was handled - final_address = address + offset; - } - - // Verify the number of writes that occurred to the backing store - size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end()); - EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address; - - // Verify the data is what we expected - std::array readback; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; - - // Re-init and re-read, testing the reload capability - EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; - } - - // Verify the full range of the logical area got written - EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 2) << "Invalid final write address"; -} - -/** - * This test runs through writing U16 values of `0` or `1` over the entire logical address range, to odd addresses only. - * - Addresses <63 will result in 2 optimised backing writes - * - Address 63 results in a single optimised backing write for the first logical byte, and a multibyte write of 2 backing writes for the second logical byte - * - Higher addresses will result in a multibyte write of 3 backing writes - */ -TEST_F(WearLeveling2ByteOptimizedWrites, WriteOneThenZeroToOddAddresses) { - auto& inst = MockBackingStore::Instance(); - - // Only attempt writes for each address up to a limit that would NOT force a consolidated data write. - std::size_t writes_per_loop = (MOCK_WRITE_LOG_MAX_ENTRIES::value / 6) - 1; // Worst case is 6 writes for each pair of writes of 0/1 - std::size_t final_address; - for (uint32_t address = 1; address < WEAR_LEVELING_LOGICAL_SIZE; address += (writes_per_loop * 2)) { - // Clear things out - std::fill(verify_data.begin(), verify_data.end(), 0); - inst.reset_instance(); - wear_leveling_init(); - - // Loop through all the addresses in this range - std::size_t expected = 0; - for (uint32_t offset = 0; offset < (writes_per_loop * 2); offset += 2) { - // If we're about to exceed the limit of the logical store, skip the writes - if (address + offset + 2 > WEAR_LEVELING_LOGICAL_SIZE) { - break; - } - - // The default erased value of the wear-leveling cache is zero, so we write a one first, then a zero, to ensure a backing store write occurs. - uint16_t val = 1; - EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - val = 0; - EXPECT_EQ(test_write(address + offset, &val, sizeof(val)), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - - std::size_t backing_store_writes_expected = 0; - if (address + offset < 63) { - // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes - backing_store_writes_expected = 4; - } else if (address + offset == 63) { - // If we're straddling the boundary for optimised bytes (addr==64), then the first logical byte is written using the optimised write (1 backing - // store write), and the second logical byte uses a multibyte write (2 backing store writes) - backing_store_writes_expected = 2 // First logical bytes written using optimised log entries - + 4; // Second logical bytes written using multibyte log entries - } else { - // All other addresses result in a multibyte write (3 backing store writes) to write two local bytes of data - backing_store_writes_expected = 6; - } - - // Keep track of the total number of expected writes to the backing store - expected += backing_store_writes_expected; - - // Verify we're at the correct number of writes - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected) << "Write log doesn't match required number of backing store writes for address " << (address + offset); - - // Verify that the write log entries we expect are actually present - std::size_t write_index = expected - backing_store_writes_expected; - auto write_iter = inst.log_begin() + write_index; - write_log_entry_t e; - if (address + offset < 63) { - // A U16 value of 0/1 at an odd address <64 will result in 2 backing writes each, so we need 4 backing writes for 2 logical writes - for (std::size_t i = 0; i < 4; ++i) { - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; - ++write_iter; - } - } else if (address + offset == 63) { - // First log entry is the 64-addr optimised one - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_OPTIMIZED_64) << "Invalid write log entry type"; - ++write_iter; - - // Second log entry is the multibyte entry for the second logical byte - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; - EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 1) << "Invalid write log entry length"; - ++write_iter; - } else { - // Multibyte write - e.raw16[0] = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; - EXPECT_EQ(LOG_ENTRY_MULTIBYTE_GET_LENGTH(e), 2) << "Invalid write log entry length"; - ++write_iter; - } - - // Keep track of the final address written, so we can verify the entire logical range was handled - final_address = address + offset; - } - - // Verify the number of writes that occurred to the backing store - size_t backing_write_count = std::distance(inst.log_begin(), inst.log_end()); - EXPECT_EQ(backing_write_count, expected) << "Invalid write count at address " << address; - - // Verify the data is what we expected - std::array readback; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; - - // Re-init and re-read, testing the reload capability - EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback for address " << address << " did not match"; - } - - // Verify the full range of the logical area got written - EXPECT_EQ(final_address, WEAR_LEVELING_LOGICAL_SIZE - 3) << "Invalid final write address"; -} - -/** - * This test verifies readback after playback of the write log, simulating power loss and reboot. - */ -TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackOptimized64_Success) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - (logstart + 2)->set(0); - (logstart + 3)->set(0); - - // Set up a 1-byte logical write of 0x11 at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); - (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result - - wear_leveling_init(); - uint8_t tmp; - - wear_leveling_read(0x01, &tmp, sizeof(tmp)); - EXPECT_EQ(tmp, 0x11) << "Failed to read back the seeded data"; -} - -/** - * This test verifies readback after playback of the write log, simulating power loss and reboot. - */ -TEST_F(WearLeveling2ByteOptimizedWrites, PlaybackReadbackWord01_Success) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - (logstart + 2)->set(0); - (logstart + 3)->set(0); - - // Set up a 1-byte logical write of 1 at logical offset 0x02 - auto entry0 = LOG_ENTRY_MAKE_WORD_01(0x02, 1); - (logstart + 4)->set(~entry0.raw16[0]); // start at offset 4 to skip FNV1a_64 result - - wear_leveling_init(); - uint8_t tmp; - - wear_leveling_read(0x02, &tmp, sizeof(tmp)); - EXPECT_EQ(tmp, 1) << "Failed to read back the seeded data"; -} diff --git a/quantum/wear_leveling/tests/wear_leveling_4byte.cpp b/quantum/wear_leveling/tests/wear_leveling_4byte.cpp deleted file mode 100644 index 54482c5fe7c3..000000000000 --- a/quantum/wear_leveling/tests/wear_leveling_4byte.cpp +++ /dev/null @@ -1,193 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -class WearLeveling4Byte : public ::testing::Test { - protected: - void SetUp() override { - MockBackingStore::Instance().reset_instance(); - wear_leveling_init(); - } -}; - -static std::array verify_data; - -static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { - memcpy(&verify_data[address], value, length); - return wear_leveling_write(address, value, length); -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. - */ -TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. - */ -TEST_F(WearLeveling4Byte, FirstWriteOccursAfterHash_AfterErase) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - wear_leveling_erase(); - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. - */ -TEST_F(WearLeveling4Byte, MultibyteBackingStoreWriteCounts) { - auto& inst = MockBackingStore::Instance(); - - for (std::size_t length = 1; length <= 5; ++length) { - // Clear things out - std::fill(verify_data.begin(), verify_data.end(), 0); - inst.reset_instance(); - wear_leveling_init(); - - // Generate a test block of data - std::vector testvalue(length); - std::iota(testvalue.begin(), testvalue.end(), 0x20); - - // Write the data - EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - - std::size_t expected; - if (length > 1) { - expected = 2; - } else { - expected = 1; - } - - // Check that we got the expected number of write log entries - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), expected); - } -} - -/** - * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the - * base logical area. - */ -TEST_F(WearLeveling4Byte, ConsolidationOverflow) { - auto& inst = MockBackingStore::Instance(); - - // Generate a test block of data - std::array testvalue; - - // Write the data - std::iota(testvalue.begin(), testvalue.end(), 0x20); - EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; - uint8_t dummy = 0x40; - EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; - - // Expected log: - // [0,1]: multibyte, 5 bytes, backing address 0x18, logical address 0x00 - // [2,3]: multibyte, 5 bytes, backing address 0x20, logical address 0x05 - // [4,5]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation - // [6]: erase - // [7,8]: consolidated data, backing address 0x00, logical address 0x00 - // [9,10]: consolidated data, backing address 0x08, logical address 0x08 - // [11,12]: FNV1a_64 result, backing address 0x10 - // [13]: multibyte, 1 byte, backing address 0x18, logical address 0x04 - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 14); - - // Verify the backing store writes for the write log - std::size_t index; - write_log_entry_t e; - for (index = 0; index < 6; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; - - // If this is the backing store write that contains the metadata, verify it - if (index % 2 == 0) { - write_log_entry_t e; - e.raw64 = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; - } - } - - // Verify the backing store erase - { - index = 6; - auto write_iter = inst.log_begin() + index; - e.raw64 = write_iter->value; - EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; - } - - // Verify the backing store writes for consolidation - for (index = 7; index < 11; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, (index - 7) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; - } - - // Verify the FNV1a_64 write - { - EXPECT_EQ((inst.log_begin() + 11)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; - e.raw32[0] = (inst.log_begin() + 11)->value; - e.raw32[1] = (inst.log_begin() + 12)->value; - EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current - } - - // Verify the final write - EXPECT_EQ((inst.log_begin() + 13)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; - - // Verify the data is what we expected - std::array readback; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; - - // Re-init and re-read, verifying the reload capability - EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; -} - -/** - * This test verifies multibyte readback gets canceled with an out-of-bounds address. - */ -TEST_F(WearLeveling4Byte, PlaybackReadbackMultibyte_OOB) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - (logstart + 1)->set(0); - - // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry0.raw8[3] = 0x11; - entry0.raw8[4] = 0x12; - (logstart + 2)->set(~entry0.raw32[0]); - (logstart + 3)->set(~entry0.raw32[1]); - - // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) - auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); - entry1.raw8[3] = 0x13; - entry1.raw8[4] = 0x14; - (logstart + 4)->set(~entry1.raw32[0]); - (logstart + 5)->set(~entry1.raw32[1]); - - // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10 - auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry2.raw8[3] = 0x15; - entry2.raw8[4] = 0x16; - (logstart + 6)->set(~entry2.raw32[0]); - (logstart + 7)->set(~entry2.raw32[1]); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; - EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; - - uint8_t buf[2]; - wear_leveling_read(0x01, buf, sizeof(buf)); - EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; - EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; -} diff --git a/quantum/wear_leveling/tests/wear_leveling_8byte.cpp b/quantum/wear_leveling/tests/wear_leveling_8byte.cpp deleted file mode 100644 index c27c21d034aa..000000000000 --- a/quantum/wear_leveling/tests/wear_leveling_8byte.cpp +++ /dev/null @@ -1,178 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -class WearLeveling8Byte : public ::testing::Test { - protected: - void SetUp() override { - MockBackingStore::Instance().reset_instance(); - wear_leveling_init(); - } -}; - -static std::array verify_data; - -static wear_leveling_status_t test_write(const uint32_t address, const void* value, size_t length) { - memcpy(&verify_data[address], value, length); - return wear_leveling_write(address, value, length); -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location. - */ -TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ(inst.log_begin()->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test verifies that the first write after initialisation occurs after the FNV1a_64 hash location, after an erase has occurred. - */ -TEST_F(WearLeveling8Byte, FirstWriteOccursAfterHash_AfterErase) { - auto& inst = MockBackingStore::Instance(); - uint8_t test_value = 0x15; - wear_leveling_erase(); - test_write(0x02, &test_value, sizeof(test_value)); - EXPECT_EQ((inst.log_begin() + 1)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid first write address."; -} - -/** - * This test ensures the correct number of backing store writes occurs with a multibyte write, given the input buffer size. - */ -TEST_F(WearLeveling8Byte, MultibyteBackingStoreWriteCounts) { - auto& inst = MockBackingStore::Instance(); - - for (std::size_t length = 1; length <= 5; ++length) { - // Clear things out - std::fill(verify_data.begin(), verify_data.end(), 0); - inst.reset_instance(); - wear_leveling_init(); - - // Generate a test block of data - std::vector testvalue(length); - std::iota(testvalue.begin(), testvalue.end(), 0x20); - - // Write the data - EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Write failed with incorrect status"; - - // Check that we got the expected number of write log entries - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 1); - } -} - -/** - * This test forces consolidation by writing enough to the write log that it overflows, consolidating the data into the - * base logical area. - */ -TEST_F(WearLeveling8Byte, ConsolidationOverflow) { - auto& inst = MockBackingStore::Instance(); - - // Generate a test block of data - std::array testvalue; - - // Write the data - std::iota(testvalue.begin(), testvalue.end(), 0x20); - EXPECT_EQ(test_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; - uint8_t dummy = 0x40; - EXPECT_EQ(test_write(0x04, &dummy, sizeof(dummy)), WEAR_LEVELING_SUCCESS) << "Write returned incorrect status"; - - // Expected log: - // [0]: multibyte, 5 bytes, backing address 0x18, logical address 0x00 - // [1]: multibyte, 5 bytes, backing address 0x20, logical address 0x05 - // [2]: multibyte, 5 bytes, backing address 0x28, logical address 0x0A, triggers consolidation - // [3]: erase - // [4]: consolidated data, backing address 0x00, logical address 0x00 - // [5]: consolidated data, backing address 0x08, logical address 0x08 - // [6]: FNV1a_64 result, backing address 0x10 - // [7]: multibyte, 1 byte, backing address 0x18, logical address 0x04 - EXPECT_EQ(std::distance(inst.log_begin(), inst.log_end()), 8); - - // Verify the backing store writes for the write log - std::size_t index; - write_log_entry_t e; - for (index = 0; index < 3; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, WEAR_LEVELING_LOGICAL_SIZE + 8 + (index * BACKING_STORE_WRITE_SIZE)) << "Invalid write log address"; - - write_log_entry_t e; - e.raw64 = write_iter->value; - EXPECT_EQ(LOG_ENTRY_GET_TYPE(e), LOG_ENTRY_TYPE_MULTIBYTE) << "Invalid write log entry type"; - } - - // Verify the backing store erase - { - index = 3; - auto write_iter = inst.log_begin() + index; - e.raw64 = write_iter->value; - EXPECT_TRUE(write_iter->erased) << "Backing store erase did not occur as required"; - } - - // Verify the backing store writes for consolidation - for (index = 4; index < 6; ++index) { - auto write_iter = inst.log_begin() + index; - EXPECT_EQ(write_iter->address, (index - 4) * BACKING_STORE_WRITE_SIZE) << "Invalid write log entry address"; - } - - // Verify the FNV1a_64 write - { - EXPECT_EQ((inst.log_begin() + 6)->address, WEAR_LEVELING_LOGICAL_SIZE) << "Invalid write log address"; - e.raw64 = (inst.log_begin() + 6)->value; - EXPECT_EQ(e.raw64, fnv_64a_buf(testvalue.data(), testvalue.size(), FNV1A_64_INIT)) << "Invalid checksum"; // Note that checksum is based on testvalue, as we overwrote one byte and need to consult the consolidated data, not the current - } - - // Verify the final write - EXPECT_EQ((inst.log_begin() + 7)->address, WEAR_LEVELING_LOGICAL_SIZE + 8) << "Invalid write log address"; - - // Verify the data is what we expected - std::array readback; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; - - // Re-init and re-read, verifying the reload capability - EXPECT_NE(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Re-initialisation failed"; - EXPECT_EQ(wear_leveling_read(0, readback.data(), WEAR_LEVELING_LOGICAL_SIZE), WEAR_LEVELING_SUCCESS) << "Failed to read back the saved data"; - EXPECT_TRUE(memcmp(readback.data(), verify_data.data(), WEAR_LEVELING_LOGICAL_SIZE) == 0) << "Readback did not match"; -} - -/** - * This test verifies multibyte readback gets canceled with an out-of-bounds address. - */ -TEST_F(WearLeveling8Byte, PlaybackReadbackMultibyte_OOB) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Invalid FNV1a_64 hash - (logstart + 0)->set(0); - - // Set up a 2-byte logical write of [0x11,0x12] at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry0.raw8[3] = 0x11; - entry0.raw8[4] = 0x12; - (logstart + 1)->set(~entry0.raw64); - - // Set up a 2-byte logical write of [0x13,0x14] at logical offset 0x1000 (out of bounds) - auto entry1 = LOG_ENTRY_MAKE_MULTIBYTE(0x1000, 2); - entry1.raw8[3] = 0x13; - entry1.raw8[4] = 0x14; - (logstart + 2)->set(~entry1.raw64); - - // Set up a 2-byte logical write of [0x15,0x16] at logical offset 0x10 - auto entry2 = LOG_ENTRY_MAKE_MULTIBYTE(0x01, 2); - entry2.raw8[3] = 0x15; - entry2.raw8[4] = 0x16; - (logstart + 3)->set(~entry2.raw64); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_CONSOLIDATED) << "Readback should have failed and triggered consolidation"; - EXPECT_EQ(inst.erasure_count(), 1) << "Invalid final erase count"; - - uint8_t buf[2]; - wear_leveling_read(0x01, buf, sizeof(buf)); - EXPECT_EQ(buf[0], 0x11) << "Readback should have maintained the previous pre-failure value from the write log"; - EXPECT_EQ(buf[1], 0x12) << "Readback should have maintained the previous pre-failure value from the write log"; -} diff --git a/quantum/wear_leveling/tests/wear_leveling_general.cpp b/quantum/wear_leveling/tests/wear_leveling_general.cpp deleted file mode 100644 index 76a4bf7bf329..000000000000 --- a/quantum/wear_leveling/tests/wear_leveling_general.cpp +++ /dev/null @@ -1,204 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "gtest/gtest.h" -#include "gmock/gmock.h" -#include "backing_mocks.hpp" - -class WearLevelingGeneral : public ::testing::Test { - protected: - void SetUp() override { - MockBackingStore::Instance().reset_instance(); - wear_leveling_init(); - } -}; - -/** - * This test verifies that even if there is consolidated data present, if the checksum doesn't match then the cache is zero'd after reading the consolidated area, but before write log is played back. - */ -TEST_F(WearLevelingGeneral, InvalidChecksum_ConsolidatedDataIgnored) { - auto& inst = MockBackingStore::Instance(); - auto logstart = inst.storage_begin() + (WEAR_LEVELING_LOGICAL_SIZE / sizeof(backing_store_int_t)); - - // Generate a test block of data - std::array testvalue; - std::iota(testvalue.begin(), testvalue.end(), 0x20); - - // Write the data - EXPECT_EQ(wear_leveling_write(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_CONSOLIDATED) << "Write returned incorrect status"; - - // Invalidate the checksum - (logstart + 0)->erase(); - (logstart + 1)->erase(); - (logstart + 2)->erase(); - (logstart + 3)->erase(); - - // Set up a 1-byte logical write of [0x11] at logical offset 0x01 - auto entry0 = LOG_ENTRY_MAKE_OPTIMIZED_64(0x01, 0x11); - (logstart + 4)->set(~entry0.raw16[0]); - - // Re-init - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_SUCCESS) << "Init returned incorrect status"; - EXPECT_EQ(wear_leveling_read(0, testvalue.data(), testvalue.size()), WEAR_LEVELING_SUCCESS) << "Failed to read"; - for (int i = 0; i < WEAR_LEVELING_LOGICAL_SIZE; ++i) { - EXPECT_EQ(testvalue[i], i == 0x01 ? 0x11 : 0x00) << "Invalid readback"; - } -} - -/** - * This test verifies that writing the same data multiple times does not result in subsequent writes to the backing store. - */ -TEST_F(WearLevelingGeneral, SameValue_SingleBackingWrite) { - auto& inst = MockBackingStore::Instance(); - - uint8_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "First overall write operation should have succeeded"; - - uint64_t invoke_count = inst.unlock_invoke_count(); - uint64_t erase_count = inst.erase_invoke_count(); - uint64_t write_count = inst.write_invoke_count(); - uint64_t lock_count = inst.lock_invoke_count(); - - for (int i = 0; i < 10; ++i) { - EXPECT_EQ(wear_leveling_write(0x02, &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Subsequent overall write operation should have succeeded"; - - EXPECT_EQ(inst.unlock_invoke_count(), invoke_count) << "Unlock count should match"; - EXPECT_EQ(inst.erase_invoke_count(), erase_count) << "Erase count should match"; - EXPECT_EQ(inst.write_invoke_count(), write_count) << "Write count should match"; - EXPECT_EQ(inst.lock_invoke_count(), lock_count) << "Lock count should match"; - } -} - -/** - * This test verifies that no other invocations occur if `backing_store_init()` fails. - */ -TEST_F(WearLevelingGeneral, InitFailure) { - auto& inst = MockBackingStore::Instance(); - inst.reset_instance(); // make sure the counters are all zero - inst.set_init_callback([](std::uint64_t count) { return false; }); - - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid initial erase count"; - EXPECT_EQ(wear_leveling_init(), WEAR_LEVELING_FAILED) << "Init should have failed"; - EXPECT_EQ(inst.erasure_count(), 0) << "Invalid final erase count"; - - EXPECT_EQ(inst.init_invoke_count(), 1) << "Init should have been invoked once"; - EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; -} - -/** - * This test verifies that no invocations occur if the supplied address is out of range while writing. - */ -TEST_F(WearLevelingGeneral, WriteFailure_OOB) { - auto& inst = MockBackingStore::Instance(); - - uint8_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; -} - -/** - * This test verifies that a single write occurs if the supplied address and data length hits the edge of the logical area. - */ -TEST_F(WearLevelingGeneral, WriteSuccess_BoundaryOK) { - auto& inst = MockBackingStore::Instance(); - - uint16_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val), &test_val, sizeof(test_val)), WEAR_LEVELING_SUCCESS) << "Overall write operation should have succeeded"; - - EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 2) << "Write should have been invoked twice"; - EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once"; -} - -/** - * This test verifies that no invocations occur if the supplied address and length would generate writes outside the logical range. - */ -TEST_F(WearLevelingGeneral, WriteFailure_BoundaryOverflow) { - auto& inst = MockBackingStore::Instance(); - - uint16_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(WEAR_LEVELING_LOGICAL_SIZE - sizeof(test_val) + 1, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; -} - -/** - * This test verifies that no invocations occur if the supplied address is out of range while reading. - */ -TEST_F(WearLevelingGeneral, ReadFailure_OOB) { - auto& inst = MockBackingStore::Instance(); - - uint8_t test_val = 0; - EXPECT_EQ(wear_leveling_read(0x21349830, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall read operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 0) << "Unlock should not have been invoked"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; -} - -/** - * This test verifies that no write invocations occur if `backing_store_unlock()` fails. - */ -TEST_F(WearLevelingGeneral, UnlockFailure_NoWrite) { - auto& inst = MockBackingStore::Instance(); - inst.set_unlock_callback([](std::uint64_t count) { return false; }); - - uint8_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; - - test_val = 0; - wear_leveling_read(0x04, &test_val, sizeof(test_val)); - EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure"; -} - -/** - * This test verifies that no erase invocations occur if `backing_store_unlock()` fails. - */ -TEST_F(WearLevelingGeneral, UnlockFailure_NoErase) { - auto& inst = MockBackingStore::Instance(); - inst.set_unlock_callback([](std::uint64_t count) { return false; }); - - EXPECT_EQ(wear_leveling_erase(), WEAR_LEVELING_FAILED) << "Overall erase operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 0) << "Write should not have been invoked"; - EXPECT_EQ(inst.lock_invoke_count(), 0) << "Lock should not have been invoked"; -} - -/** - * This test verifies that only one write invocation occurs if `backing_store_write()` fails. - */ -TEST_F(WearLevelingGeneral, WriteFailure_NoSubsequentWrites) { - auto& inst = MockBackingStore::Instance(); - inst.set_write_callback([](std::uint64_t count, std::uint32_t address) { return false; }); - - uint8_t test_val = 0x14; - EXPECT_EQ(wear_leveling_write(0x04, &test_val, sizeof(test_val)), WEAR_LEVELING_FAILED) << "Overall write operation should have failed"; - - EXPECT_EQ(inst.unlock_invoke_count(), 1) << "Unlock should have been invoked once"; - EXPECT_EQ(inst.erase_invoke_count(), 0) << "Erase should not have been invoked"; - EXPECT_EQ(inst.write_invoke_count(), 1) << "Write should have been invoked once"; - EXPECT_EQ(inst.lock_invoke_count(), 1) << "Lock should have been invoked once"; - - test_val = 0; - wear_leveling_read(0x04, &test_val, sizeof(test_val)); - EXPECT_EQ(test_val, 0x14) << "Readback should come from cache regardless of unlock failure"; -} diff --git a/quantum/wear_leveling/wear_leveling.c b/quantum/wear_leveling/wear_leveling.c deleted file mode 100644 index 429df45df5ea..000000000000 --- a/quantum/wear_leveling/wear_leveling.c +++ /dev/null @@ -1,768 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#include -#include "fnv.h" -#include "wear_leveling.h" -#include "wear_leveling_internal.h" - -/* - This wear leveling algorithm is adapted from algorithms from previous - implementations in QMK, namely: - - Artur F. (http://engsta.com/stm32-flash-memory-eeprom-emulator/) - - Yiancar -- QMK's base implementation for STM32F303 - - Ilya Zhuravlev -- initial wear leveling algorithm - - Don Kjer -- increased flash density algorithm - - Nick Brassel (@tzarc) -- decoupled for use on other peripherals - - At this layer, it is assumed that any reads/writes from the backing store - have a "reset state" after erasure of zero. - It is up to the backing store to perform translation of values, such as - taking the complement in order to deal with flash memory's reset value. - - Terminology: - - - Backing store: this is the storage area used by the wear leveling - algorithm. - - - Backing size: this is the amount of storage provided by the backing - store for use by the wear leveling algorithm. - - - Backing write size: this is the minimum number of bytes the backing - store can write in a single operation. - - - Logical data: this is the externally-visible "emulated EEPROM" that - external subsystems "see" when performing reads/writes. - - - Logical size: this is the amount of storage available for use - externally. Effectively, the "size of the EEPROM". - - - Write log: this is a section of the backing store used to keep track - of modifications without overwriting existing data. This log is - "played back" on startup such that any subsequent reads are capable - of returning the latest data. - - - Consolidated data: this is a section of the backing store reserved for - use for the latest copy of logical data. This is only ever written - when the write log is full -- the latest values for the logical data - are written here and the write log is cleared. - - Configurables: - - - BACKING_STORE_WRITE_SIZE: The number of bytes requires for a write - operation. This is defined by the capabilities of the backing store. - - - WEAR_LEVELING_BACKING_SIZE: The number of bytes provided by the - backing store for use by the wear leveling algorithm. This is - defined by the capabilities of the backing store. This value must - also be at least twice the size of the logical size, as well as a - multiple of the logical size. - - - WEAR_LEVELING_LOGICAL_SIZE: The number of bytes externally visible - to other subsystems performing reads/writes. This must be a multiple - of the write size. - - General algorithm: - - During initialization: - * The contents of the consolidated data section are read into cache. - * The contents of the write log are "played back" and update the - cache accordingly. - - During reads: - * Logical data is served from the cache. - - During writes: - * The cache is updated with the new data. - * A new write log entry is appended to the log. - * If the log's full, data is consolidated and the write log cleared. - - Write log structure: - - The first 8 bytes of the write log are a FNV1a_64 hash of the contents - of the consolidated data area, in an attempt to detect and guard against - any data corruption. - - The write log follows the hash: - - Given that the algorithm needs to cater for 2-, 4-, and 8-byte writes, - a variable-length write log entry is used such that the minimal amount - of storage is used based off the backing store write size. - - Firstly, an empty log entry is expected to be all zeros. If the backing - store uses 0xFF for cleared bytes, it should return the complement, such - that this wear-leveling algorithm "receives" zeros. - - For multi-byte writes, up to 8 bytes will be used for each log entry, - depending on the size of backing store writes: - - ╔ Multi-byte Log Entry (2, 4-byte) ═╗ - ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║ - ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║ - ║ LenAdd║ Address║ Address║Value[0]║ - ╚════════╩════════╩════════╩════════╝ - ╔ Multi-byte Log Entry (2-byte) ══════════════════════╗ - ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║BBBBBBBB║CCCCCCCC║ - ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║ - ║ LenAdd║ Address║ Address║Value[0]║Value[1]║Value[2]║ - ╚════════╩════════╩════════╩════════╩════════╩════════╝ - ╔ Multi-byte Log Entry (2, 4, 8-byte) ══════════════════════════════════╗ - ║00XXXYYY║YYYYYYYY║YYYYYYYY║AAAAAAAA║BBBBBBBB║CCCCCCCC║DDDDDDDD║EEEEEEEE║ - ║ └┬┘└┬┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║└──┬───┘║ - ║ LenAdd║ Address║ Address║Value[0]║Value[1]║Value[2]║Value[3]║Value[4]║ - ╚════════╩════════╩════════╩════════╩════════╩════════╩════════╩════════╝ - - 19 bits are used for the address, which allows for a max logical size of - 512kB. Up to 5 bytes can be included in a single log entry. - - For 2-byte backing store writes, the last two bytes are optional - depending on the length of data to be written. Accordingly, either 3 - or 4 backing store write operations will occur. - For 4-byte backing store writes, either one or two write operations - occur, depending on the length. - For 8-byte backing store writes, one write operation occur. - - 2-byte backing store optimizations: - - For single byte writes, addresses between 0...63 are encoded in a single - backing store write operation. 4- and 8-byte backing stores do not have - this optimization as it does not minimize the number of bytes written. - - ╔ Byte-Entry ════╗ - ║01XXXXXXYYYYYYYY║ - ║ └─┬──┘└──┬───┘║ - ║ Address Value ║ - ╚════════════════╝ - 0 <= Address < 0x40 (64) - - A second optimization takes into account uint16_t writes of 0 or 1, - specifically catering for KC_NO and KC_TRANSPARENT in the dynamic keymap - subsystem. This is valid only for the first 16kB of logical data -- - addresses outside this range will use the multi-byte encoding above. - - ╔ U16-Encoded 0 ═╗ - ║100XXXXXXXXXXXXX║ - ║ │└─────┬─────┘║ - ║ │Address >> 1 ║ - ║ └── Value: 0 ║ - ╚════════════════╝ - 0 <= Address <= 0x3FFE (16382) - - ╔ U16-Encoded 1 ═╗ - ║101XXXXXXXXXXXXX║ - ║ │└─────┬─────┘║ - ║ │Address >> 1 ║ - ║ └── Value: 1 ║ - ╚════════════════╝ - 0 <= Address <= 0x3FFE (16382) */ - -/** - * Storage area for the wear-leveling cache. - */ -static struct __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) { - __attribute__((__aligned__(BACKING_STORE_WRITE_SIZE))) uint8_t cache[(WEAR_LEVELING_LOGICAL_SIZE)]; - uint32_t write_address; - bool unlocked; -} wear_leveling; - -/** - * Locking helper: status - */ -typedef enum backing_store_lock_status_t { STATUS_FAILURE = 0, STATUS_SUCCESS, STATUS_UNCHANGED } backing_store_lock_status_t; - -/** - * Locking helper: unlock - */ -static inline backing_store_lock_status_t wear_leveling_unlock(void) { - if (wear_leveling.unlocked) { - return STATUS_UNCHANGED; - } - if (!backing_store_unlock()) { - return STATUS_FAILURE; - } - wear_leveling.unlocked = true; - return STATUS_SUCCESS; -} - -/** - * Locking helper: lock - */ -static inline backing_store_lock_status_t wear_leveling_lock(void) { - if (!wear_leveling.unlocked) { - return STATUS_UNCHANGED; - } - if (!backing_store_lock()) { - return STATUS_FAILURE; - } - wear_leveling.unlocked = false; - return STATUS_SUCCESS; -} - -/** - * Resets the cache, ensuring the write address is correctly initialised. - */ -static void wear_leveling_clear_cache(void) { - memset(wear_leveling.cache, 0, (WEAR_LEVELING_LOGICAL_SIZE)); - wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 is due to the FNV1a_64 of the consolidated buffer -} - -/** - * Reads the consolidated data from the backing store into the cache. - * Does not consider the write log. - */ -static wear_leveling_status_t wear_leveling_read_consolidated(void) { - wl_dprintf("Reading consolidated data\n"); - - wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; - if (!backing_store_read_bulk(0, (backing_store_int_t *)wear_leveling.cache, sizeof(wear_leveling.cache) / sizeof(backing_store_int_t))) { - wl_dprintf("Failed to read from backing store\n"); - status = WEAR_LEVELING_FAILED; - } - - // Verify the FNV1a_64 result - if (status != WEAR_LEVELING_FAILED) { - uint64_t expected = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT); - write_log_entry_t entry; - wl_dprintf("Reading checksum\n"); -#if BACKING_STORE_WRITE_SIZE == 2 - backing_store_read_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw16, 4); -#elif BACKING_STORE_WRITE_SIZE == 4 - backing_store_read_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw32, 2); -#elif BACKING_STORE_WRITE_SIZE == 8 - backing_store_read((WEAR_LEVELING_LOGICAL_SIZE) + 0, &entry.raw64); -#endif - // If we have a mismatch, clear the cache but do not flag a failure, - // which will cater for the completely clean MCU case. - if (entry.raw64 == expected) { - wl_dprintf("Checksum matches, consolidated data is correct\n"); - } else { - wl_dprintf("Checksum mismatch, clearing cache\n"); - wear_leveling_clear_cache(); - } - } - - // If we failed for any reason, then clear the cache - if (status == WEAR_LEVELING_FAILED) { - wear_leveling_clear_cache(); - } - - return status; -} - -/** - * Writes the current cache to consolidated data at the beginning of the backing store. - * Does not clear the write log. - * Pre-condition: this is just after an erase, so we can write directly without reading. - */ -static wear_leveling_status_t wear_leveling_write_consolidated(void) { - wl_dprintf("Writing consolidated data\n"); - - backing_store_lock_status_t lock_status = wear_leveling_unlock(); - wear_leveling_status_t status = WEAR_LEVELING_CONSOLIDATED; - if (!backing_store_write_bulk(0, (backing_store_int_t *)wear_leveling.cache, sizeof(wear_leveling.cache) / sizeof(backing_store_int_t))) { - wl_dprintf("Failed to write to backing store\n"); - status = WEAR_LEVELING_FAILED; - } - - if (status != WEAR_LEVELING_FAILED) { - // Write out the FNV1a_64 result of the consolidated data - write_log_entry_t entry; - entry.raw64 = fnv_64a_buf(wear_leveling.cache, (WEAR_LEVELING_LOGICAL_SIZE), FNV1A_64_INIT); - wl_dprintf("Writing checksum\n"); - do { -#if BACKING_STORE_WRITE_SIZE == 2 - if (!backing_store_write_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw16, 4)) { - status = WEAR_LEVELING_FAILED; - break; - } -#elif BACKING_STORE_WRITE_SIZE == 4 - if (!backing_store_write_bulk((WEAR_LEVELING_LOGICAL_SIZE), entry.raw32, 2)) { - status = WEAR_LEVELING_FAILED; - break; - } -#elif BACKING_STORE_WRITE_SIZE == 8 - if (!backing_store_write((WEAR_LEVELING_LOGICAL_SIZE), entry.raw64)) { - status = WEAR_LEVELING_FAILED; - break; - } -#endif - } while (0); - } - - if (lock_status == STATUS_SUCCESS) { - wear_leveling_lock(); - } - return status; -} - -/** - * Forces a write of the current cache. - * Erases the backing store, including the write log. - * During this operation, there is the potential for data loss if a power loss occurs. - */ -static wear_leveling_status_t wear_leveling_consolidate_force(void) { - wl_dprintf("Erasing backing store\n"); - - // Erase the backing store. Expectation is that any un-written values that are read back after this call come back as zero. - bool ok = backing_store_erase(); - if (!ok) { - wl_dprintf("Failed to erase backing store\n"); - return WEAR_LEVELING_FAILED; - } - - // Write the cache to the first section of the backing store. - wear_leveling_status_t status = wear_leveling_write_consolidated(); - if (status == WEAR_LEVELING_FAILED) { - wl_dprintf("Failed to write consolidated data\n"); - } - - // Next write of the log occurs after the consolidated values at the start of the backing store. - wear_leveling.write_address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area - - return status; -} - -/** - * Potential write of the current cache to the backing store. - * Skipped if the current write log position is not at the end of the backing store. - * During this operation, there is the potential for data loss if a power loss occurs. - * - * @return true if consolidation occurred - */ -static wear_leveling_status_t wear_leveling_consolidate_if_needed(void) { - if (wear_leveling.write_address >= (WEAR_LEVELING_BACKING_SIZE)) { - return wear_leveling_consolidate_force(); - } - - return WEAR_LEVELING_SUCCESS; -} - -/** - * Appends the supplied fixed-width entry to the write log, optionally consolidating if the log is full. - * - * @return true if consolidation occurred - */ -static wear_leveling_status_t wear_leveling_append_raw(backing_store_int_t value) { - bool ok = backing_store_write(wear_leveling.write_address, value); - if (!ok) { - wl_dprintf("Failed to write to backing store\n"); - return WEAR_LEVELING_FAILED; - } - wear_leveling.write_address += (BACKING_STORE_WRITE_SIZE); - return wear_leveling_consolidate_if_needed(); -} - -/** - * Handles writing multi_byte-encoded data to the backing store. - * - * @return true if consolidation occurred - */ -static wear_leveling_status_t wear_leveling_write_raw_multibyte(uint32_t address, const void *value, size_t length) { - const uint8_t * p = value; - write_log_entry_t log = LOG_ENTRY_MAKE_MULTIBYTE(address, length); - for (size_t i = 0; i < length; ++i) { - log.raw8[3 + i] = p[i]; - } - - // Write to the backing store. See the multi-byte log format in the documentation header at the top of the file. - wear_leveling_status_t status; -#if BACKING_STORE_WRITE_SIZE == 2 - status = wear_leveling_append_raw(log.raw16[0]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - - status = wear_leveling_append_raw(log.raw16[1]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - - if (length > 1) { - status = wear_leveling_append_raw(log.raw16[2]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - } - - if (length > 3) { - status = wear_leveling_append_raw(log.raw16[3]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - } -#elif BACKING_STORE_WRITE_SIZE == 4 - status = wear_leveling_append_raw(log.raw32[0]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - - if (length > 1) { - status = wear_leveling_append_raw(log.raw32[1]); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } - } -#elif BACKING_STORE_WRITE_SIZE == 8 - status = wear_leveling_append_raw(log.raw64); - if (status != WEAR_LEVELING_SUCCESS) { - return status; - } -#endif - return status; -} - -/** - * Handles the actual writing of logical data into the write log section of the backing store. - */ -static wear_leveling_status_t wear_leveling_write_raw(uint32_t address, const void *value, size_t length) { - const uint8_t * p = value; - size_t remaining = length; - wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; - while (remaining > 0) { -#if BACKING_STORE_WRITE_SIZE == 2 - // Small-write optimizations - uint16_t, 0 or 1, address is even, address <16384: - if (remaining >= 2 && address % 2 == 0 && address < 16384) { - const uint16_t v = ((uint16_t)p[1]) << 8 | p[0]; // don't just dereference a uint16_t here -- if unaligned it generates faults on some MCUs - if (v == 0 || v == 1) { - const write_log_entry_t log = LOG_ENTRY_MAKE_WORD_01(address, v); - status = wear_leveling_append_raw(log.raw16[0]); - if (status != WEAR_LEVELING_SUCCESS) { - // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. - // If a failure occurred, pass it on. - return status; - } - - remaining -= 2; - address += 2; - p += 2; - continue; - } - } - - // Small-write optimizations - address<64: - if (address < 64) { - const write_log_entry_t log = LOG_ENTRY_MAKE_OPTIMIZED_64(address, *p); - status = wear_leveling_append_raw(log.raw16[0]); - if (status != WEAR_LEVELING_SUCCESS) { - // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. - // If a failure occurred, pass it on. - return status; - } - - remaining--; - address++; - p++; - continue; - } -#endif // BACKING_STORE_WRITE_SIZE == 2 - const size_t this_length = remaining >= LOG_ENTRY_MULTIBYTE_MAX_BYTES ? LOG_ENTRY_MULTIBYTE_MAX_BYTES : remaining; - status = wear_leveling_write_raw_multibyte(address, p, this_length); - if (status != WEAR_LEVELING_SUCCESS) { - // If consolidation occurred, then the cache has already been written to the consolidated area. No need to continue. - // If a failure occurred, pass it on. - return status; - } - remaining -= this_length; - address += (uint32_t)this_length; - p += this_length; - } - - return status; -} - -/** - * "Replays" the write log from the backing store, updating the local cache with updated values. - */ -static wear_leveling_status_t wear_leveling_playback_log(void) { - wl_dprintf("Playback write log\n"); - - wear_leveling_status_t status = WEAR_LEVELING_SUCCESS; - bool cancel_playback = false; - uint32_t address = (WEAR_LEVELING_LOGICAL_SIZE) + 8; // +8 due to the FNV1a_64 of the consolidated area - while (!cancel_playback && address < (WEAR_LEVELING_BACKING_SIZE)) { - backing_store_int_t value; - bool ok = backing_store_read(address, &value); - if (!ok) { - wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - if (value == 0) { - wl_dprintf("Found empty slot, no more log entries\n"); - cancel_playback = true; - break; - } - - // If we got a nonzero value, then we need to increment the address to ensure next write occurs at next location - address += (BACKING_STORE_WRITE_SIZE); - - // Read from the write log - write_log_entry_t log; -#if BACKING_STORE_WRITE_SIZE == 2 - log.raw16[0] = value; -#elif BACKING_STORE_WRITE_SIZE == 4 - log.raw32[0] = value; -#elif BACKING_STORE_WRITE_SIZE == 8 - log.raw64 = value; -#endif - - switch (LOG_ENTRY_GET_TYPE(log)) { - case LOG_ENTRY_TYPE_MULTIBYTE: { -#if BACKING_STORE_WRITE_SIZE == 2 - ok = backing_store_read(address, &log.raw16[1]); - if (!ok) { - wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - address += (BACKING_STORE_WRITE_SIZE); -#endif // BACKING_STORE_WRITE_SIZE == 2 - const uint32_t a = LOG_ENTRY_MULTIBYTE_GET_ADDRESS(log); - const uint8_t l = LOG_ENTRY_MULTIBYTE_GET_LENGTH(log); - - if (a + l > (WEAR_LEVELING_LOGICAL_SIZE)) { - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - -#if BACKING_STORE_WRITE_SIZE == 2 - if (l > 1) { - ok = backing_store_read(address, &log.raw16[2]); - if (!ok) { - wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - address += (BACKING_STORE_WRITE_SIZE); - } - if (l > 3) { - ok = backing_store_read(address, &log.raw16[3]); - if (!ok) { - wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - address += (BACKING_STORE_WRITE_SIZE); - } -#elif BACKING_STORE_WRITE_SIZE == 4 - if (l > 1) { - ok = backing_store_read(address, &log.raw32[1]); - if (!ok) { - wl_dprintf("Failed to load from backing store, skipping playback of write log\n"); - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - address += (BACKING_STORE_WRITE_SIZE); - } -#endif - - memcpy(&wear_leveling.cache[a], &log.raw8[3], l); - } break; -#if BACKING_STORE_WRITE_SIZE == 2 - case LOG_ENTRY_TYPE_OPTIMIZED_64: { - const uint32_t a = LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(log); - const uint8_t v = LOG_ENTRY_OPTIMIZED_64_GET_VALUE(log); - - if (a >= (WEAR_LEVELING_LOGICAL_SIZE)) { - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - - wear_leveling.cache[a] = v; - } break; - case LOG_ENTRY_TYPE_WORD_01: { - const uint32_t a = LOG_ENTRY_WORD_01_GET_ADDRESS(log); - const uint8_t v = LOG_ENTRY_WORD_01_GET_VALUE(log); - - if (a + 1 >= (WEAR_LEVELING_LOGICAL_SIZE)) { - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - break; - } - - wear_leveling.cache[a + 0] = v; - wear_leveling.cache[a + 1] = 0; - } break; -#endif // BACKING_STORE_WRITE_SIZE == 2 - default: { - cancel_playback = true; - status = WEAR_LEVELING_FAILED; - } break; - } - } - - // We've reached the end of the log, so we're at the new write location - wear_leveling.write_address = address; - - if (status == WEAR_LEVELING_FAILED) { - // If we had a failure during readback, assume we're corrupted -- force a consolidation with the data we already have - status = wear_leveling_consolidate_force(); - } else { - // Consolidate the cache + write log if required - status = wear_leveling_consolidate_if_needed(); - } - - return status; -} - -/** - * Wear-leveling initialization - */ -wear_leveling_status_t wear_leveling_init(void) { - wl_dprintf("Init\n"); - - // Reset the cache - wear_leveling_clear_cache(); - - // Initialise the backing store - if (!backing_store_init()) { - // If it failed, clear the cache and return with failure - wear_leveling_clear_cache(); - return WEAR_LEVELING_FAILED; - } - - // Read the previous consolidated values, then replay the existing write log so that the cache has the "live" values - wear_leveling_status_t status = wear_leveling_read_consolidated(); - if (status == WEAR_LEVELING_FAILED) { - // If it failed, clear the cache and return with failure - wear_leveling_clear_cache(); - return status; - } - - status = wear_leveling_playback_log(); - if (status == WEAR_LEVELING_FAILED) { - // If it failed, clear the cache and return with failure - wear_leveling_clear_cache(); - return status; - } - - return status; -} - -/** - * Wear-leveling erase. - * Post-condition: any reads from the backing store directly after an erase operation must come back as zero. - */ -wear_leveling_status_t wear_leveling_erase(void) { - wl_dprintf("Erase\n"); - - // Unlock the backing store - backing_store_lock_status_t lock_status = wear_leveling_unlock(); - if (lock_status == STATUS_FAILURE) { - wear_leveling_lock(); - return WEAR_LEVELING_FAILED; - } - - // Perform the erase - bool ret = backing_store_erase(); - wear_leveling_clear_cache(); - - // Lock the backing store if we acquired the lock successfully - if (lock_status == STATUS_SUCCESS) { - ret &= (wear_leveling_lock() != STATUS_FAILURE); - } - - return ret ? WEAR_LEVELING_SUCCESS : WEAR_LEVELING_FAILED; -} - -/** - * Writes logical data into the backing store. Skips writes if there are no changes to values. - */ -wear_leveling_status_t wear_leveling_write(const uint32_t address, const void *value, size_t length) { - wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE)); - if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) { - return WEAR_LEVELING_FAILED; - } - - wl_dprintf("Write "); - wl_dump(address, value, length); - - // Skip write if there's no change compared to the current cached value - if (memcmp(value, &wear_leveling.cache[address], length) == 0) { - return true; - } - - // Update the cache before writing to the backing store -- if we hit the end of the backing store during writes to the log then we'll force a consolidation in-line - memcpy(&wear_leveling.cache[address], value, length); - - // Unlock the backing store - backing_store_lock_status_t lock_status = wear_leveling_unlock(); - if (lock_status == STATUS_FAILURE) { - wear_leveling_lock(); - return WEAR_LEVELING_FAILED; - } - - // Perform the actual write - wear_leveling_status_t status = wear_leveling_write_raw(address, value, length); - switch (status) { - case WEAR_LEVELING_CONSOLIDATED: - case WEAR_LEVELING_FAILED: - // If the write triggered consolidation, or the write failed, then nothing else needs to occur. - break; - - case WEAR_LEVELING_SUCCESS: - // Consolidate the cache + write log if required - status = wear_leveling_consolidate_if_needed(); - break; - - default: - // Unsure how we'd get here... - status = WEAR_LEVELING_FAILED; - break; - } - - if (lock_status == STATUS_SUCCESS) { - if (wear_leveling_lock() == STATUS_FAILURE) { - status = WEAR_LEVELING_FAILED; - } - } - - return status; -} - -/** - * Reads logical data from the cache. - */ -wear_leveling_status_t wear_leveling_read(const uint32_t address, void *value, size_t length) { - wl_assert(address + length <= (WEAR_LEVELING_LOGICAL_SIZE)); - if (address + length > (WEAR_LEVELING_LOGICAL_SIZE)) { - return WEAR_LEVELING_FAILED; - } - - // Only need to copy from the cache - memcpy(value, &wear_leveling.cache[address], length); - - wl_dprintf("Read "); - wl_dump(address, value, length); - return WEAR_LEVELING_SUCCESS; -} - -/** - * Weak implementation of bulk read, drivers can implement more optimised implementations. - */ -__attribute__((weak)) bool backing_store_read_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) { - for (size_t i = 0; i < item_count; ++i) { - if (!backing_store_read(address + (i * BACKING_STORE_WRITE_SIZE), &values[i])) { - return false; - } - } - return true; -} - -/** - * Weak implementation of bulk write, drivers can implement more optimised implementations. - */ -__attribute__((weak)) bool backing_store_write_bulk(uint32_t address, backing_store_int_t *values, size_t item_count) { - for (size_t i = 0; i < item_count; ++i) { - if (!backing_store_write(address + (i * BACKING_STORE_WRITE_SIZE), values[i])) { - return false; - } - } - return true; -} diff --git a/quantum/wear_leveling/wear_leveling.h b/quantum/wear_leveling/wear_leveling.h deleted file mode 100644 index 6641bc49b3c4..000000000000 --- a/quantum/wear_leveling/wear_leveling.h +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once -#include -#include - -/** - * @typedef Status returned from any wear-leveling API. - */ -typedef enum wear_leveling_status_t { - WEAR_LEVELING_FAILED, //< Invocation failed - WEAR_LEVELING_SUCCESS, //< Invocation succeeded - WEAR_LEVELING_CONSOLIDATED //< Invocation succeeded, consolidation occurred -} wear_leveling_status_t; - -/** - * Wear-leveling initialization - * - * @return Status of the request - */ -wear_leveling_status_t wear_leveling_init(void); - -/** - * Wear-leveling erasure. - * - * Clears the wear-leveling area, with the definition that the "reset state" of all data is zero. - * - * @return Status of the request - */ -wear_leveling_status_t wear_leveling_erase(void); - -/** - * Writes logical data into the backing store. - * - * Skips writes if there are no changes to written values. The entire written block is considered when attempting to - * determine if an overwrite should occur -- if there is any data mismatch the entire block will be written to the log, - * not just the changed bytes. - * - * @param address[in] the logical address to write data - * @param value[in] pointer to the source buffer - * @param length[in] length of the data - * @return Status of the request - */ -wear_leveling_status_t wear_leveling_write(uint32_t address, const void* value, size_t length); - -/** - * Reads logical data from the cache. - * - * @param address[in] the logical address to read data - * @param value[out] pointer to the destination buffer - * @param length[in] length of the data - * @return Status of the request - */ -wear_leveling_status_t wear_leveling_read(uint32_t address, void* value, size_t length); diff --git a/quantum/wear_leveling/wear_leveling_internal.h b/quantum/wear_leveling/wear_leveling_internal.h deleted file mode 100644 index e83f9b22eaf3..000000000000 --- a/quantum/wear_leveling/wear_leveling_internal.h +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2022 Nick Brassel (@tzarc) -// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once - -#ifdef __cplusplus -# define _Static_assert static_assert -#endif - -#include -#include - -#if BACKING_STORE_WRITE_SIZE == 2 -typedef uint16_t backing_store_int_t; -#elif BACKING_STORE_WRITE_SIZE == 4 -typedef uint32_t backing_store_int_t; -#elif BACKING_STORE_WRITE_SIZE == 8 -typedef uint64_t backing_store_int_t; -#else -# error Invalid BACKING_STORE_WRITE_SIZE, needs to be 2/4/8. -#endif - -#ifndef WEAR_LEVELING_BACKING_SIZE -# error WEAR_LEVELING_BACKING_SIZE was not set. -#endif - -#ifndef WEAR_LEVELING_LOGICAL_SIZE -# error WEAR_LEVELING_LOGICAL_SIZE was not set. -#endif - -#ifdef WEAR_LEVELING_DEBUG_OUTPUT -# include -# define bs_dprintf(...) dprintf("Backing store: " __VA_ARGS__) -# define wl_dprintf(...) dprintf("Wear leveling: " __VA_ARGS__) -# define wl_dump(address, value, length) \ - do { \ - dprintf("[0x%04X]: ", (int)(address)); \ - const uint8_t* p = (const uint8_t*)(value); \ - for (int i = 0; i < (length); ++i) { \ - dprintf(" %02X", (int)p[i]); \ - } \ - dprintf("\n"); \ - } while (0) -#else -# define wl_dprintf(...) \ - do { \ - } while (0) -# define bs_dprintf(...) \ - do { \ - } while (0) -# define wl_dump(...) \ - do { \ - } while (0) -#endif // WEAR_LEVELING_DEBUG_OUTPUT - -#ifdef WEAR_LEVELING_ASSERTS -# include -# define wl_assert(...) assert(__VA_ARGS__) -#else -# define wl_assert(...) \ - do { \ - } while (0) -#endif // WEAR_LEVELING_ASSERTS - -// Compile-time validation of configurable options -_Static_assert(WEAR_LEVELING_BACKING_SIZE >= (WEAR_LEVELING_LOGICAL_SIZE * 2), "Total backing size must be at least twice the size of the logical size"); -_Static_assert(WEAR_LEVELING_LOGICAL_SIZE % BACKING_STORE_WRITE_SIZE == 0, "Logical size must be a multiple of write size"); -_Static_assert(WEAR_LEVELING_BACKING_SIZE % WEAR_LEVELING_LOGICAL_SIZE == 0, "Backing size must be a multiple of logical size"); - -// Backing Store API, to be implemented elsewhere by flash driver etc. -bool backing_store_init(void); -bool backing_store_unlock(void); -bool backing_store_erase(void); -bool backing_store_write(uint32_t address, backing_store_int_t value); -bool backing_store_write_bulk(uint32_t address, backing_store_int_t* values, size_t item_count); // weak implementation already provided, optimized implementation can be implemented by driver -bool backing_store_lock(void); -bool backing_store_read(uint32_t address, backing_store_int_t* value); -bool backing_store_read_bulk(uint32_t address, backing_store_int_t* values, size_t item_count); // weak implementation already provided, optimized implementation can be implemented by driver - -/** - * Helper type used to contain a write log entry. - */ -typedef union write_log_entry_t { - uint64_t raw64; - uint32_t raw32[2]; - uint16_t raw16[4]; - uint8_t raw8[8]; -} write_log_entry_t; - -_Static_assert(sizeof(write_log_entry_t) == 8, "Wear leveling write log entry size was not 8"); - -/** - * Log entry type discriminator. - */ -enum { - // 0x00 -- Multi-byte storage type - LOG_ENTRY_TYPE_MULTIBYTE, - - // 0x01 -- 2-byte backing store write optimization: address < 64 - LOG_ENTRY_TYPE_OPTIMIZED_64, - - // 0x02 -- 2-byte backing store write optimization: word-encoded 0/1 values - LOG_ENTRY_TYPE_WORD_01, - - LOG_ENTRY_TYPES -}; - -_Static_assert(LOG_ENTRY_TYPES <= (1 << 2), "Too many log entry types to fit into 2 bits of storage"); - -#define BITMASK_FOR_BITCOUNT(n) ((1 << (n)) - 1) - -#define LOG_ENTRY_GET_TYPE(entry) (((entry).raw8[0] >> 6) & BITMASK_FOR_BITCOUNT(2)) - -#define LOG_ENTRY_MULTIBYTE_MAX_BYTES 5 -#define LOG_ENTRY_MULTIBYTE_GET_ADDRESS(entry) (((((uint32_t)((entry).raw8[0])) & BITMASK_FOR_BITCOUNT(3)) << 16) | (((uint32_t)((entry).raw8[1])) << 8) | (entry).raw8[2]) -#define LOG_ENTRY_MULTIBYTE_GET_LENGTH(entry) ((uint8_t)(((entry).raw8[0] >> 3) & BITMASK_FOR_BITCOUNT(3))) -#define LOG_ENTRY_MAKE_MULTIBYTE(address, length) \ - (write_log_entry_t) { \ - .raw8 = { \ - [0] = (((((uint8_t)LOG_ENTRY_TYPE_MULTIBYTE) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ - | ((((uint8_t)(length)) & BITMASK_FOR_BITCOUNT(3)) << 3) /* length */ \ - | ((((uint8_t)((address) >> 16))) & BITMASK_FOR_BITCOUNT(3)) /* address */ \ - ), \ - [1] = (((uint8_t)((address) >> 8)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \ - [2] = (((uint8_t)(address)) & BITMASK_FOR_BITCOUNT(8)), /* address */ \ - } \ - } - -#define LOG_ENTRY_OPTIMIZED_64_GET_ADDRESS(entry) ((uint32_t)((entry).raw8[0] & BITMASK_FOR_BITCOUNT(6))) -#define LOG_ENTRY_OPTIMIZED_64_GET_VALUE(entry) ((entry).raw8[1]) -#define LOG_ENTRY_MAKE_OPTIMIZED_64(address, value) \ - (write_log_entry_t) { \ - .raw8 = { \ - [0] = (((((uint8_t)LOG_ENTRY_TYPE_OPTIMIZED_64) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ - | ((((uint8_t)(address))) & BITMASK_FOR_BITCOUNT(6)) /* address */ \ - ), \ - [1] = ((uint8_t)(value)), /* value */ \ - } \ - } - -#define LOG_ENTRY_WORD_01_GET_ADDRESS(entry) ((((uint32_t)(((entry).raw8[0]) & BITMASK_FOR_BITCOUNT(5))) << 9) | (((uint32_t)((entry).raw8[1])) << 1)) -#define LOG_ENTRY_WORD_01_GET_VALUE(entry) ((uint8_t)((entry).raw8[0] >> 5) & BITMASK_FOR_BITCOUNT(1)) -#define LOG_ENTRY_MAKE_WORD_01(address, value) \ - (write_log_entry_t) { \ - .raw8 = { \ - [0] = (((((uint8_t)LOG_ENTRY_TYPE_WORD_01) & BITMASK_FOR_BITCOUNT(2)) << 6) /* type */ \ - | (((((uint8_t)((value) ? 1 : 0))) & BITMASK_FOR_BITCOUNT(1)) << 5) /* value */ \ - | ((((uint8_t)((address) >> 9))) & BITMASK_FOR_BITCOUNT(5)) /* address */ \ - ), \ - [1] = (uint8_t)((address) >> 1), /* address */ \ - } \ - } diff --git a/quantum/wpm.c b/quantum/wpm.c deleted file mode 100644 index 9a125efba093..000000000000 --- a/quantum/wpm.c +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2020 Richard Sutherland (rich@brickbots.com) - * - * 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 . - */ - -#include "wpm.h" -#include "timer.h" -#include "keycode.h" -#include "quantum_keycodes.h" -#include "action_util.h" -#include - -// WPM Stuff -static uint8_t current_wpm = 0; -static uint32_t wpm_timer = 0; - -/* The WPM calculation works by specifying a certain number of 'periods' inside - * a ring buffer, and we count the number of keypresses which occur in each of - * those periods. Then to calculate WPM, we add up all of the keypresses in - * the whole ring buffer, divide by the number of keypresses in a 'word', and - * then adjust for how much time is captured by our ring buffer. The size - * of the ring buffer can be configured using the keymap configuration - * value `WPM_SAMPLE_PERIODS`. - * - */ -#define MAX_PERIODS (WPM_SAMPLE_PERIODS) -#define PERIOD_DURATION (1000 * WPM_SAMPLE_SECONDS / MAX_PERIODS) - -static int16_t period_presses[MAX_PERIODS] = {0}; -static uint8_t current_period = 0; -static uint8_t periods = 1; - -#if !defined(WPM_UNFILTERED) -/* LATENCY is used as part of filtering, and controls how quickly the reported - * WPM trails behind our actual instantaneous measured WPM value, and is - * defined in milliseconds. So for LATENCY == 100, the displayed WPM is - * smoothed out over periods of 0.1 seconds. This results in a nice, - * smoothly-moving reported WPM value which nevertheless is never more than - * 0.1 seconds behind the typist's actual current WPM. - * - * LATENCY is not used if WPM_UNFILTERED is defined. - */ -# define LATENCY (100) -static uint32_t smoothing_timer = 0; -static uint8_t prev_wpm = 0; -static uint8_t next_wpm = 0; -#endif - -void set_current_wpm(uint8_t new_wpm) { - current_wpm = new_wpm; -} -uint8_t get_current_wpm(void) { - return current_wpm; -} - -bool wpm_keycode(uint16_t keycode) { - return wpm_keycode_kb(keycode); -} - -__attribute__((weak)) bool wpm_keycode_kb(uint16_t keycode) { - return wpm_keycode_user(keycode); -} - -__attribute__((weak)) bool wpm_keycode_user(uint16_t keycode) { - if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) { - keycode = keycode & 0xFF; - } else if (keycode > 0xFF) { - keycode = 0; - } - if ((keycode >= KC_A && keycode <= KC_0) || (keycode >= KC_TAB && keycode <= KC_SLASH)) { - return true; - } - - return false; -} - -#if defined(WPM_ALLOW_COUNT_REGRESSION) -__attribute__((weak)) uint8_t wpm_regress_count(uint16_t keycode) { - bool weak_modded = (keycode >= QK_LCTL && keycode < QK_LSFT) || (keycode >= QK_RCTL && keycode < QK_RSFT); - - if ((keycode >= QK_MOD_TAP && keycode <= QK_MOD_TAP_MAX) || (keycode >= QK_LAYER_TAP && keycode <= QK_LAYER_TAP_MAX) || (keycode >= QK_MODS && keycode <= QK_MODS_MAX)) { - keycode = keycode & 0xFF; - } else if (keycode > 0xFF) { - keycode = 0; - } - if (keycode == KC_DELETE || keycode == KC_BACKSPACE) { - if (((get_mods() | get_oneshot_mods()) & MOD_MASK_CTRL) || weak_modded) { - return WPM_ESTIMATED_WORD_SIZE; - } else { - return 1; - } - } else { - return 0; - } -} -#endif - -// Outside 'raw' mode we smooth results over time. - -void update_wpm(uint16_t keycode) { - if (wpm_keycode(keycode) && period_presses[current_period] < INT16_MAX) { - period_presses[current_period]++; - } -#if defined(WPM_ALLOW_COUNT_REGRESSION) - uint8_t regress = wpm_regress_count(keycode); - if (regress && period_presses[current_period] > INT16_MIN) { - period_presses[current_period]--; - } -#endif -} - -void decay_wpm(void) { - int32_t presses = period_presses[0]; - for (int i = 1; i <= periods; i++) { - presses += period_presses[i]; - } - if (presses < 0) { - presses = 0; - } - int32_t elapsed = timer_elapsed32(wpm_timer); - uint32_t duration = (((periods)*PERIOD_DURATION) + elapsed); - int32_t wpm_now = (60000 * presses) / (duration * WPM_ESTIMATED_WORD_SIZE); - - if (wpm_now < 0) // set some reasonable WPM measurement limits - wpm_now = 0; - if (wpm_now > 240) wpm_now = 240; - - if (elapsed > PERIOD_DURATION) { - current_period = (current_period + 1) % MAX_PERIODS; - period_presses[current_period] = 0; - periods = (periods < MAX_PERIODS - 1) ? periods + 1 : MAX_PERIODS - 1; - elapsed = 0; - wpm_timer = timer_read32(); - } - if (presses < 2) // don't guess high WPM based on a single keypress. - wpm_now = 0; - -#if defined(WPM_LAUNCH_CONTROL) - /* - * If the `WPM_LAUNCH_CONTROL` option is enabled, then whenever our WPM - * drops to absolute zero due to no typing occurring within our sample - * ring buffer, we reset and start measuring fresh, which lets our WPM - * immediately reach the correct value even before a full sampling buffer - * has been filled. - */ - if (presses == 0) { - current_period = 0; - periods = 0; - wpm_now = 0; - period_presses[0] = 0; - } -#endif // WPM_LAUNCH_CONTROL - -#if defined(WPM_UNFILTERED) - current_wpm = wpm_now; -#else - int32_t latency = timer_elapsed32(smoothing_timer); - if (latency > LATENCY) { - smoothing_timer = timer_read32(); - prev_wpm = current_wpm; - next_wpm = wpm_now; - } - - current_wpm = prev_wpm + (latency * ((int)next_wpm - (int)prev_wpm) / LATENCY); -#endif -} diff --git a/quantum/wpm.h b/quantum/wpm.h deleted file mode 100644 index 87a55fd4223d..000000000000 --- a/quantum/wpm.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2020 Richard Sutherland (rich@brickbots.com) - * - * 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 . - */ - -#pragma once - -#include -#include - -#ifndef WPM_ESTIMATED_WORD_SIZE -# define WPM_ESTIMATED_WORD_SIZE 5 -#endif -#ifndef WPM_SAMPLE_SECONDS -# define WPM_SAMPLE_SECONDS 5 -#endif -#ifndef WPM_SAMPLE_PERIODS -# define WPM_SAMPLE_PERIODS 25 -#endif - -bool wpm_keycode(uint16_t keycode); -bool wpm_keycode_kb(uint16_t keycode); -bool wpm_keycode_user(uint16_t keycode); - -#ifdef WPM_ALLOW_COUNT_REGRESSION -uint8_t wpm_regress_count(uint16_t keycode); -#endif - -void set_current_wpm(uint8_t); -uint8_t get_current_wpm(void); -void update_wpm(uint16_t); - -void decay_wpm(void); diff --git a/readme.md b/readme.md deleted file mode 100644 index c2fcda103ece..000000000000 --- a/readme.md +++ /dev/null @@ -1,40 +0,0 @@ -# THIS IS THE DEVELOP BRANCH - -Warning- This is the `develop` branch of QMK Firmware. You may encounter broken code here. Please see [Breaking Changes](https://docs.qmk.fm/#/breaking_changes) for more information. - -# Quantum Mechanical Keyboard Firmware - -[![Current Version](https://img.shields.io/github/tag/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/tags) -[![Discord](https://img.shields.io/discord/440868230475677696.svg)](https://discord.gg/Uq7gcHh) -[![Docs Status](https://img.shields.io/badge/docs-ready-orange.svg)](https://docs.qmk.fm) -[![GitHub contributors](https://img.shields.io/github/contributors/qmk/qmk_firmware.svg)](https://github.com/qmk/qmk_firmware/pulse/monthly) -[![GitHub forks](https://img.shields.io/github/forks/qmk/qmk_firmware.svg?style=social&label=Fork)](https://github.com/qmk/qmk_firmware/) - -This is a keyboard firmware based on the [tmk\_keyboard firmware](https://github.com/tmk/tmk_keyboard) with some useful features for Atmel AVR and ARM controllers, and more specifically, the [OLKB product line](https://olkb.com), the [ErgoDox EZ](https://ergodox-ez.com) keyboard, and the [Clueboard product line](https://clueboard.co). - -## Documentation - -* [See the official documentation on docs.qmk.fm](https://docs.qmk.fm) - -The docs are powered by [Docsify](https://docsify.js.org/) and hosted on [GitHub](/docs/). They are also viewable offline; see [Previewing the Documentation](https://docs.qmk.fm/#/contributing?id=previewing-the-documentation) for more details. - -You can request changes by making a fork and opening a [pull request](https://github.com/qmk/qmk_firmware/pulls), or by clicking the "Edit this page" link at the bottom of any page. - -## Supported Keyboards - -* [Planck](/keyboards/planck/) -* [Preonic](/keyboards/preonic/) -* [ErgoDox EZ](/keyboards/ergodox_ez/) -* [Clueboard](/keyboards/clueboard/) -* [Cluepad](/keyboards/clueboard/17/) -* [Atreus](/keyboards/atreus/) - -The project also includes community support for [lots of other keyboards](/keyboards/). - -## Maintainers - -QMK is developed and maintained by Jack Humbert of OLKB with contributions from the community, and of course, [Hasu](https://github.com/tmk). The OLKB product firmwares are maintained by [Jack Humbert](https://github.com/jackhumbert), the Ergodox EZ by [ZSA Technology Labs](https://github.com/zsa), the Clueboard by [Zach White](https://github.com/skullydazed), and the Atreus by [Phil Hagelberg](https://github.com/technomancy). - -## Official Website - -[qmk.fm](https://qmk.fm) is the official website of QMK, where you can find links to this page, the documentation, and the keyboards supported by QMK. diff --git a/tests/caps_word/caps_word_unicodemap/test_caps_word_unicodemap.cpp b/tests/caps_word/caps_word_unicodemap/test_caps_word_unicodemap.cpp index 01cdfd6408d2..21e5493526e0 100644 --- a/tests/caps_word/caps_word_unicodemap/test_caps_word_unicodemap.cpp +++ b/tests/caps_word/caps_word_unicodemap/test_caps_word_unicodemap.cpp @@ -39,8 +39,8 @@ const uint32_t unicode_map[] PROGMEM = { [DELTA_UPPERCASE] = 0x0394, }; -#define U_DASH XP(ENDASH, EMDASH) -#define U_DELTA XP(DELTA_LOWERCASE, DELTA_UPPERCASE) +#define U_DASH UP(ENDASH, EMDASH) +#define U_DELTA UP(DELTA_LOWERCASE, DELTA_UPPERCASE) bool caps_word_press_user(uint16_t keycode) { switch (keycode) { diff --git a/users/konstantin/unicode.h b/users/konstantin/unicode.h index 82caea7c9ace..472f48a9428a 100644 --- a/users/konstantin/unicode.h +++ b/users/konstantin/unicode.h @@ -31,7 +31,7 @@ #define UCM_NAME(name, code) UCM_ ## name, #define UCM_ENTRY(name, code) [UCM_ ## name] = code, -#define UCM_KEYCODE(name, code) name = X(UCM_ ## name), +#define UCM_KEYCODE(name, code) name = UM(UCM_ ## name), #if defined(UNICODE_ENABLE) enum unicode_keycodes { diff --git a/users/kuchosauronad0/unicode.h b/users/kuchosauronad0/unicode.h index 9ff523baadf7..340b4cf94bcf 100644 --- a/users/kuchosauronad0/unicode.h +++ b/users/kuchosauronad0/unicode.h @@ -2,7 +2,6 @@ #include "quantum.h" -/* use X(n) to call the */ #ifdef UNICODEMAP_ENABLE enum unicode_name { OKOK, // diff --git a/users/kuchosauronad0/wrappers.h b/users/kuchosauronad0/wrappers.h index 543586e00906..a17e4178ffe4 100644 --- a/users/kuchosauronad0/wrappers.h +++ b/users/kuchosauronad0/wrappers.h @@ -152,13 +152,13 @@ NOTE: These are all the same length. If you do a search/replace #endif #ifdef UNICODEMAP_ENABLE -# define _______________UNICODE_L1__________________ X(SMRK), X(THINK), X(CLOWN), X(HUNDR), X(BANG) -# define _______________UNICODE_L2__________________ X(GRIN), X(MONKEY), X(OKOK), X(EGGPL), X(LIT) -# define _______________UNICODE_L3__________________ X(WEARY), X(UNAMU), X(EFFU), X(MONOCL), X(IRONY) +# define _______________UNICODE_L1__________________ UM(SMRK), UM(THINK), UM(CLOWN), UM(HUNDR), UM(BANG) +# define _______________UNICODE_L2__________________ UM(GRIN), UM(MONKEY), UM(OKOK), UM(EGGPL), UM(LIT) +# define _______________UNICODE_L3__________________ UM(WEARY), UM(UNAMU), UM(EFFU), UM(MONOCL), UM(IRONY) -# define _______________UNICODE_R1__________________ X(DRUG0), X(THUP), X(INUP), X(DIZZY), X(COOL) -# define _______________UNICODE_R2__________________ X(FIST0), X(FIST2), X(FIST3), X(FIST1), X(OKOK) -# define _______________UNICODE_R3__________________ X(MNDBLWN), X(THDN), X(SPOCK), X(HOLE), X(DASH) +# define _______________UNICODE_R1__________________ UM(DRUG0), UM(THUP), UM(INUP), UM(DIZZY), UM(COOL) +# define _______________UNICODE_R2__________________ UM(FIST0), UM(FIST2), UM(FIST3), UM(FIST1), UM(OKOK) +# define _______________UNICODE_R3__________________ UM(MNDBLWN), UM(THDN), UM(SPOCK), UM(HOLE), UM(DASH) #endif #define ________________NUMBER_LEFT________________ KC_1, KC_2, KC_3, KC_4, KC_5 diff --git a/users/ridingqwerty/unicode.h b/users/ridingqwerty/unicode.h index de8d1593b4a1..08b6f4fb8d50 100644 --- a/users/ridingqwerty/unicode.h +++ b/users/ridingqwerty/unicode.h @@ -216,7 +216,7 @@ #define UCM_NAME(name, code) UCM_ ## name, // UCM_LALP, #define UCM_ENTRY(name, code) [UCM_ ## name] = code, // [UCM_LALP] = 0x03B1, -#define UCM_KEYCODE(name, code) name = X(UCM_ ## name), // LALP = X(UCM_LALP) +#define UCM_KEYCODE(name, code) name = UM(UCM_ ## name), // LALP = UM(UCM_LALP) #if defined(UNICODE_ENABLE) enum unicode_keycodes { @@ -235,61 +235,61 @@ enum unicode_keycodes { #endif -#define ALPHA XP(LALP, UALP) -#define BETA XP(LBET, UBET) -#define GAMMA XP(LGAM, UGAM) -#define DELTA XP(LDEL, UDEL) -#define EPSLN XP(LEPS, UEPS) -#define ZETA XP(LZET, UZET) -#define ETA XP(LETA, UETA) -#define THETA XP(LTHE, UTHE) -#define IOTA XP(LIOT, UIOT) -#define KAPPA XP(LKAP, UKAP) -#define LAMBD XP(LLAM, ULAM) -#define GMU XP(LMU, UMU) -#define NU XP(LNU, UNU) -#define XI XP(LXI, UXI) -#define OMCRN XP(LOMI, UOMI) -#define PI XP(LPI, UPI) -#define RHO XP(LRHO, URHO) -#define SIGMA XP(LSIG, USIG) -#define TAU XP(LTAU, UTAU) -#define UPSLN XP(LUPS, UUPS) -#define PHI XP(LPHI, UPHI) -#define CHI XP(LCHI, UCHI) -#define PSI XP(LPSI, UPSI) -#define OMEGA XP(LOME, UOME) +#define ALPHA UP(LALP, UALP) +#define BETA UP(LBET, UBET) +#define GAMMA UP(LGAM, UGAM) +#define DELTA UP(LDEL, UDEL) +#define EPSLN UP(LEPS, UEPS) +#define ZETA UP(LZET, UZET) +#define ETA UP(LETA, UETA) +#define THETA UP(LTHE, UTHE) +#define IOTA UP(LIOT, UIOT) +#define KAPPA UP(LKAP, UKAP) +#define LAMBD UP(LLAM, ULAM) +#define GMU UP(LMU, UMU) +#define NU UP(LNU, UNU) +#define XI UP(LXI, UXI) +#define OMCRN UP(LOMI, UOMI) +#define PI UP(LPI, UPI) +#define RHO UP(LRHO, URHO) +#define SIGMA UP(LSIG, USIG) +#define TAU UP(LTAU, UTAU) +#define UPSLN UP(LUPS, UUPS) +#define PHI UP(LPHI, UPHI) +#define CHI UP(LCHI, UCHI) +#define PSI UP(LPSI, UPSI) +#define OMEGA UP(LOME, UOME) -#define AH XP(LAH, UAH) -#define BE XP(LBE, UBE) -#define VE XP(LVE, UVE) -#define GHE XP(LGHE, UGHE) -#define DE XP(LDE, UDE) -#define IE XP(LIE, UIE) -#define IO XP(LIO, UIO) -#define ZHE XP(LZHE, UZHE) -#define ZE XP(LZE, UZE) -#define IH XP(LIH, UIH) -#define SIH XP(LSIH, USIH) -#define KA XP(LKA, UKA) -#define EL XP(LEL, UEL) -#define EM XP(LEM, UEM) -#define EN XP(LEN, UEN) -#define OH XP(LOH, UOH) -#define PE XP(LPE, UPE) -#define ER XP(LER, UER) -#define ES XP(LES, UES) -#define TE XP(LTE, UTE) -#define UU XP(LUU, UUU) -#define EF XP(LEF, UEF) -#define HA XP(LHA, UHA) -#define TSE XP(LTSE, UTSE) -#define CHE XP(LCHE, UCHE) -#define SHA XP(LSHA, USHA) -#define SCHA XP(LSCHA, USCHA) -#define HARD XP(LHARD, UHARD) -#define YERU XP(LYERU, UYERU) -#define SOFT XP(LSOFT, USOFT) -#define EH XP(LEH, UEH) -#define YU XP(LYU, UYU) -#define YA XP(LYA, UYA) +#define AH UP(LAH, UAH) +#define BE UP(LBE, UBE) +#define VE UP(LVE, UVE) +#define GHE UP(LGHE, UGHE) +#define DE UP(LDE, UDE) +#define IE UP(LIE, UIE) +#define IO UP(LIO, UIO) +#define ZHE UP(LZHE, UZHE) +#define ZE UP(LZE, UZE) +#define IH UP(LIH, UIH) +#define SIH UP(LSIH, USIH) +#define KA UP(LKA, UKA) +#define EL UP(LEL, UEL) +#define EM UP(LEM, UEM) +#define EN UP(LEN, UEN) +#define OH UP(LOH, UOH) +#define PE UP(LPE, UPE) +#define ER UP(LER, UER) +#define ES UP(LES, UES) +#define TE UP(LTE, UTE) +#define UU UP(LUU, UUU) +#define EF UP(LEF, UEF) +#define HA UP(LHA, UHA) +#define TSE UP(LTSE, UTSE) +#define CHE UP(LCHE, UCHE) +#define SHA UP(LSHA, USHA) +#define SCHA UP(LSCHA, USCHA) +#define HARD UP(LHARD, UHARD) +#define YERU UP(LYERU, UYERU) +#define SOFT UP(LSOFT, USOFT) +#define EH UP(LEH, UEH) +#define YU UP(LYU, UYU) +#define YA UP(LYA, UYA) diff --git a/users/rmeli/keyrecords/unicode.h b/users/rmeli/keyrecords/unicode.h index c3ba96d5b654..63c355415e32 100644 --- a/users/rmeli/keyrecords/unicode.h +++ b/users/rmeli/keyrecords/unicode.h @@ -74,13 +74,13 @@ const uint32_t unicode_map[] PROGMEM = { }; // Accents -#define A_GRV XP(aGRV, AGRV) -#define A_UML XP(aUML, AUML) -#define E_GRV XP(eGRV, EGRV) -#define E_ACT XP(eACT, EACT) -#define I_GRV XP(iGRV, IGRV) -#define I_CIR XP(iCIR, ICIR) -#define O_GRV XP(oGRV, OGRV) -#define O_UML XP(oUML, OUML) -#define U_GRV XP(uGRV, UGRV) -#define U_UML XP(uUML, UUML) +#define A_GRV UP(aGRV, AGRV) +#define A_UML UP(aUML, AUML) +#define E_GRV UP(eGRV, EGRV) +#define E_ACT UP(eACT, EACT) +#define I_GRV UP(iGRV, IGRV) +#define I_CIR UP(iCIR, ICIR) +#define O_GRV UP(oGRV, OGRV) +#define O_UML UP(oUML, OUML) +#define U_GRV UP(uGRV, UGRV) +#define U_UML UP(uUML, UUML) diff --git a/users/rupa/wrappers.h b/users/rupa/wrappers.h index dfc00b512004..df32ef39abf8 100644 --- a/users/rupa/wrappers.h +++ b/users/rupa/wrappers.h @@ -28,14 +28,14 @@ along with this program. If not, see . #define G_LWR LT(_LOWER, KC_G) #if defined(UNICODEMAP_ENABLE) -# define CSHAPES XP(CCIR,CKEY) -# define CUIDADO XP(CUI,HAS) -# define NOPENAH XP(NOPE,STOP) -# define MUSIC_A XP(M4,M8) -# define MUSIC_B XP(M8B,M16) -# define SMILE XP(SMB,SMW) -# define STARS XP(STB,STW) -# define YEPYEP XP(CHEK,HUN) +# define CSHAPES UP(CCIR,CKEY) +# define CUIDADO UP(CUI,HAS) +# define NOPENAH UP(NOPE,STOP) +# define MUSIC_A UP(M4,M8) +# define MUSIC_B UP(M8B,M16) +# define SMILE UP(SMB,SMW) +# define STARS UP(STB,STW) +# define YEPYEP UP(CHEK,HUN) #endif /* _QWERTY @@ -70,10 +70,10 @@ along with this program. If not, see . * │RCtl│RAlt│RGui│ FLIP │ │ │ │M← │M↓ │M→ │ * └────┴────┴────┴────────────────────────┴───┴───┴───┴───┴───┴───┘ */ -#define ____65_RAISE_______________ROW1 KC_GRV, X(IBNG), X(IRNY), _______, X(CENT), _______, _______, _______, STARS, _______, SMILE, X(NEG), CSHAPES, KC_DEL, KC_HOME -#define ____65_RAISE_______________ROW2 _______, _______, WAT, X(LEXI), RUPA, TADA, YUNO, _______, X(LELM), X(OM), _______, MUSIC_A, MUSIC_B, _______, KC_INS -#define ____65_RAISE_______________ROW3 _______, X(LALL), X(EFF), DICE, FART, _______, HUGS, JOY, KISS, LOD, _______, NOPENAH, YEPYEP, KC_END -#define ____65_RAISE_______________ROW4 OS_RSFT, CUIDADO, X(ECKS), CATS, DOMO, BUGS, X(NUM), MUSIC, DANCE, X(LPRO), SHRUG, KC_BTN1, KC_MS_U, KC_BTN2 +#define ____65_RAISE_______________ROW1 KC_GRV, UM(IBNG), UM(IRNY), _______, UM(CENT), _______, _______, _______, STARS, _______, SMILE, UM(NEG), CSHAPES, KC_DEL, KC_HOME +#define ____65_RAISE_______________ROW2 _______, _______, WAT, UM(LEXI), RUPA, TADA, YUNO, _______, UM(LELM), UM(OM), _______, MUSIC_A, MUSIC_B, _______, KC_INS +#define ____65_RAISE_______________ROW3 _______, UM(LALL), UM(EFF), DICE, FART, _______, HUGS, JOY, KISS, LOD, _______, NOPENAH, YEPYEP, KC_END +#define ____65_RAISE_______________ROW4 OS_RSFT, CUIDADO, UM(ECKS), CATS, DOMO, BUGS, UM(NUM), MUSIC, DANCE, UM(LPRO), SHRUG, KC_BTN1, KC_MS_U, KC_BTN2 #define ____65_RAISE_______________ROW5 OS_RCTL, OS_RALT, OS_RGUI, FLIP, _______, _______, _______, KC_MS_L, KC_MS_D, KC_MS_R /* _LOWER diff --git a/users/spidey3/spidey3_unicode.h b/users/spidey3/spidey3_unicode.h index ee8e00056ce6..4a3657fdfd83 100644 --- a/users/spidey3/spidey3_unicode.h +++ b/users/spidey3/spidey3_unicode.h @@ -25,7 +25,7 @@ enum unicode_names { SURPRISE, }; -# define X_BUL (XP(BUL1, BUL2)) -# define X_DASH (XP(EMDASH, ENDASH)) +# define X_BUL (UP(BUL1, BUL2)) +# define X_DASH (UP(EMDASH, ENDASH)) #endif diff --git a/users/turbomech/turbomech.c b/users/turbomech/turbomech.c index 892db1b92724..75796fb8fb36 100644 --- a/users/turbomech/turbomech.c +++ b/users/turbomech/turbomech.c @@ -101,8 +101,7 @@ bool process_record_user(uint16_t keycode, keyrecord_t *record) { if (record->event.pressed) { register_code(KC_LPRN); unregister_code(KC_LPRN); - register_code(X(0x00B0)); - unregister_code(X(0x00B0)); + register_unicode(0x00B0); UC(0x256F); PROCESS_UNICODE(UC(0x00B0)); diff --git a/users/yet-another-developer/unicode.h b/users/yet-another-developer/unicode.h index 9ff523baadf7..340b4cf94bcf 100644 --- a/users/yet-another-developer/unicode.h +++ b/users/yet-another-developer/unicode.h @@ -2,7 +2,6 @@ #include "quantum.h" -/* use X(n) to call the */ #ifdef UNICODEMAP_ENABLE enum unicode_name { OKOK, // diff --git a/users/yet-another-developer/wrappers.h b/users/yet-another-developer/wrappers.h index cd21032a4ecc..776da0c77ef3 100644 --- a/users/yet-another-developer/wrappers.h +++ b/users/yet-another-developer/wrappers.h @@ -118,13 +118,13 @@ NOTE: These are all the same length. If you do a search/replace #endif #ifdef UNICODEMAP_ENABLE -#define _______________UNICODE_L1__________________ X(SMRK), X(THINK), X(CLOWN), X(HUNDR), X(BANG) -#define _______________UNICODE_L2__________________ X(GRIN), X(MONKEY), X(OKOK), X(EGGPL), X(LIT) -#define _______________UNICODE_L3__________________ X(WEARY), X(UNAMU), X(EFFU), X(MONOCL), X(IRONY) +#define _______________UNICODE_L1__________________ UM(SMRK), UM(THINK), UM(CLOWN), UM(HUNDR), UM(BANG) +#define _______________UNICODE_L2__________________ UM(GRIN), UM(MONKEY), UM(OKOK), UM(EGGPL), UM(LIT) +#define _______________UNICODE_L3__________________ UM(WEARY), UM(UNAMU), UM(EFFU), UM(MONOCL), UM(IRONY) -#define _______________UNICODE_R1__________________ X(DRUG0), X(THUP), X(INUP), X(DIZZY), X(COOL) -#define _______________UNICODE_R2__________________ X(FIST0), X(FIST2),X(FIST3),X(FIST1), X(OKOK) -#define _______________UNICODE_R3__________________ X(MNDBLWN), X(THDN), X(SPOCK),X(HOLE), X(DASH) +#define _______________UNICODE_R1__________________ UM(DRUG0), UM(THUP), UM(INUP), UM(DIZZY), UM(COOL) +#define _______________UNICODE_R2__________________ UM(FIST0), UM(FIST2),UM(FIST3),UM(FIST1), UM(OKOK) +#define _______________UNICODE_R3__________________ UM(MNDBLWN), UM(THDN), UM(SPOCK),UM(HOLE), UM(DASH) #endif #define ________________NUMBER_LEFT________________ KC_1, KC_2, KC_3, KC_4, KC_5 diff --git a/util/uf2conv.py b/util/uf2conv.py index 578b2b49772d..84271cee4f6f 100755 --- a/util/uf2conv.py +++ b/util/uf2conv.py @@ -74,7 +74,7 @@ def convert_from_uf2(buf): assert False, "Non-word padding size at " + ptr while padding > 0: padding -= 4 - outp += b"\x00\x00\x00\x00" + outp.append(b"\x00\x00\x00\x00") if familyid == 0x0 or ((hd[2] & 0x2000) and familyid == hd[7]): outp.append(block[32 : 32 + datalen]) curraddr = newaddr + datalen @@ -218,18 +218,17 @@ def get_drives(): if len(words) >= 3 and words[1] == "2" and words[2] == "FAT": drives.append(words[0]) else: - rootpath = "/media" + searchpaths = ["/media"] if sys.platform == "darwin": - rootpath = "/Volumes" + searchpaths = ["/Volumes"] elif sys.platform == "linux": - tmp = rootpath + "/" + os.environ["USER"] - if os.path.isdir(tmp): - rootpath = tmp - tmp = "/run" + rootpath + "/" + os.environ["USER"] - if os.path.isdir(tmp): - rootpath = tmp - for d in os.listdir(rootpath): - drives.append(os.path.join(rootpath, d)) + searchpaths += ["/media/" + os.environ["USER"], '/run/media/' + os.environ["USER"]] + + for rootpath in searchpaths: + if os.path.isdir(rootpath): + for d in os.listdir(rootpath): + if os.path.isdir(rootpath): + drives.append(os.path.join(rootpath, d)) def has_info(d): diff --git a/util/uf2families.json b/util/uf2families.json index c2140fe351a2..778af4421fc6 100644 --- a/util/uf2families.json +++ b/util/uf2families.json @@ -203,5 +203,15 @@ "id": "0x11de784a", "short_name": "M0SENSE", "description": "M0SENSE BL702" + }, + { + "id": "0x4b684d71", + "short_name": "MaixPlay-U4", + "description": "Sipeed MaixPlay-U4(BL618)" + }, + { + "id": "0x9517422f", + "short_name": "RZA1LU", + "description": "Renesas RZ/A1LU (R7S7210xx)" } -] \ No newline at end of file +]